Compare commits
38 Commits
7d052f0691
...
main_app权限
| Author | SHA1 | Date | |
|---|---|---|---|
| ed180d6f18 | |||
| c0c33f6c2e | |||
| 953ffdfb28 | |||
| 6b9a09c9e8 | |||
| 64729a223d | |||
| ec03919c78 | |||
| c61f2a7265 | |||
| ae88cc16cc | |||
| b467e02ff6 | |||
| d64216ee5f | |||
| a7bb1d8e84 | |||
| 1f7f4bf537 | |||
| 9a975b36c5 | |||
| 401d6752cf | |||
| 3e0394eaea | |||
| d91012ee1b | |||
| 1438178f70 | |||
| fb94eaf97c | |||
| 089e0df124 | |||
| 8f810ff315 | |||
| a72f606b36 | |||
| dcbe9c4dd2 | |||
| 3278b789dd | |||
| 735c12951c | |||
| 568ad0ebf4 | |||
| a13df9bfa6 | |||
| e5c6cc664d | |||
| f9a340c77c | |||
| a02819261d | |||
| b11d3ccd61 | |||
| 7549219213 | |||
| 9fa8a64949 | |||
| a9eca5029e | |||
| 8bb8526edf | |||
| bcaf594145 | |||
| 27aea7e20d | |||
| bc0419e2c3 | |||
| d421ca5499 |
@ -17,6 +17,7 @@ package com.fuyuanshen.config;
|
||||
|
||||
import com.fuyuanshen.utils.SecurityUtils;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.stereotype.Service;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@ -39,4 +40,5 @@ public class AuthorityConfig {
|
||||
// 判断当前用户的所有权限是否包含接口上定义的权限
|
||||
return elPermissions.contains("admin") || Arrays.stream(permissions).anyMatch(elPermissions::contains);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,8 @@
|
||||
package com.fuyuanshen.constants;
|
||||
|
||||
public class RedisConstants {
|
||||
|
||||
public static final String APP_FORGOT_PASSWORD_SMS_TOKEN = "app_sms_forgotPassword:";
|
||||
|
||||
public static final String APP_REGISTER_SMS_TOKEN = "app_sms_register:";
|
||||
}
|
||||
@ -31,6 +31,8 @@ public interface CacheKey {
|
||||
* 数据
|
||||
*/
|
||||
String DATA_USER = "data::user:";
|
||||
String DATA_APP_USER = "data::appUser:";
|
||||
|
||||
|
||||
/**
|
||||
* 菜单
|
||||
|
||||
@ -229,6 +229,7 @@ public class RedisUtils {
|
||||
* @return 值
|
||||
*/
|
||||
public <T> T get(String key, Class<T> clazz) {
|
||||
System.out.println("get:------------------------"+ key);
|
||||
Object value = key == null ? null : redisTemplate.opsForValue().get(key);
|
||||
if (value == null) {
|
||||
return null;
|
||||
@ -324,6 +325,8 @@ public class RedisUtils {
|
||||
* @return true成功 false 失败
|
||||
*/
|
||||
public boolean set(String key, Object value, long time) {
|
||||
System.out.println("set:------------------------"+ key);
|
||||
|
||||
try {
|
||||
if (time > 0) {
|
||||
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
|
||||
|
||||
@ -16,25 +16,28 @@
|
||||
package com.fuyuanshen.utils;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.jwt.Claims;
|
||||
import cn.hutool.jwt.JWT;
|
||||
import cn.hutool.jwt.JWTUtil;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import com.fuyuanshen.utils.enums.DataScopeEnum;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 获取当前登录的用户
|
||||
*
|
||||
* @author Zheng Jie
|
||||
* @date 2019-01-17
|
||||
*/
|
||||
@ -59,6 +62,7 @@ public class SecurityUtils {
|
||||
|
||||
/**
|
||||
* 获取当前登录的用户
|
||||
*
|
||||
* @return UserDetails
|
||||
*/
|
||||
public static UserDetails getCurrentUser() {
|
||||
@ -68,9 +72,10 @@ public class SecurityUtils {
|
||||
|
||||
/**
|
||||
* 获取当前用户的数据权限
|
||||
*
|
||||
* @return /
|
||||
*/
|
||||
public static List<Long> getCurrentUserDataScope(){
|
||||
public static List<Long> getCurrentUserDataScope() {
|
||||
UserDetails userDetails = getCurrentUser();
|
||||
// 将 Java 对象转换为 JSONObject 对象
|
||||
JSONObject jsonObject = (JSONObject) JSON.toJSON(userDetails);
|
||||
@ -80,11 +85,12 @@ public class SecurityUtils {
|
||||
|
||||
/**
|
||||
* 获取数据权限级别
|
||||
*
|
||||
* @return 级别
|
||||
*/
|
||||
public static String getDataScopeType() {
|
||||
List<Long> dataScopes = getCurrentUserDataScope();
|
||||
if(CollUtil.isEmpty(dataScopes)){
|
||||
if (CollUtil.isEmpty(dataScopes)) {
|
||||
return "";
|
||||
}
|
||||
return DataScopeEnum.ALL.getValue();
|
||||
@ -92,6 +98,7 @@ public class SecurityUtils {
|
||||
|
||||
/**
|
||||
* 获取用户ID
|
||||
*
|
||||
* @return 系统用户ID
|
||||
*/
|
||||
public static Long getCurrentUserId() {
|
||||
@ -100,6 +107,7 @@ public class SecurityUtils {
|
||||
|
||||
/**
|
||||
* 获取用户ID
|
||||
*
|
||||
* @return 系统用户ID
|
||||
*/
|
||||
public static Long getCurrentUserId(String token) {
|
||||
@ -128,11 +136,11 @@ public class SecurityUtils {
|
||||
|
||||
/**
|
||||
* 获取Token
|
||||
*
|
||||
* @return /
|
||||
*/
|
||||
public static String getToken() {
|
||||
HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder
|
||||
.getRequestAttributes())).getRequest();
|
||||
HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
|
||||
String bearerToken = request.getHeader(header);
|
||||
if (bearerToken != null && bearerToken.startsWith(tokenStartWith)) {
|
||||
// 去掉令牌前缀
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
package com.fuyuanshen.utils.enums;
|
||||
|
||||
/**
|
||||
* @author: 默苍璃
|
||||
* @date: 2025-06-2019:08
|
||||
*/
|
||||
/**
|
||||
* 表示 NanoId 生成时使用的长度配置
|
||||
*/
|
||||
public enum NanoIdLengthEnum {
|
||||
|
||||
/**
|
||||
* 默认设备类型 ID 长度
|
||||
*/
|
||||
DEVICE_TYPE_ID(10),
|
||||
|
||||
/**
|
||||
* 更长的唯一标识符,用于高并发场景
|
||||
*/
|
||||
HIGH_CONCURRENCY(15);
|
||||
|
||||
private final int length;
|
||||
|
||||
NanoIdLengthEnum(int length) {
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,93 @@
|
||||
package com.fuyuanshen.modules.MiniProgram.controller;
|
||||
|
||||
import com.fuyuanshen.annotation.Log;
|
||||
import com.fuyuanshen.annotation.rest.AnonymousPostMapping;
|
||||
import com.fuyuanshen.modules.MiniProgram.service.MPService;
|
||||
import com.fuyuanshen.modules.security.config.SecurityProperties;
|
||||
import com.fuyuanshen.modules.security.security.TokenProvider;
|
||||
import com.fuyuanshen.modules.security.service.OnlineUserService;
|
||||
import com.fuyuanshen.modules.security.service.dto.AuthUserDto;
|
||||
import com.fuyuanshen.modules.security.service.dto.AuthorityDto;
|
||||
import com.fuyuanshen.modules.security.service.dto.JwtUserDto;
|
||||
import com.fuyuanshen.modules.system.domain.User;
|
||||
import com.fuyuanshen.modules.system.service.DeviceService;
|
||||
import com.fuyuanshen.modules.utils.ResponseVO;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author: 默苍璃
|
||||
* @date: 2025-06-2313:56
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/mp")
|
||||
@RequiredArgsConstructor
|
||||
@Api(tags = "小程序:相关接口")
|
||||
public class MPController {
|
||||
|
||||
private final TokenProvider tokenProvider;
|
||||
private final SecurityProperties properties;
|
||||
private final OnlineUserService onlineUserService;
|
||||
private final DeviceService deviceService;
|
||||
private final MPService mpService;
|
||||
|
||||
@Log("小程序用户登录")
|
||||
@ApiOperation("小程序登录授权")
|
||||
@AnonymousPostMapping(value = "/login")
|
||||
public ResponseEntity<Object> login(@RequestBody AuthUserDto authUser, HttpServletRequest request) throws Exception {
|
||||
|
||||
// 获取用户信息
|
||||
User user = new User();
|
||||
user.setUsername("MP");
|
||||
user.setPassword("MP");
|
||||
AuthorityDto authorityDto = new AuthorityDto();
|
||||
authorityDto.setAuthority("MP");
|
||||
List<AuthorityDto> authorityDtos = new ArrayList<>();
|
||||
authorityDtos.add(authorityDto);
|
||||
user.setPhone(authUser.getPhoneNumber());
|
||||
JwtUserDto jwtUser = new JwtUserDto(null, user, null, authorityDtos);
|
||||
|
||||
Authentication authentication = new UsernamePasswordAuthenticationToken(jwtUser, null, authorityDtos);
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
// 生成令牌
|
||||
String token = tokenProvider.createToken(jwtUser);
|
||||
// 返回 token 与 用户信息
|
||||
Map<String, Object> authInfo = new HashMap<String, Object>(2) {{
|
||||
put("token", properties.getTokenStartWith() + token);
|
||||
put("user", jwtUser);
|
||||
}};
|
||||
|
||||
// 保存在线信息
|
||||
onlineUserService.save(jwtUser, token, request);
|
||||
|
||||
// 返回登录信息
|
||||
return ResponseEntity.ok(authInfo);
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/queryDevice")
|
||||
@ApiOperation("是否存在设备MAC号")
|
||||
public ResponseVO<Boolean> queryDevice(@ApiParam("设备mac值") String mac) {
|
||||
return ResponseVO.success(mpService.queryDevice(mac));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
package com.fuyuanshen.modules.MiniProgram.service;
|
||||
|
||||
/**
|
||||
* @author: 默苍璃
|
||||
* @date: 2025-06-2314:56
|
||||
*/
|
||||
public interface MPService {
|
||||
Boolean queryDevice(String mac);
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
package com.fuyuanshen.modules.MiniProgram.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.fuyuanshen.modules.MiniProgram.service.MPService;
|
||||
import com.fuyuanshen.modules.system.domain.Device;
|
||||
import com.fuyuanshen.modules.system.mapper.DeviceMapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author: 默苍璃
|
||||
* @date: 2025-06-2314:56
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class MPServiceImpl implements MPService {
|
||||
|
||||
private final DeviceMapper deviceMapper;
|
||||
|
||||
/**
|
||||
* 查询设备MAC号
|
||||
*
|
||||
* @param mac
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Boolean queryDevice(String mac) {
|
||||
QueryWrapper<Device> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq("device_mac", mac);
|
||||
List<Device> deviceList = deviceMapper.selectList(wrapper);
|
||||
if (CollectionUtil.isNotEmpty(deviceList)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -87,4 +87,5 @@ public class AppController {
|
||||
appService.delete(ids);
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,33 @@
|
||||
package com.fuyuanshen.modules.mqtt.config;
|
||||
|
||||
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory;
|
||||
import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
|
||||
|
||||
/**
|
||||
* @Author: HarryLin
|
||||
* @Date: 2025/3/20 14:40
|
||||
* @Company: 北京红山信息科技研究院有限公司
|
||||
* @Email: linyun@***.com.cn
|
||||
**/
|
||||
@Configuration
|
||||
public class MqttConfiguration {
|
||||
@Autowired
|
||||
private MqttPropertiesConfig mqttPropertiesConfig;
|
||||
/** 创建连接工厂 **/
|
||||
@Bean
|
||||
public MqttPahoClientFactory mqttPahoClientFactory(){
|
||||
DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
|
||||
MqttConnectOptions options = new MqttConnectOptions();
|
||||
options.setCleanSession(true); //设置新会话
|
||||
options.setUserName(mqttPropertiesConfig.getUsername());
|
||||
options.setPassword(mqttPropertiesConfig.getPassword().toCharArray());
|
||||
options.setServerURIs(new String[]{mqttPropertiesConfig.getUrl()});
|
||||
factory.setConnectionOptions(options);
|
||||
return factory;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
package com.fuyuanshen.modules.mqtt.config;
|
||||
|
||||
import org.springframework.integration.annotation.MessagingGateway;
|
||||
import org.springframework.integration.mqtt.support.MqttHeaders;
|
||||
import org.springframework.messaging.handler.annotation.Header;
|
||||
|
||||
/**
|
||||
* @Author: HarryLin
|
||||
* @Date: 2025/3/20 17:06
|
||||
* @Company: 北京红山信息科技研究院有限公司
|
||||
* @Email: linyun@***.com.cn
|
||||
**/
|
||||
@MessagingGateway(defaultRequestChannel = "mqttOutboundChannel")
|
||||
public interface MqttGateway {
|
||||
public abstract void sendMsgToMqtt(@Header(value = MqttHeaders.TOPIC) String topic, String payload);
|
||||
public abstract void sendMsgToMqtt(@Header(value = MqttHeaders.TOPIC) String topic, @Header(value = MqttHeaders.QOS) int qos, String payload );
|
||||
}
|
||||
@ -0,0 +1,60 @@
|
||||
package com.fuyuanshen.modules.mqtt.config;
|
||||
|
||||
|
||||
import com.fuyuanshen.modules.mqtt.receiver.ReceiverMessageHandler;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.integration.annotation.ServiceActivator;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
import org.springframework.integration.core.MessageProducer;
|
||||
import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
|
||||
import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter;
|
||||
import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
|
||||
/**
|
||||
* @Author: HarryLin
|
||||
* @Date: 2025/3/20 14:54
|
||||
* @Company: 北京红山信息科技研究院有限公司
|
||||
* @Email: linyun@***.com.cn
|
||||
**/
|
||||
@Configuration
|
||||
public class MqttInboundConfiguration {
|
||||
@Autowired
|
||||
private MqttPropertiesConfig mqttPropertiesConfig;
|
||||
@Autowired
|
||||
private MqttPahoClientFactory mqttPahoClientFactory;
|
||||
@Autowired
|
||||
private ReceiverMessageHandler receiverMessageHandler;
|
||||
//消息通道
|
||||
@Bean
|
||||
public MessageChannel messageInboundChannel(){
|
||||
return new DirectChannel();
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置入站适配器
|
||||
* 作用: 设置订阅主题,以及指定消息的通道 等相关属性
|
||||
* */
|
||||
@Bean
|
||||
public MessageProducer messageProducer(){
|
||||
MqttPahoMessageDrivenChannelAdapter mqttPahoMessageDrivenChannelAdapter = new MqttPahoMessageDrivenChannelAdapter(
|
||||
mqttPropertiesConfig.getUrl(),
|
||||
mqttPropertiesConfig.getSubClientId(),
|
||||
mqttPahoClientFactory,
|
||||
mqttPropertiesConfig.getSubTopic().split(",")
|
||||
);
|
||||
mqttPahoMessageDrivenChannelAdapter.setQos(1);
|
||||
mqttPahoMessageDrivenChannelAdapter.setConverter(new DefaultPahoMessageConverter());
|
||||
mqttPahoMessageDrivenChannelAdapter.setOutputChannel(messageInboundChannel());
|
||||
return mqttPahoMessageDrivenChannelAdapter;
|
||||
}
|
||||
/** 指定处理消息来自哪个通道 */
|
||||
@Bean
|
||||
@ServiceActivator(inputChannel = "messageInboundChannel")
|
||||
public MessageHandler messageHandler(){
|
||||
return receiverMessageHandler;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
package com.fuyuanshen.modules.mqtt.config;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.integration.annotation.ServiceActivator;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
|
||||
import org.springframework.integration.mqtt.outbound.MqttPahoMessageHandler;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
|
||||
/**
|
||||
* @Author: HarryLin
|
||||
* @Date: 2025/3/20 15:46
|
||||
* @Company: 北京红山信息科技研究院有限公司
|
||||
* @Email: linyun@***.com.cn
|
||||
**/
|
||||
@Configuration
|
||||
@Slf4j
|
||||
public class MqttOutboundConfiguration {
|
||||
@Autowired
|
||||
private MqttPropertiesConfig mqttPropertiesConfig;
|
||||
@Autowired
|
||||
private MqttPahoClientFactory mqttPahoClientFactory;
|
||||
|
||||
// 消息通道
|
||||
@Bean
|
||||
public MessageChannel mqttOutboundChannel(){
|
||||
return new DirectChannel();
|
||||
}
|
||||
|
||||
|
||||
/** 配置出站消息处理器 */
|
||||
@Bean
|
||||
@ServiceActivator(inputChannel = "mqttOutboundChannel") // 指定处理器针对哪个通道的消息进行处理
|
||||
public MessageHandler mqttOutboundMessageHandler(){
|
||||
MqttPahoMessageHandler mqttPahoMessageHandler = new MqttPahoMessageHandler(
|
||||
mqttPropertiesConfig.getUrl(),
|
||||
mqttPropertiesConfig.getPubClientId(),
|
||||
mqttPahoClientFactory
|
||||
);
|
||||
mqttPahoMessageHandler.setDefaultQos(1);
|
||||
mqttPahoMessageHandler.setDefaultTopic("worker/location");
|
||||
mqttPahoMessageHandler.setAsync(true);
|
||||
return mqttPahoMessageHandler;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package com.fuyuanshen.modules.mqtt.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @Author: HarryLin
|
||||
* @Date: 2025/3/20 14:32
|
||||
* @Company: 北京红山信息科技研究院有限公司
|
||||
* @Email: linyun@***.com.cn
|
||||
**/
|
||||
@Data
|
||||
@ConfigurationProperties(prefix = "mqtt")
|
||||
@Component
|
||||
public class MqttPropertiesConfig {
|
||||
private String username;
|
||||
private String password;
|
||||
private String url;
|
||||
private String subClientId;
|
||||
private String subTopic;
|
||||
private String pubClientId;
|
||||
private String pubTopic;
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
package com.fuyuanshen.modules.mqtt.publish;
|
||||
|
||||
import com.fuyuanshen.annotation.rest.AnonymousGetMapping;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/device")
|
||||
@Slf4j
|
||||
public class DeviceDataController {
|
||||
|
||||
@Autowired
|
||||
private MqttClientTest mqttClientTest;
|
||||
|
||||
// @PostMapping("/{deviceId}/command")
|
||||
@AnonymousGetMapping(value = "/test/command")
|
||||
public ResponseEntity<String> sendCommand() {
|
||||
|
||||
mqttClientTest.sendMsg();
|
||||
return ResponseEntity.ok("success");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
package com.fuyuanshen.modules.mqtt.publish;
|
||||
|
||||
|
||||
import com.fuyuanshen.modules.mqtt.config.MqttGateway;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class MqttClientTest {
|
||||
@Autowired
|
||||
private MqttGateway mqttGateway;
|
||||
|
||||
public void sendMsg() {
|
||||
mqttGateway.sendMsgToMqtt("worker/location/1", "hello mqtt spring boot");
|
||||
log.info("message is send");
|
||||
|
||||
mqttGateway.sendMsgToMqtt("worker/alert/2", "hello mqtt spring boot2");
|
||||
log.info("message is send2");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
package com.fuyuanshen.modules.mqtt.publish;
|
||||
|
||||
import com.fuyuanshen.modules.mqtt.config.MqttGateway;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.integration.mqtt.support.MqttHeaders;
|
||||
import org.springframework.messaging.handler.annotation.Header;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @Author: HarryLin
|
||||
* @Date: 2025/3/20 16:16
|
||||
* @Company: 北京红山信息科技研究院有限公司
|
||||
* @Email: linyun@***.com.cn
|
||||
**/
|
||||
@Service
|
||||
public class MqttMessageSender {
|
||||
@Autowired
|
||||
private MqttGateway mqttGateway;
|
||||
public void sendMsg(@Header(value = MqttHeaders.TOPIC) String topic, String payload) {
|
||||
mqttGateway.sendMsgToMqtt(topic,payload);
|
||||
}
|
||||
public void sendMsg(@Header(value = MqttHeaders.TOPIC) String topic, @Header(value = MqttHeaders.QOS) int qos, String payload) {
|
||||
mqttGateway.sendMsgToMqtt(topic,qos,payload);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
package com.fuyuanshen.modules.mqtt.receiver;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @Author: HarryLin
|
||||
* @Date: 2025/3/20 15:24
|
||||
* @Company: 北京红山信息科技研究院有限公司
|
||||
* @Email: linyun@***.com.cn
|
||||
**/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class ReceiverMessageHandler implements MessageHandler {
|
||||
@Override
|
||||
public void handleMessage(Message<?> message) throws MessagingException{
|
||||
Object payload = message.getPayload();
|
||||
MessageHeaders headers = message.getHeaders();
|
||||
String receivedTopic = Objects.requireNonNull(headers.get("mqtt_receivedTopic")).toString();
|
||||
String receivedQos = Objects.requireNonNull(headers.get("mqtt_receivedQos")).toString();
|
||||
String timestamp = Objects.requireNonNull(headers.get("timestamp")).toString();
|
||||
log.info("MQTT payload= {} \n receivedTopic = {} \n receivedQos = {} \n timestamp = {}"
|
||||
,payload,receivedTopic,receivedQos,timestamp);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
package com.fuyuanshen.modules.security.config;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.integration.annotation.ServiceActivator;
|
||||
import org.springframework.integration.mqtt.support.MqttHeaders;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class DeviceDataService {
|
||||
|
||||
|
||||
@ServiceActivator(inputChannel = "mqttInputChannel")
|
||||
public void handleDeviceData(Message<?> message) {
|
||||
String topic = message.getHeaders().get(MqttHeaders.RECEIVED_TOPIC).toString();
|
||||
String payload = message.getPayload().toString();
|
||||
|
||||
// 解析设备数据
|
||||
if (topic.startsWith("device/data/")) {
|
||||
log.info("Received device data device/data/: {} {}", topic, payload);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -31,10 +31,11 @@ import org.springframework.context.annotation.Configuration;
|
||||
public class LoginProperties {
|
||||
|
||||
/**
|
||||
* 账号单用户 登录
|
||||
* 账号单用户
|
||||
*/
|
||||
private boolean singleLogin = false;
|
||||
|
||||
public static final String cacheKey = "user_login_cache:";
|
||||
public static final String cacheKey_app = "app_user_login_cache:";
|
||||
|
||||
}
|
||||
|
||||
@ -55,6 +55,11 @@ public class SecurityProperties {
|
||||
*/
|
||||
private String onlineKey;
|
||||
|
||||
/**
|
||||
* app在线用户
|
||||
*/
|
||||
private String appOnlineKey;
|
||||
|
||||
/**
|
||||
* 验证码 key
|
||||
*/
|
||||
|
||||
@ -17,6 +17,7 @@ package com.fuyuanshen.modules.security.rest;
|
||||
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.crypto.digest.MD5;
|
||||
import com.fuyuanshen.annotation.Log;
|
||||
import com.fuyuanshen.annotation.rest.AnonymousDeleteMapping;
|
||||
import com.fuyuanshen.annotation.rest.AnonymousGetMapping;
|
||||
@ -27,29 +28,36 @@ import com.fuyuanshen.modules.security.config.LoginProperties;
|
||||
import com.fuyuanshen.modules.security.config.SecurityProperties;
|
||||
import com.fuyuanshen.modules.security.config.enums.LoginCodeEnum;
|
||||
import com.fuyuanshen.modules.security.security.TokenProvider;
|
||||
import com.fuyuanshen.modules.security.security.app.AppTokenProvider;
|
||||
import com.fuyuanshen.modules.security.service.OnlineUserService;
|
||||
import com.fuyuanshen.modules.security.service.UserDetailsServiceImpl;
|
||||
import com.fuyuanshen.modules.security.service.dto.app.AppAuthUserQuery;
|
||||
import com.fuyuanshen.modules.security.service.dto.app.AppAuthUserDto;
|
||||
import com.fuyuanshen.modules.security.service.dto.app.AppJwtUserDto;
|
||||
import com.fuyuanshen.modules.security.service.dto.app.AppRoleDto;
|
||||
import com.fuyuanshen.modules.security.service.dto.AuthUserDto;
|
||||
import com.fuyuanshen.modules.security.service.dto.JwtUserDto;
|
||||
import com.fuyuanshen.modules.system.domain.app.APPUser;
|
||||
import com.fuyuanshen.modules.system.domain.query.APPUserDto;
|
||||
import com.fuyuanshen.modules.system.domain.query.APPUserQuery;
|
||||
import com.fuyuanshen.modules.system.mapper.app.APPUserMapper;
|
||||
import com.fuyuanshen.modules.system.service.app.APPUserService;
|
||||
import com.fuyuanshen.modules.utils.ResponseVO;
|
||||
import com.fuyuanshen.utils.RedisUtils;
|
||||
import com.fuyuanshen.utils.SecurityUtils;
|
||||
import com.fuyuanshen.utils.StringUtils;
|
||||
import com.wf.captcha.base.Captcha;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.ss.formula.functions.T;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
@ -57,7 +65,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -77,12 +85,13 @@ public class AuthController {
|
||||
private final SecurityProperties properties;
|
||||
private final RedisUtils redisUtils;
|
||||
private final OnlineUserService onlineUserService;
|
||||
private final AppTokenProvider appTokenProvider;
|
||||
private final TokenProvider tokenProvider;
|
||||
private final CaptchaConfig captchaConfig;
|
||||
private final LoginProperties loginProperties;
|
||||
private final UserDetailsServiceImpl userDetailsService;
|
||||
private final APPUserMapper appUserMapper;
|
||||
|
||||
private final APPUserService appUserService;
|
||||
@Log("用户登录")
|
||||
@ApiOperation("登录授权")
|
||||
@AnonymousPostMapping(value = "/login")
|
||||
@ -134,67 +143,21 @@ public class AuthController {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Log("app用户注册")
|
||||
@ApiOperation("app用户注册")
|
||||
@AnonymousPostMapping(value = "/app/register")
|
||||
public ResponseEntity<Boolean> APPRegister(@Validated @RequestBody AppAuthUserQuery authUser, HttpServletRequest request) throws Exception {
|
||||
|
||||
// 校验手机号是否为空
|
||||
if (StringUtils.isBlank(authUser.getPhoneNumber())) {
|
||||
throw new BadRequestException("手机号不能为空");
|
||||
}
|
||||
|
||||
// 验证验证码(示例)
|
||||
int verificationCode = 0000;
|
||||
if (authUser.getVerificationCode() != verificationCode) {
|
||||
throw new BadRequestException("验证码错误");
|
||||
}
|
||||
// 构建用户对象
|
||||
APPUserDto appUserDTO = new APPUserDto();
|
||||
appUserDTO.setUsername(authUser.getPhoneNumber());
|
||||
appUserDTO.setPassword(authUser.getPassword());
|
||||
appUserDTO.setPhoneNumber(authUser.getPhoneNumber());
|
||||
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
appUserDTO.setCreateTime(now);
|
||||
appUserDTO.setUpdateTime(now);
|
||||
|
||||
log.debug("注册参数: {}", appUserDTO);
|
||||
|
||||
// 检查手机号是否已注册
|
||||
APPUser existingUser = appUserMapper.selectByQueryOne(appUserDTO);
|
||||
if (existingUser != null) {
|
||||
throw new BadRequestException("手机号已注册");
|
||||
}
|
||||
|
||||
// 执行注册
|
||||
boolean isRegistered = appUserMapper.createAppUser(appUserDTO);
|
||||
if (!isRegistered) {
|
||||
throw new BadRequestException("注册失败");
|
||||
}
|
||||
|
||||
return ResponseEntity.ok(true);
|
||||
|
||||
}
|
||||
|
||||
@Log("app用户登录")
|
||||
@ApiOperation("app用户登录")
|
||||
@AnonymousPostMapping(value = "/app/login")
|
||||
public ResponseEntity<Object> APPLogin(@Validated @RequestBody AppAuthUserQuery authUser, HttpServletRequest request) throws Exception {
|
||||
public ResponseVO<Object> APPLogin(@Validated @RequestBody AppAuthUserDto authUser, HttpServletRequest request) throws Exception {
|
||||
|
||||
// 1. 构建查询参数
|
||||
APPUserDto appUserDTO = new APPUserDto();
|
||||
appUserDTO.setPhoneNumber(authUser.getPhoneNumber());
|
||||
appUserDTO.setPassword(authUser.getPassword());
|
||||
|
||||
|
||||
log.debug("登录参数: {}", appUserDTO);
|
||||
APPUserQuery appUserQuery = new APPUserQuery();
|
||||
appUserQuery.setPhoneNumber(authUser.getPhoneNumber());
|
||||
appUserQuery.setPassword(authUser.getPassword());
|
||||
appUserQuery.setUsername(authUser.getPhoneNumber());
|
||||
log.debug("登录参数: {}", appUserQuery);
|
||||
|
||||
// 2. 查询用户
|
||||
APPUser appUser = appUserMapper.selectByQueryOne(appUserDTO);
|
||||
APPUser appUser = appUserMapper.selectByQueryOne(appUserQuery);
|
||||
log.debug("查询用户: {}", appUser);
|
||||
if (appUser == null) {
|
||||
log.debug("手机号未注册: {}", authUser.getPhoneNumber());
|
||||
throw new BadRequestException("手机号未注册");
|
||||
@ -206,23 +169,22 @@ public class AuthController {
|
||||
}
|
||||
|
||||
// 4. 加载用户详情
|
||||
JwtUserDto jwtUser = userDetailsService.loadUserByUsername(appUser.getUsername());
|
||||
JwtUserDto jwtUser = userDetailsService.loadUserByAppUsername(appUser.getUsername());
|
||||
|
||||
// 5. 创建认证信息
|
||||
Authentication authentication = new UsernamePasswordAuthenticationToken(jwtUser, null, jwtUser.getAuthorities());
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
|
||||
// 6. 生成 Token
|
||||
String token = tokenProvider.createToken(jwtUser);
|
||||
String token = appTokenProvider.createAppToken(jwtUser);
|
||||
|
||||
// 7. 获取角色权限
|
||||
AppRoleDto appRoleDto = appUserMapper.selectRoleByUserLevel(appUser.getUserLevel());
|
||||
//Integer optLevel = appUserService.selectRoleByUserLevel(appUser.getRoles());
|
||||
|
||||
// 8. 构建响应数据
|
||||
Map<String, Object> authInfo = new HashMap<>(3) {{
|
||||
Map<String, Object> authInfo = new HashMap<>(2) {{
|
||||
put("token", properties.getTokenStartWith() + token);
|
||||
put("user", jwtUser);
|
||||
put("role", appRoleDto);
|
||||
}};
|
||||
|
||||
// 9. 单点登录踢人
|
||||
@ -231,10 +193,10 @@ public class AuthController {
|
||||
}
|
||||
|
||||
// 10. 记录在线状态
|
||||
onlineUserService.save(jwtUser, token, request);
|
||||
onlineUserService.saveAppOnlineUser(jwtUser, token, request);
|
||||
|
||||
// 11. 返回结果
|
||||
return ResponseEntity.ok(authInfo);
|
||||
return ResponseVO.success(authInfo);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -27,6 +27,7 @@ import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
@ -45,8 +46,8 @@ public class OnlineController {
|
||||
@ApiOperation("查询在线用户")
|
||||
@GetMapping
|
||||
@PreAuthorize("@el.check()")
|
||||
public ResponseEntity<PageResult<OnlineUserDto>> queryOnlineUser(String username, Pageable pageable){
|
||||
return new ResponseEntity<>(onlineUserService.getAll(username, pageable),HttpStatus.OK);
|
||||
public ResponseEntity<PageResult<OnlineUserDto>> queryOnlineUser(String username, Pageable pageable) {
|
||||
return new ResponseEntity<>(onlineUserService.getAll(username, pageable), HttpStatus.OK);
|
||||
}
|
||||
|
||||
@ApiOperation("导出数据")
|
||||
@ -67,4 +68,5 @@ public class OnlineController {
|
||||
}
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -30,6 +30,7 @@ import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.stereotype.Component;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.security.Key;
|
||||
@ -75,9 +76,10 @@ public class TokenProvider implements InitializingBean {
|
||||
claims.put(AUTHORITIES_UID_KEY, user.getUser().getId());
|
||||
// 设置UUID,确保每次Token不一样
|
||||
claims.put(AUTHORITIES_UUID_KEY, IdUtil.simpleUUID());
|
||||
claims.put("userType","0");//0 系统登录 1 APP登录
|
||||
return jwtBuilder
|
||||
.setClaims(claims)
|
||||
.setSubject(user.getUsername())
|
||||
.setSubject(user.getUser().getUsername())
|
||||
.compact();
|
||||
}
|
||||
|
||||
@ -134,6 +136,16 @@ public class TokenProvider implements InitializingBean {
|
||||
return properties.getOnlineKey() + claims.getSubject() + ":" + getId(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取app登录用户RedisKey
|
||||
* @param token /
|
||||
* @return key
|
||||
*/
|
||||
public String appLoginKey(String token) {
|
||||
Claims claims = getClaims(token);
|
||||
return properties.getAppOnlineKey() + claims.getSubject() + ":" + getId(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取会话编号
|
||||
* @param token /
|
||||
|
||||
@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright 2019-2025 Zheng Jie
|
||||
*
|
||||
* 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.fuyuanshen.modules.security.security.app;
|
||||
|
||||
import cn.hutool.core.date.DateField;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import com.fuyuanshen.modules.security.config.SecurityProperties;
|
||||
import com.fuyuanshen.modules.security.service.dto.JwtUserDto;
|
||||
import com.fuyuanshen.modules.security.service.dto.app.AppJwtUserDto;
|
||||
import com.fuyuanshen.utils.RedisUtils;
|
||||
import io.jsonwebtoken.*;
|
||||
import io.jsonwebtoken.io.Decoders;
|
||||
import io.jsonwebtoken.security.Keys;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.security.Key;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author /
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class AppTokenProvider implements InitializingBean {
|
||||
|
||||
private JwtParser jwtParser;
|
||||
private JwtBuilder jwtBuilder;
|
||||
private final RedisUtils redisUtils;
|
||||
private final SecurityProperties properties;
|
||||
public static final String AUTHORITIES_UUID_KEY = "uid";
|
||||
public static final String AUTHORITIES_UID_KEY = "userId";
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
byte[] keyBytes = Decoders.BASE64.decode(properties.getBase64Secret());
|
||||
Key key = Keys.hmacShaKeyFor(keyBytes);
|
||||
jwtParser = Jwts.parserBuilder()
|
||||
.setSigningKey(key)
|
||||
.build();
|
||||
jwtBuilder = Jwts.builder()
|
||||
.signWith(key, SignatureAlgorithm.HS512);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建Token 设置永不过期,
|
||||
* Token 的时间有效性转到Redis 维护
|
||||
*
|
||||
* @param user /
|
||||
* @return /
|
||||
*/
|
||||
public String createToken(JwtUserDto user) {
|
||||
// 设置参数
|
||||
Map<String, Object> claims = new HashMap<>(6);
|
||||
// 设置用户ID
|
||||
claims.put(AUTHORITIES_UID_KEY, user.getAppUser().getId());
|
||||
// if (user.getAppUser() != null){
|
||||
// claims.put(AUTHORITIES_UID_KEY, user.getAppUser().getId());
|
||||
// }else {
|
||||
// claims.put(AUTHORITIES_UID_KEY, 0);
|
||||
// }
|
||||
// 设置UUID,确保每次Token不一样
|
||||
claims.put(AUTHORITIES_UUID_KEY, IdUtil.simpleUUID());
|
||||
return jwtBuilder
|
||||
.setClaims(claims)
|
||||
.setSubject(user.getUsername())
|
||||
.compact();
|
||||
}
|
||||
|
||||
/**
|
||||
* APP创建Token 设置永不过期,
|
||||
* Token 的时间有效性转到Redis 维护
|
||||
*
|
||||
* @param user /
|
||||
* @return /
|
||||
*/
|
||||
public String createAppToken(JwtUserDto user) {
|
||||
// 设置参数
|
||||
Map<String, Object> claims = new HashMap<>(6);
|
||||
|
||||
// 设置用户ID
|
||||
claims.put(AUTHORITIES_UID_KEY, user.getAppUser().getId());
|
||||
// if (user.getAppUser() != null){
|
||||
// claims.put(AUTHORITIES_UID_KEY, user.getAppUser().getId());
|
||||
// }else {
|
||||
// claims.put(AUTHORITIES_UID_KEY, 0);
|
||||
// }
|
||||
// 设置UUID,确保每次Token不一样
|
||||
claims.put(AUTHORITIES_UUID_KEY, IdUtil.simpleUUID());
|
||||
claims.put("userType", "1");// 0 系统登录 1 APP登录
|
||||
return jwtBuilder
|
||||
.setClaims(claims)
|
||||
.setSubject(user.getAppUser().getUsername())
|
||||
.compact();
|
||||
}
|
||||
|
||||
/**
|
||||
* 依据Token 获取鉴权信息
|
||||
*
|
||||
* @param token /
|
||||
* @return /
|
||||
*/
|
||||
Authentication getAuthentication(String token) {
|
||||
Claims claims = getClaims(token);
|
||||
User principal = new User(claims.getSubject(), "******", new ArrayList<>());
|
||||
return new UsernamePasswordAuthenticationToken(principal, token, new ArrayList<>());
|
||||
}
|
||||
|
||||
public Claims getClaims(String token) {
|
||||
return jwtParser
|
||||
.parseClaimsJws(token)
|
||||
.getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param token 需要检查的token
|
||||
*/
|
||||
public void checkRenewal(String token) {
|
||||
// 判断是否续期token,计算token的过期时间
|
||||
String loginKey = loginKey(token);
|
||||
long time = redisUtils.getExpire(loginKey) * 1000;
|
||||
Date expireDate = DateUtil.offset(new Date(), DateField.MILLISECOND, (int) time);
|
||||
// 判断当前时间与过期时间的时间差
|
||||
long differ = expireDate.getTime() - System.currentTimeMillis();
|
||||
// 如果在续期检查的范围内,则续期
|
||||
if (differ <= properties.getDetect()) {
|
||||
long renew = time + properties.getRenew();
|
||||
redisUtils.expire(loginKey, renew, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
public String getToken(HttpServletRequest request) {
|
||||
final String requestHeader = request.getHeader(properties.getHeader());
|
||||
if (requestHeader != null && requestHeader.startsWith(properties.getTokenStartWith())) {
|
||||
return requestHeader.substring(7);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登录用户RedisKey
|
||||
*
|
||||
* @param token /
|
||||
* @return key
|
||||
*/
|
||||
public String loginKey(String token) {
|
||||
Claims claims = getClaims(token);
|
||||
return properties.getOnlineKey() + claims.getSubject() + ":" + getId(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取会话编号
|
||||
*
|
||||
* @param token /
|
||||
* @return /
|
||||
*/
|
||||
public String getId(String token) {
|
||||
Claims claims = getClaims(token);
|
||||
return claims.get(AUTHORITIES_UUID_KEY, String.class);
|
||||
}
|
||||
}
|
||||
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.fuyuanshen.modules.security.service;
|
||||
|
||||
import com.fuyuanshen.modules.security.service.dto.app.AppJwtUserDto;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import com.fuyuanshen.modules.security.security.TokenProvider;
|
||||
@ -44,6 +45,7 @@ public class OnlineUserService {
|
||||
private final TokenProvider tokenProvider;
|
||||
private final RedisUtils redisUtils;
|
||||
|
||||
|
||||
/**
|
||||
* 保存在线用户信息
|
||||
* @param jwtUserDto /
|
||||
@ -66,6 +68,29 @@ public class OnlineUserService {
|
||||
redisUtils.set(loginKey, onlineUserDto, properties.getTokenValidityInSeconds(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存在线用户信息
|
||||
* @param jwtUserDto /
|
||||
* @param token /
|
||||
* @param request /
|
||||
*/
|
||||
public void saveAppOnlineUser(JwtUserDto jwtUserDto, String token, HttpServletRequest request){
|
||||
String dept = jwtUserDto.getAppUser().getDept() == null ? null : jwtUserDto.getAppUser().getDept().getName();
|
||||
String ip = StringUtils.getIp(request);
|
||||
String id = tokenProvider.getId(token);
|
||||
String browser = StringUtils.getBrowser(request);
|
||||
String address = StringUtils.getCityInfo(ip);
|
||||
OnlineUserDto onlineUserDto = null;
|
||||
try {
|
||||
onlineUserDto = new OnlineUserDto(id, jwtUserDto.getAppUser().getUsername(), jwtUserDto.getAppUser().getNickName(), dept, browser , ip, address, EncryptUtils.desEncrypt(token), new Date());
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
}
|
||||
String loginKey = tokenProvider.loginKey(token);
|
||||
redisUtils.set(loginKey, onlineUserDto, properties.getTokenValidityInSeconds(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询全部数据
|
||||
* @param username /
|
||||
|
||||
@ -18,11 +18,13 @@ package com.fuyuanshen.modules.security.service;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import com.fuyuanshen.modules.security.config.LoginProperties;
|
||||
import com.fuyuanshen.modules.security.service.dto.JwtUserDto;
|
||||
import com.fuyuanshen.modules.security.service.dto.app.AppJwtUserDto;
|
||||
import com.fuyuanshen.utils.RedisUtils;
|
||||
import com.fuyuanshen.utils.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
@ -38,8 +40,10 @@ public class UserCacheManager {
|
||||
@Value("${login.user-cache.idle-time}")
|
||||
private long idleTime;
|
||||
|
||||
|
||||
/**
|
||||
* 返回用户缓存
|
||||
*
|
||||
* @param userName 用户名
|
||||
* @return JwtUserDto
|
||||
*/
|
||||
@ -50,11 +54,30 @@ public class UserCacheManager {
|
||||
// 获取数据
|
||||
return redisUtils.get(LoginProperties.cacheKey + userName, JwtUserDto.class);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加缓存到Redis
|
||||
* 返回用户缓存
|
||||
*
|
||||
* @param userName 用户名
|
||||
* @return JwtUserDto
|
||||
*/
|
||||
public JwtUserDto getAppUserCache(String userName) {
|
||||
// 转小写
|
||||
userName = StringUtils.lowerCase(userName);
|
||||
if (StringUtils.isNotEmpty(userName)) {
|
||||
// 获取数据
|
||||
return redisUtils.get(LoginProperties.cacheKey_app + userName, JwtUserDto.class);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加缓存到Redis
|
||||
*
|
||||
* @param userName 用户名
|
||||
*/
|
||||
@Async
|
||||
@ -71,6 +94,7 @@ public class UserCacheManager {
|
||||
/**
|
||||
* 清理用户缓存信息
|
||||
* 用户信息变更时
|
||||
*
|
||||
* @param userName 用户名
|
||||
*/
|
||||
@Async
|
||||
@ -82,4 +106,81 @@ public class UserCacheManager {
|
||||
redisUtils.del(LoginProperties.cacheKey + userName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回用户缓存
|
||||
*
|
||||
* @param userName 用户名
|
||||
* @return JwtUserDto
|
||||
*/
|
||||
public AppJwtUserDto getUserCache(String userName, Integer userType) {
|
||||
// 转小写
|
||||
userName = StringUtils.lowerCase(userName);
|
||||
if (StringUtils.isNotEmpty(userName)) {
|
||||
// 获取数据
|
||||
try {
|
||||
AppJwtUserDto jwtUserDto = redisUtils.get(LoginProperties.cacheKey_app + userName, AppJwtUserDto.class);
|
||||
if (jwtUserDto != null) {
|
||||
jwtUserDto.getUsername();
|
||||
}
|
||||
return jwtUserDto;
|
||||
} catch (Exception e) {
|
||||
// redisUtils.del(LoginProperties.cacheKey + userName);
|
||||
cleanUserCache(userName);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加缓存到Redis
|
||||
*
|
||||
* @param userName 用户名
|
||||
*/
|
||||
@Async
|
||||
public void addUserCache(String userName, JwtUserDto user, Integer userType) {
|
||||
// 转小写
|
||||
userName = StringUtils.lowerCase(userName);
|
||||
if (StringUtils.isNotEmpty(userName)) {
|
||||
// 添加数据, 避免数据同时过期
|
||||
long time = idleTime + RandomUtil.randomInt(900, 1800);
|
||||
redisUtils.set(LoginProperties.cacheKey_app + userName, user, time);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* App用户添加缓存到Redis
|
||||
*
|
||||
* @param userName 用户名
|
||||
*/
|
||||
@Async
|
||||
public void addAppUserCache(String userName, JwtUserDto user) {
|
||||
// 转小写
|
||||
userName = StringUtils.lowerCase(userName);
|
||||
if (StringUtils.isNotEmpty(userName)) {
|
||||
// 添加数据, 避免数据同时过期
|
||||
long time = idleTime + RandomUtil.randomInt(900, 1800);
|
||||
redisUtils.set(LoginProperties.cacheKey_app + userName, user, time);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理用户缓存信息
|
||||
* 用户信息变更时
|
||||
*
|
||||
* @param userName 用户名
|
||||
*/
|
||||
@Async
|
||||
public void cleanUserCache(String userName, Integer userType) {
|
||||
// 转小写
|
||||
userName = StringUtils.lowerCase(userName);
|
||||
if (StringUtils.isNotEmpty(userName)) {
|
||||
// 清除数据
|
||||
redisUtils.del(LoginProperties.cacheKey_app + userName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -15,15 +15,19 @@
|
||||
*/
|
||||
package com.fuyuanshen.modules.security.service;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import cn.hutool.jwt.JWT;
|
||||
import cn.hutool.jwt.JWTUtil;
|
||||
import com.fuyuanshen.exception.BadRequestException;
|
||||
import com.fuyuanshen.modules.security.service.dto.AuthorityDto;
|
||||
import com.fuyuanshen.modules.security.service.dto.JwtUserDto;
|
||||
import com.fuyuanshen.modules.system.domain.User;
|
||||
import com.fuyuanshen.modules.system.domain.app.APPUser;
|
||||
import com.fuyuanshen.modules.system.service.DataService;
|
||||
import com.fuyuanshen.modules.system.service.RoleService;
|
||||
import com.fuyuanshen.modules.system.service.UserService;
|
||||
import com.fuyuanshen.utils.SecurityUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@ -43,9 +47,30 @@ public class UserDetailsServiceImpl implements UserDetailsService {
|
||||
private final DataService dataService;
|
||||
private final UserCacheManager userCacheManager;
|
||||
|
||||
private final static String APP_USER_TYPE = "1"; // app用户类型
|
||||
|
||||
private final static String SYSTEM_USER_TYPE = "0"; // 系统用户类型
|
||||
@Override
|
||||
public JwtUserDto loadUserByUsername(String username) {
|
||||
if(SecurityUtils.getToken() != null){
|
||||
JWT jwt = JWTUtil.parseToken(SecurityUtils.getToken());
|
||||
String userType = jwt.getPayload("userType").toString();
|
||||
if(APP_USER_TYPE.equals(userType)){
|
||||
return loadUserByAppUsername(username);
|
||||
}else{
|
||||
return loadSystemUserByUsername(username);
|
||||
}
|
||||
}else{
|
||||
return loadSystemUserByUsername(username);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载系统用户详情信息
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
private JwtUserDto loadSystemUserByUsername(String username) {
|
||||
JwtUserDto jwtUserDto = userCacheManager.getUserCache(username);
|
||||
if (jwtUserDto == null) {
|
||||
User user = userService.getLoginData(username);
|
||||
@ -58,11 +83,40 @@ public class UserDetailsServiceImpl implements UserDetailsService {
|
||||
// 获取用户的权限
|
||||
List<AuthorityDto> authorities = roleService.buildPermissions(user);
|
||||
// 初始化JwtUserDto
|
||||
jwtUserDto = new JwtUserDto(user, dataService.getDeptIds(user), authorities);
|
||||
jwtUserDto = new JwtUserDto(null,user, dataService.getDeptIds(user), authorities);
|
||||
// 添加缓存数据
|
||||
userCacheManager.addUserCache(username, jwtUserDto);
|
||||
}
|
||||
}
|
||||
return jwtUserDto;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载app用户详情信息
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
public JwtUserDto loadUserByAppUsername(String username) {
|
||||
|
||||
JwtUserDto jwtUserDto = userCacheManager.getAppUserCache(username);
|
||||
if (jwtUserDto == null) {
|
||||
APPUser user = userService.appGetLoginData(username);
|
||||
if (user == null) {
|
||||
throw new BadRequestException("用户不存在");
|
||||
} else {
|
||||
if (!user.getEnabled()) {
|
||||
throw new BadRequestException("账号未激活!");
|
||||
}
|
||||
// 获取用户的权限
|
||||
List<AuthorityDto> authorities = roleService.appBuildPermissions(user);
|
||||
// 初始化JwtUserDto
|
||||
jwtUserDto = new JwtUserDto(user,null, dataService.getDeptIds(user), authorities);
|
||||
// 添加缓存数据
|
||||
userCacheManager.addAppUserCache(username, jwtUserDto);
|
||||
}
|
||||
}
|
||||
return jwtUserDto;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -32,8 +32,8 @@ public class AuthUserDto {
|
||||
@ApiModelProperty(value = "用户名")
|
||||
private String username;
|
||||
|
||||
@ApiModelProperty(value = "手机号(APP登录)")
|
||||
private String phoneNumber;
|
||||
@ApiModelProperty(value = "手机号(APP/小程序 登录)")
|
||||
private Long phoneNumber;
|
||||
|
||||
@NotBlank
|
||||
@ApiModelProperty(value = "密码")
|
||||
|
||||
@ -16,12 +16,14 @@
|
||||
package com.fuyuanshen.modules.security.service.dto;
|
||||
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import com.fuyuanshen.modules.system.domain.app.APPUser;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import com.fuyuanshen.modules.system.domain.User;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
@ -33,6 +35,8 @@ import java.util.stream.Collectors;
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public class JwtUserDto implements UserDetails {
|
||||
@ApiModelProperty(value = "app用户")
|
||||
private final APPUser appUser;
|
||||
|
||||
@ApiModelProperty(value = "用户")
|
||||
private final User user;
|
||||
@ -50,12 +54,19 @@ public class JwtUserDto implements UserDetails {
|
||||
@Override
|
||||
@JSONField(serialize = false)
|
||||
public String getPassword() {
|
||||
if (appUser != null) {
|
||||
return appUser.getPassword();
|
||||
}
|
||||
|
||||
return user.getPassword();
|
||||
}
|
||||
|
||||
@Override
|
||||
@JSONField(serialize = false)
|
||||
public String getUsername() {
|
||||
if (appUser != null) {
|
||||
return appUser.getUsername();
|
||||
}
|
||||
return user.getUsername();
|
||||
}
|
||||
|
||||
@ -80,6 +91,9 @@ public class JwtUserDto implements UserDetails {
|
||||
@Override
|
||||
@JSONField(serialize = false)
|
||||
public boolean isEnabled() {
|
||||
if (appUser != null) {
|
||||
return appUser.getEnabled();
|
||||
}
|
||||
return user.getEnabled();
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@ import javax.validation.constraints.NotBlank;
|
||||
* @date 2025-06-18
|
||||
*/
|
||||
@Data
|
||||
public class AppAuthUserQuery {
|
||||
public class AppAuthUserDto {
|
||||
|
||||
@ApiModelProperty(value = "用户名")
|
||||
private String username;
|
||||
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2019-2025 Zheng Jie
|
||||
*
|
||||
* 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.fuyuanshen.modules.security.service.dto.app;
|
||||
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import com.fuyuanshen.modules.security.service.dto.AuthorityDto;
|
||||
import com.fuyuanshen.modules.system.domain.app.APPUser;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author Zheng Jie
|
||||
* @date 2018-11-23
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public class AppJwtUserDto implements UserDetails {
|
||||
|
||||
@ApiModelProperty(value = "用户")
|
||||
private final APPUser appUser;
|
||||
|
||||
@ApiModelProperty(value = "数据权限")
|
||||
private final List<Long> dataScopes;
|
||||
|
||||
@ApiModelProperty(value = "角色")
|
||||
private final List<AuthorityDto> authorities;
|
||||
|
||||
public Set<String> getRoles() {
|
||||
return authorities.stream().map(AuthorityDto::getAuthority).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
@JSONField(serialize = false)
|
||||
public String getPassword() {
|
||||
return appUser.getPassword();
|
||||
}
|
||||
|
||||
@Override
|
||||
@JSONField(serialize = false)
|
||||
public String getUsername() {
|
||||
return appUser.getUsername();
|
||||
}
|
||||
|
||||
@JSONField(serialize = false)
|
||||
@Override
|
||||
public boolean isAccountNonExpired() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@JSONField(serialize = false)
|
||||
@Override
|
||||
public boolean isAccountNonLocked() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@JSONField(serialize = false)
|
||||
@Override
|
||||
public boolean isCredentialsNonExpired() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@JSONField(serialize = false)
|
||||
public boolean isEnabled() {
|
||||
return appUser.getEnabled();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
package com.fuyuanshen.modules.security.service.dto.app;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class AppSecurityQuery {
|
||||
private String username;
|
||||
private String usertype;
|
||||
}
|
||||
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2019-2025 Zheng Jie
|
||||
*
|
||||
* 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.fuyuanshen.modules.security.service.dto.app;
|
||||
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import com.fuyuanshen.modules.security.config.LoginProperties;
|
||||
import com.fuyuanshen.modules.security.service.dto.JwtUserDto;
|
||||
import com.fuyuanshen.utils.RedisUtils;
|
||||
import com.fuyuanshen.utils.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* @author Zheng Jie
|
||||
* @description 用户缓存管理
|
||||
* @date 2022-05-26
|
||||
**/
|
||||
@Component
|
||||
public class AppUserCacheManager {
|
||||
|
||||
@Resource
|
||||
private RedisUtils redisUtils;
|
||||
@Value("${login.user-cache.idle-time}")
|
||||
private long idleTime;
|
||||
|
||||
/**
|
||||
* 返回用户缓存
|
||||
* @param userName 用户名
|
||||
* @return JwtUserDto
|
||||
*/
|
||||
public JwtUserDto getUserCache(String userName) {
|
||||
// 转小写
|
||||
userName = StringUtils.lowerCase(userName);
|
||||
if (StringUtils.isNotEmpty(userName)) {
|
||||
// 获取数据
|
||||
return redisUtils.get(LoginProperties.cacheKey_app + userName, JwtUserDto.class);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加缓存到Redis
|
||||
* @param userName 用户名
|
||||
*/
|
||||
@Async
|
||||
public void addUserCache(String userName, JwtUserDto user) {
|
||||
// 转小写
|
||||
userName = StringUtils.lowerCase(userName);
|
||||
if (StringUtils.isNotEmpty(userName)) {
|
||||
// 添加数据, 避免数据同时过期
|
||||
long time = idleTime + RandomUtil.randomInt(900, 1800);
|
||||
redisUtils.set(LoginProperties.cacheKey_app + userName, user, time);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理用户缓存信息
|
||||
* 用户信息变更时
|
||||
* @param userName 用户名
|
||||
*/
|
||||
@Async
|
||||
public void cleanUserCache(String userName) {
|
||||
// 转小写
|
||||
userName = StringUtils.lowerCase(userName);
|
||||
if (StringUtils.isNotEmpty(userName)) {
|
||||
// 清除数据
|
||||
redisUtils.del(LoginProperties.cacheKey_app + userName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package com.fuyuanshen.modules.system.constant;
|
||||
|
||||
/**
|
||||
* 响应消息常量类
|
||||
*
|
||||
* @author: 默苍璃
|
||||
* @date: 2025-06-2117:21
|
||||
*/
|
||||
public class ResponseMessageConstants {
|
||||
|
||||
/**
|
||||
* 删除操作成功提示
|
||||
*/
|
||||
public static final String DELETE_SUCCESS = "删除成功!";
|
||||
|
||||
/**
|
||||
* 新增操作成功提示
|
||||
*/
|
||||
public static final String SAVE_SUCCESS = "新增成功!";
|
||||
|
||||
/**
|
||||
* 更新操作成功提示
|
||||
*/
|
||||
public static final String UPDATE_SUCCESS = "更新成功!";
|
||||
|
||||
// 可根据业务需求继续扩展其他常用提示信息
|
||||
|
||||
}
|
||||
@ -10,6 +10,7 @@ import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import com.fuyuanshen.base.BaseEntity;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
@ -25,12 +26,33 @@ public class Device extends BaseEntity implements Serializable {
|
||||
@ApiModelProperty(value = "ID")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "设备记录ID")
|
||||
@TableField(exist = false)
|
||||
private Long assignId;
|
||||
|
||||
@ApiModelProperty(value = "设备类型")
|
||||
private Long deviceType;
|
||||
|
||||
@ApiModelProperty(value = "设备类型名称")
|
||||
private String typeName;
|
||||
|
||||
@ApiModelProperty(value = "客户号")
|
||||
private Long customerId;
|
||||
|
||||
/**
|
||||
* 当前所有者
|
||||
* current_owner_id
|
||||
*/
|
||||
@ApiModelProperty(value = "当前所有者")
|
||||
private Long currentOwnerId;
|
||||
|
||||
/**
|
||||
* 原始所有者(创建者)
|
||||
* original_owner_id
|
||||
*/
|
||||
@ApiModelProperty(value = "原始所有者(创建者)")
|
||||
private Long originalOwnerId;
|
||||
|
||||
@ApiModelProperty(value = "所属客户")
|
||||
private String customerName;
|
||||
|
||||
@ -46,6 +68,9 @@ public class Device extends BaseEntity implements Serializable {
|
||||
@ApiModelProperty(value = "设备MAC")
|
||||
private String deviceMac;
|
||||
|
||||
@ApiModelProperty(value = "设备IMEI")
|
||||
private String deviceImei;
|
||||
|
||||
@ApiModelProperty(value = "设备SN")
|
||||
private String deviceSn;
|
||||
|
||||
@ -58,10 +83,6 @@ public class Device extends BaseEntity implements Serializable {
|
||||
@ApiModelProperty(value = "备注")
|
||||
private String remark;
|
||||
|
||||
@TableField(exist = false)
|
||||
@ApiModelProperty(value = "设备类型名称")
|
||||
private String typeName;
|
||||
|
||||
/**
|
||||
* 租户ID
|
||||
*/
|
||||
|
||||
@ -0,0 +1,86 @@
|
||||
package com.fuyuanshen.modules.system.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 设备分配记录表
|
||||
*
|
||||
* @TableName device_assignments
|
||||
*/
|
||||
@TableName(value = "device_assignments")
|
||||
@Data
|
||||
public class DeviceAssignments {
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 设备id
|
||||
*/
|
||||
private Long deviceId;
|
||||
|
||||
/**
|
||||
* 分配方
|
||||
*/
|
||||
private Long fromCustomerId;
|
||||
|
||||
/**
|
||||
* 接收方
|
||||
*/
|
||||
private Long toCustomerId;
|
||||
|
||||
/**
|
||||
* 分配者
|
||||
* assigner_name
|
||||
*/
|
||||
private Long assignerId;
|
||||
private String assignerName;
|
||||
|
||||
/**
|
||||
* 接收者
|
||||
* assignee_name
|
||||
*/
|
||||
private Long assigneeId;
|
||||
private String assigneeName;
|
||||
|
||||
/**
|
||||
* 分配时间
|
||||
*/
|
||||
private LocalDateTime assignedAt;
|
||||
|
||||
/**
|
||||
* 0 未授权
|
||||
* 1 已授权
|
||||
* 是否同步授权了设备类型
|
||||
*/
|
||||
private Integer deviceTypeGranted;
|
||||
|
||||
/**
|
||||
* 0 否
|
||||
* 1 是
|
||||
* 是否直接分配(用于父级显示)
|
||||
*/
|
||||
private Integer direct;
|
||||
|
||||
/**
|
||||
* 0 否
|
||||
* 1 是
|
||||
* 设备是否有效
|
||||
*/
|
||||
private Integer active;
|
||||
|
||||
/**
|
||||
* 分配等级(用于失效)
|
||||
*/
|
||||
private String lever;
|
||||
|
||||
}
|
||||
@ -28,9 +28,12 @@ public class DeviceType extends BaseEntity implements Serializable {
|
||||
@ApiModelProperty(value = "ID", hidden = true)
|
||||
private Long id;
|
||||
|
||||
@ExcelProperty("客户号")
|
||||
@ApiModelProperty(value = "客户号")
|
||||
private Long customerId;
|
||||
|
||||
@ApiModelProperty(value = "创建该类型的客户")
|
||||
private Long ownerCustomerId;
|
||||
|
||||
/**
|
||||
* 租户ID
|
||||
*/
|
||||
@ -54,6 +57,7 @@ public class DeviceType extends BaseEntity implements Serializable {
|
||||
@ApiModelProperty(value = "通讯方式", example = "0:4G;1:蓝牙")
|
||||
private String communicationMode;
|
||||
|
||||
|
||||
public void copy(DeviceType source) {
|
||||
BeanUtil.copyProperties(source, this, CopyOptions.create().setIgnoreNullValue(true));
|
||||
}
|
||||
|
||||
@ -0,0 +1,95 @@
|
||||
package com.fuyuanshen.modules.system.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fuyuanshen.base.BaseEntity;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 设备分配权限表 (解决跨客户共享)
|
||||
*
|
||||
* @TableName device_type_grants
|
||||
*/
|
||||
@TableName(value = "device_type_grants")
|
||||
@Data
|
||||
public class DeviceTypeGrants {
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 设备类型
|
||||
*/
|
||||
private Long deviceTypeId;
|
||||
|
||||
/**
|
||||
* 被授权的客户
|
||||
*/
|
||||
private Long customerId;
|
||||
|
||||
/**
|
||||
* 授权方客户
|
||||
*/
|
||||
private Long grantorCustomerId;
|
||||
|
||||
/**
|
||||
* 生成日期
|
||||
*/
|
||||
private Date grantedAt;
|
||||
|
||||
/**
|
||||
* 关联分配记录
|
||||
*/
|
||||
private Long assignmentId;
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object that) {
|
||||
if (this == that) {
|
||||
return true;
|
||||
}
|
||||
if (that == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != that.getClass()) {
|
||||
return false;
|
||||
}
|
||||
DeviceTypeGrants other = (DeviceTypeGrants) that;
|
||||
return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId())) && (this.getDeviceTypeId() == null ? other.getDeviceTypeId() == null : this.getDeviceTypeId().equals(other.getDeviceTypeId())) && (this.getCustomerId() == null ? other.getCustomerId() == null : this.getCustomerId().equals(other.getCustomerId())) && (this.getGrantorCustomerId() == null ? other.getGrantorCustomerId() == null : this.getGrantorCustomerId().equals(other.getGrantorCustomerId())) && (this.getGrantedAt() == null ? other.getGrantedAt() == null : this.getGrantedAt().equals(other.getGrantedAt())) && (this.getAssignmentId() == null ? other.getAssignmentId() == null : this.getAssignmentId().equals(other.getAssignmentId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
|
||||
result = prime * result + ((getDeviceTypeId() == null) ? 0 : getDeviceTypeId().hashCode());
|
||||
result = prime * result + ((getCustomerId() == null) ? 0 : getCustomerId().hashCode());
|
||||
result = prime * result + ((getGrantorCustomerId() == null) ? 0 : getGrantorCustomerId().hashCode());
|
||||
result = prime * result + ((getGrantedAt() == null) ? 0 : getGrantedAt().hashCode());
|
||||
result = prime * result + ((getAssignmentId() == null) ? 0 : getAssignmentId().hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(getClass().getSimpleName());
|
||||
sb.append(" [");
|
||||
sb.append("Hash = ").append(hashCode());
|
||||
sb.append(", id=").append(id);
|
||||
sb.append(", deviceTypeId=").append(deviceTypeId);
|
||||
sb.append(", customerId=").append(customerId);
|
||||
sb.append(", grantorCustomerId=").append(grantorCustomerId);
|
||||
sb.append(", grantedAt=").append(grantedAt);
|
||||
sb.append(", assignmentId=").append(assignmentId);
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@ -26,7 +26,6 @@ public class APPDevice extends BaseEntity implements Serializable {
|
||||
@ApiModelProperty(value = "ID")
|
||||
private Long id;
|
||||
|
||||
|
||||
@ApiModelProperty(value = "设备类型")
|
||||
private Long deviceType;
|
||||
|
||||
@ -51,6 +50,9 @@ public class APPDevice extends BaseEntity implements Serializable {
|
||||
@ApiModelProperty(value = "设备MAC")
|
||||
private String deviceMac;
|
||||
|
||||
@ApiModelProperty(value = "设备IMEI")
|
||||
private String deviceImei;
|
||||
|
||||
@ApiModelProperty(value = "设备SN")
|
||||
private String deviceSn;
|
||||
|
||||
@ -90,6 +92,14 @@ public class APPDevice extends BaseEntity implements Serializable {
|
||||
@ApiModelProperty(value = "绑定状态")
|
||||
private Integer bindingStatus;
|
||||
|
||||
/**
|
||||
* 绑定类型
|
||||
* 0 APP
|
||||
* 1 小程序
|
||||
*/
|
||||
@ApiModelProperty(value = "绑定类型")
|
||||
private Integer bindingType;
|
||||
|
||||
|
||||
public void copy(Device source) {
|
||||
BeanUtil.copyProperties(source, this, CopyOptions.create().setIgnoreNullValue(true));
|
||||
|
||||
@ -3,10 +3,13 @@ package com.fuyuanshen.modules.system.domain.app;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fuyuanshen.modules.system.domain.DeviceType;
|
||||
import com.fuyuanshen.base.BaseEntity;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @Description: 设备类型
|
||||
* @Author: WY
|
||||
@ -14,11 +17,40 @@ import lombok.Data;
|
||||
**/
|
||||
@Data
|
||||
@TableName("app_device_type")
|
||||
public class APPDeviceType extends DeviceType {
|
||||
public class APPDeviceType extends BaseEntity implements Serializable {
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
@ApiModelProperty(value = "ID", hidden = true)
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "客户号")
|
||||
private Long customerId;
|
||||
|
||||
@ApiModelProperty(value = "创建该类型的客户")
|
||||
private Long ownerCustomerId;
|
||||
|
||||
/**
|
||||
* 租户ID
|
||||
*/
|
||||
// @TableField(value = "tenant_id")
|
||||
// @ApiModelProperty(hidden = true)
|
||||
// private Long tenantId;
|
||||
|
||||
@NotBlank(message = "设备类型名称不能为空")
|
||||
@ApiModelProperty(value = "类型名称", required = true)
|
||||
private String typeName;
|
||||
|
||||
@ApiModelProperty(value = "是否支持蓝牙")
|
||||
private Boolean isSupportBle;
|
||||
|
||||
@ApiModelProperty(value = "定位方式", example = "0:无;1:GPS;2:基站;3:wifi;4:北斗")
|
||||
private String locateMode;
|
||||
|
||||
@ApiModelProperty(value = "联网方式", example = "0:无;1:4G;2:WIFI")
|
||||
private String networkWay;
|
||||
|
||||
@ApiModelProperty(value = "通讯方式", example = "0:4G;1:蓝牙")
|
||||
private String communicationMode;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -16,14 +16,19 @@
|
||||
package com.fuyuanshen.modules.system.domain.app;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fuyuanshen.modules.system.domain.Role;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import com.fuyuanshen.base.BaseEntity;
|
||||
import com.fuyuanshen.utils.enums.DataScopeEnum;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 角色
|
||||
@ -32,12 +37,49 @@ import javax.validation.constraints.NotNull;
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@TableName("app_sys_role")
|
||||
public class APPRole extends Role {
|
||||
@TableName("sys_role")
|
||||
public class APPRole extends BaseEntity implements Serializable {
|
||||
|
||||
@NotNull(groups = {Update.class})
|
||||
@TableId(value="app_role_id", type = IdType.AUTO)
|
||||
@TableId(value="role_id", type = IdType.AUTO)
|
||||
@ApiModelProperty(value = "ID", hidden = true)
|
||||
private Long id;
|
||||
|
||||
@TableField(exist = false)
|
||||
@ApiModelProperty(value = "用户", hidden = true)
|
||||
private Set<APPUser> users;
|
||||
|
||||
@TableField(exist = false)
|
||||
@ApiModelProperty(value = "菜单", hidden = true)
|
||||
private Set<APPMenu> menus;
|
||||
|
||||
@NotBlank
|
||||
@ApiModelProperty(value = "名称", hidden = true)
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "数据权限,全部 、 本级 、 自定义")
|
||||
private String dataScope = DataScopeEnum.THIS_LEVEL.getValue();
|
||||
|
||||
@ApiModelProperty(value = "级别,数值越小,级别越大")
|
||||
private Integer level = 3;
|
||||
|
||||
@ApiModelProperty(value = "描述")
|
||||
private String description;
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
APPRole role = (APPRole) o;
|
||||
return Objects.equals(id, role.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,6 +25,7 @@ import com.fuyuanshen.modules.system.domain.Job;
|
||||
import com.fuyuanshen.modules.system.domain.Role;
|
||||
import com.fuyuanshen.modules.system.domain.User;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@ -39,8 +40,7 @@ import java.util.Set;
|
||||
* @author Zheng Jie
|
||||
* @date 2018-11-22
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Data
|
||||
@TableName("app_user")
|
||||
public class APPUser extends BaseEntity implements Serializable {
|
||||
|
||||
@ -53,6 +53,10 @@ public class APPUser extends BaseEntity implements Serializable {
|
||||
@ApiModelProperty(hidden = true)
|
||||
private Long deptId;
|
||||
|
||||
@TableField(exist = false)
|
||||
@ApiModelProperty(value = "用户角色")
|
||||
private Set<Role> roles;
|
||||
|
||||
@ApiModelProperty(hidden = true)
|
||||
private Long pid;
|
||||
|
||||
@ -104,7 +108,7 @@ public class APPUser extends BaseEntity implements Serializable {
|
||||
*/
|
||||
@ApiModelProperty(value = "是否为admin账号", hidden = true)
|
||||
@TableField(value = "is_admin")
|
||||
private Byte admin;
|
||||
private Byte admin = 0;
|
||||
|
||||
@TableField(exist = false)
|
||||
private Boolean isAdmin = false;
|
||||
@ -129,4 +133,8 @@ public class APPUser extends BaseEntity implements Serializable {
|
||||
@ApiModelProperty(hidden = true)
|
||||
private Integer userType;
|
||||
|
||||
/**
|
||||
* 地区
|
||||
*/
|
||||
private String region;
|
||||
}
|
||||
@ -2,7 +2,9 @@ package com.fuyuanshen.modules.system.domain.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -11,12 +13,15 @@ import java.util.List;
|
||||
* @Date: 2025/5/28
|
||||
**/
|
||||
@Data
|
||||
@Validated
|
||||
public class CustomerVo {
|
||||
|
||||
@ApiModelProperty(value = "客户ID")
|
||||
@NotNull(message = "客户ID不能为空")
|
||||
private Long customerId;
|
||||
|
||||
@ApiModelProperty(value = "设备ID")
|
||||
@NotNull(message = "设备ID不能为空")
|
||||
private List<Long> deviceIds;
|
||||
|
||||
}
|
||||
|
||||
@ -46,9 +46,9 @@ public class DeviceExcelExportDTO {
|
||||
@ColumnWidth(20)
|
||||
private String deviceMac;
|
||||
|
||||
@ExcelProperty("设备SN")
|
||||
@ExcelProperty("设备IMEI")
|
||||
@ColumnWidth(20)
|
||||
private String deviceSn;
|
||||
private String deviceImei;
|
||||
|
||||
@ExcelProperty("经度")
|
||||
private String longitude;
|
||||
|
||||
@ -5,6 +5,7 @@ import com.alibaba.excel.annotation.write.style.ColumnWidth;
|
||||
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
|
||||
import com.alibaba.excel.annotation.write.style.HeadRowHeight;
|
||||
import com.alibaba.excel.converters.bytearray.ByteArrayImageConverter;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import com.fuyuanshen.modules.system.converter.IgnoreFailedImageConverter;
|
||||
|
||||
@ -43,6 +44,11 @@ public class DeviceExcelImportDTO {
|
||||
@ColumnWidth(20)
|
||||
private String deviceMac;
|
||||
|
||||
@ExcelProperty("设备IMEI")
|
||||
@ColumnWidth(20)
|
||||
@ApiModelProperty(value = "设备IMEI")
|
||||
private String deviceImei;
|
||||
|
||||
@ExcelProperty("设备SN")
|
||||
@ColumnWidth(20)
|
||||
private String deviceSn;
|
||||
|
||||
@ -33,11 +33,14 @@ public class DeviceForm {
|
||||
@ApiModelProperty(value = "设备图片存储路径", hidden = true)
|
||||
private String devicePic;
|
||||
|
||||
@NotBlank(message = "设备MAC不能为空")
|
||||
@ApiModelProperty(value = "设备MAC", required = true)
|
||||
// @NotBlank(message = "设备MAC不能为空")
|
||||
@ApiModelProperty(value = "设备MAC")
|
||||
private String deviceMac;
|
||||
|
||||
@NotBlank(message = "设备SN不能为空")
|
||||
@ApiModelProperty(value = "设备IMEI")
|
||||
private String deviceImei;
|
||||
|
||||
// @NotBlank(message = "设备SN不能为空")
|
||||
@ApiModelProperty(value = "设备SN", required = true)
|
||||
private String deviceSn;
|
||||
|
||||
|
||||
@ -25,6 +25,9 @@ public class DeviceQueryCriteria {
|
||||
@ApiModelProperty(value = "设备MAC")
|
||||
private String deviceMac;
|
||||
|
||||
@ApiModelProperty(value = "设备IMEI")
|
||||
private String deviceImei;
|
||||
|
||||
@ApiModelProperty(value = "设备SN")
|
||||
private String deviceSn;
|
||||
|
||||
@ -49,7 +52,13 @@ public class DeviceQueryCriteria {
|
||||
private Long customerId;
|
||||
private Set<Long> customerIds;
|
||||
|
||||
@ApiModelProperty(value = "当前所有者")
|
||||
private Long currentOwnerId;
|
||||
|
||||
@ApiModelProperty(value = "租户ID")
|
||||
private Long tenantId;
|
||||
|
||||
@ApiModelProperty(value = "通讯方式", example = "0:4G;1:蓝牙")
|
||||
private Integer communicationMode;
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
package com.fuyuanshen.modules.system.domain.dto.app;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* @author: 默苍璃
|
||||
* @date: 2025-06-1818:36
|
||||
*/
|
||||
@Data
|
||||
public class APPForgotPasswordDTO {
|
||||
|
||||
@NotBlank(message = "手机号不能为空")
|
||||
@ApiModelProperty(value = "手机号(APP登录)")
|
||||
private String phoneNumber;
|
||||
|
||||
|
||||
@NotBlank(message = "密码不能为空")
|
||||
@ApiModelProperty(value = "密码")
|
||||
private String password;
|
||||
|
||||
@ApiModelProperty(value = "验证码")
|
||||
@NotBlank(message = "验证码不能为空")
|
||||
private String verificationCode;
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
package com.fuyuanshen.modules.system.domain.dto.app;
|
||||
|
||||
import com.fuyuanshen.modules.system.domain.app.APPUser;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* @author: 默苍璃
|
||||
* @date: 2025-06-1818:36
|
||||
*/
|
||||
@Data
|
||||
public class APPUpdateUserDTO {
|
||||
|
||||
|
||||
@ApiModelProperty(value = "ID", hidden = true)
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "用户昵称")
|
||||
private String nickName;
|
||||
|
||||
@ApiModelProperty(value = "地区")
|
||||
private String region;
|
||||
|
||||
@ApiModelProperty(value = "用户性别")
|
||||
private String gender;
|
||||
|
||||
@ApiModelProperty(value = "头像图片")
|
||||
private MultipartFile file;
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
package com.fuyuanshen.modules.system.domain.dto.app;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* @author: 默苍璃
|
||||
* @date: 2025-06-1818:36
|
||||
*/
|
||||
@Data
|
||||
public class APPUserDTO {
|
||||
|
||||
|
||||
@ApiModelProperty(value = "用户名")
|
||||
private String username;
|
||||
|
||||
@NotBlank(message = "手机号不能为空")
|
||||
@ApiModelProperty(value = "手机号(APP登录)")
|
||||
private String phoneNumber;
|
||||
|
||||
@NotBlank(message = "密码不能为空")
|
||||
@ApiModelProperty(value = "密码")
|
||||
private String password;
|
||||
|
||||
@ApiModelProperty(value = "验证码")
|
||||
private String verificationCode;
|
||||
|
||||
/*@ApiModelProperty(value = "验证码")
|
||||
private String code;
|
||||
|
||||
@ApiModelProperty(value = "验证码的key")
|
||||
private String uuid = "";*/
|
||||
|
||||
}
|
||||
@ -1,21 +1,17 @@
|
||||
package com.fuyuanshen.modules.system.domain.query;
|
||||
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author: 默苍璃
|
||||
* @date: 2025-06-1213:49
|
||||
*/
|
||||
@Data
|
||||
public class APPUserDto implements Serializable {
|
||||
public class APPUserQuery implements Serializable {
|
||||
|
||||
@ApiModelProperty(value = "ID", hidden = true)
|
||||
private Long id;
|
||||
@ -0,0 +1,40 @@
|
||||
package com.fuyuanshen.modules.system.domain.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author: 默苍璃
|
||||
* @date: 2025-06-1211:34
|
||||
*/
|
||||
@Data
|
||||
@JsonInclude(JsonInclude.Include.ALWAYS)
|
||||
public class APPUserVo {
|
||||
|
||||
@ApiModelProperty(value = "ID")
|
||||
@JsonProperty("id")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "用户昵称")
|
||||
@JsonProperty("nickName")
|
||||
private String nickName;
|
||||
|
||||
@ApiModelProperty(value = "用户性别")
|
||||
@JsonProperty("gender")
|
||||
private String gender;
|
||||
|
||||
@ApiModelProperty(value = "电话号码")
|
||||
@JsonProperty("phone")
|
||||
private Long phone;
|
||||
|
||||
@ApiModelProperty(value = "头像存储的路径")
|
||||
@JsonProperty("avatarPath")
|
||||
private String avatarPath;
|
||||
|
||||
@ApiModelProperty(value = "地区")
|
||||
@JsonProperty("region")
|
||||
private String region;
|
||||
|
||||
}
|
||||
@ -0,0 +1,45 @@
|
||||
package com.fuyuanshen.modules.system.enums;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
|
||||
/**
|
||||
* 通讯方式枚举
|
||||
*
|
||||
* @author: 默苍璃
|
||||
* @date: 2025-06-2414:11
|
||||
*/
|
||||
public enum CommunicationModeEnum {
|
||||
|
||||
FOUR_G(0, "4G"),
|
||||
BLUETOOTH(1, "蓝牙");
|
||||
|
||||
private final int value;
|
||||
private final String label;
|
||||
|
||||
CommunicationModeEnum(int value, String label) {
|
||||
this.value = value;
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
@JsonValue
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据值获取标签
|
||||
*/
|
||||
public static String getLabelByValue(int value) {
|
||||
for (CommunicationModeEnum mode : values()) {
|
||||
if (mode.getValue() == value) {
|
||||
return mode.getLabel();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
package com.fuyuanshen.modules.system.enums;
|
||||
|
||||
/**
|
||||
* 设备有效性状态枚举
|
||||
*
|
||||
* @author: 默苍璃
|
||||
* @date: 2025-06-2113:26
|
||||
*/
|
||||
public enum DeviceActiveStatusEnum {
|
||||
|
||||
INACTIVE(0, "无效"), ACTIVE(1, "有效");
|
||||
|
||||
private final Integer code;
|
||||
private final String description;
|
||||
|
||||
DeviceActiveStatusEnum(Integer code, String description) {
|
||||
this.code = code;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 code 获取描述
|
||||
*
|
||||
* @param code 状态码
|
||||
* @return 描述信息
|
||||
*/
|
||||
public static String getDescriptionByCode(Integer code) {
|
||||
for (DeviceActiveStatusEnum status : values()) {
|
||||
if (status.getCode().equals(code)) {
|
||||
return status.getDescription();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
package com.fuyuanshen.modules.system.enums;
|
||||
|
||||
/**
|
||||
* @author: 默苍璃
|
||||
* @date: 2025-06-1918:50
|
||||
*/
|
||||
public enum DeviceAuthorizationStatus {
|
||||
/**
|
||||
* 未授权
|
||||
*/
|
||||
UNAUTHORIZED(0),
|
||||
|
||||
/**
|
||||
* 已授权
|
||||
*/
|
||||
AUTHORIZED(1);
|
||||
|
||||
private final int value;
|
||||
|
||||
DeviceAuthorizationStatus(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据整数值获取对应的枚举值
|
||||
*
|
||||
* @param value 整数值(0 或 1)
|
||||
* @return 对应的 DeviceAuthorizationStatus 枚举
|
||||
* @throws IllegalArgumentException 如果值不是 0 或 1
|
||||
*/
|
||||
public static DeviceAuthorizationStatus fromValue(int value) {
|
||||
for (DeviceAuthorizationStatus status : values()) {
|
||||
if (status.getValue() == value) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Invalid device authorization status value: " + value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,51 @@
|
||||
package com.fuyuanshen.modules.system.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 设备状态枚举
|
||||
*
|
||||
* @author: 默苍璃
|
||||
* @date: 2025-06-1916:02
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum DeviceStatusEnum {
|
||||
|
||||
/**
|
||||
* 失效
|
||||
*/
|
||||
INVALID(0, "失效"),
|
||||
|
||||
/**
|
||||
* 正常
|
||||
*/
|
||||
NORMAL(1, "正常");
|
||||
|
||||
/**
|
||||
* 状态码
|
||||
*/
|
||||
private final Integer code;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
private final String description;
|
||||
|
||||
/**
|
||||
* 根据状态码获取描述
|
||||
*
|
||||
* @param code 状态码
|
||||
* @return 描述
|
||||
*/
|
||||
public static String getDescriptionByCode(Integer code) {
|
||||
for (DeviceStatusEnum status : DeviceStatusEnum.values()) {
|
||||
if (status.getCode().equals(code)) {
|
||||
return status.getDescription();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@ -3,6 +3,7 @@ package com.fuyuanshen.modules.system.listener.excel;
|
||||
import com.fuyuanshen.modules.system.mapper.DeviceMapper;
|
||||
import com.fuyuanshen.modules.system.mapper.DeviceTypeMapper;
|
||||
import com.fuyuanshen.modules.system.mapper.UserMapper;
|
||||
import com.fuyuanshen.modules.system.service.DeviceAssignmentsService;
|
||||
import com.fuyuanshen.modules.system.service.DeviceService;
|
||||
import lombok.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
@ -19,6 +20,7 @@ import org.springframework.web.multipart.MultipartFile;
|
||||
public class DeviceImportParams {
|
||||
|
||||
private DeviceService deviceService;
|
||||
private DeviceAssignmentsService deviceAssignmentsService;
|
||||
private DeviceMapper deviceMapper;
|
||||
private UserMapper userMapper;
|
||||
private DeviceTypeMapper deviceTypeMapper;
|
||||
|
||||
@ -7,9 +7,13 @@ import com.alibaba.excel.context.AnalysisContext;
|
||||
import com.alibaba.excel.read.listener.ReadListener;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.fuyuanshen.modules.system.domain.DeviceAssignments;
|
||||
import com.fuyuanshen.modules.system.domain.DeviceType;
|
||||
import com.fuyuanshen.modules.system.domain.User;
|
||||
import com.fuyuanshen.modules.system.domain.dto.DeviceQueryCriteria;
|
||||
import com.fuyuanshen.modules.system.enums.DeviceActiveStatusEnum;
|
||||
import com.fuyuanshen.modules.system.mapper.UserMapper;
|
||||
import com.fuyuanshen.utils.SecurityUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import com.fuyuanshen.constants.DeviceConstants;
|
||||
import com.fuyuanshen.modules.system.domain.Device;
|
||||
@ -24,6 +28,7 @@ import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@ -149,6 +154,7 @@ public class UploadDeviceDataListener implements ReadListener<DeviceExcelImportD
|
||||
|
||||
|
||||
private void processDataRowByRow() {
|
||||
User currentUser = params.getUserMapper().findByUsername(SecurityUtils.getCurrentUsername());
|
||||
for (Integer rowIndex : rowIndexList) {
|
||||
Device device = rowDeviceMap.get(rowIndex);
|
||||
DeviceExcelImportDTO originalDto = rowDtoMap.get(rowIndex);
|
||||
@ -171,6 +177,20 @@ public class UploadDeviceDataListener implements ReadListener<DeviceExcelImportD
|
||||
device.setDeviceType(deviceTypes.get(0).getId());
|
||||
}
|
||||
params.getDeviceService().save(device);
|
||||
|
||||
// 新增设备类型记录
|
||||
DeviceAssignments assignments = new DeviceAssignments();
|
||||
assignments.setDeviceId(device.getId());
|
||||
assignments.setAssignedAt(LocalDateTime.now());
|
||||
// 分配者
|
||||
assignments.setAssignerId(currentUser.getId());
|
||||
// 接收者
|
||||
assignments.setAssigneeId(currentUser.getId());
|
||||
assignments.setActive(DeviceActiveStatusEnum.ACTIVE.getCode());
|
||||
String lever = currentUser.getId() + ":";
|
||||
assignments.setLever(lever);
|
||||
params.getDeviceAssignmentsService().save(assignments);
|
||||
|
||||
successCount++;
|
||||
log.info("行 {} 数据插入成功", rowIndex);
|
||||
} catch (Exception e) {
|
||||
|
||||
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2019-2025 Zheng Jie
|
||||
*
|
||||
* 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.fuyuanshen.modules.system.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.fuyuanshen.modules.system.domain.Role;
|
||||
import com.fuyuanshen.modules.system.domain.app.APPRole;
|
||||
import com.fuyuanshen.modules.system.domain.dto.RoleQueryCriteria;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Zheng Jie
|
||||
* @date 2023-06-20
|
||||
*/
|
||||
@Mapper
|
||||
public interface APPRoleMapper extends BaseMapper<APPRole> {
|
||||
|
||||
|
||||
List<APPRole> findByUserId(@Param("userId") Long userId);
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package com.fuyuanshen.modules.system.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.fuyuanshen.modules.system.domain.DeviceAssignments;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* @author 97433
|
||||
* @description 针对表【device_assignments】的数据库操作Mapper
|
||||
* @createDate 2025-06-19 18:19:13
|
||||
* @Entity system.domain.DeviceAssignments
|
||||
*/
|
||||
@Mapper
|
||||
public interface DeviceAssignmentsMapper extends BaseMapper<DeviceAssignments> {
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package com.fuyuanshen.modules.system.mapper;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.fuyuanshen.modules.system.domain.DeviceTypeGrants;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* @author 97433
|
||||
* @description 针对表【device_type_grants】的数据库操作Mapper
|
||||
* @createDate 2025-06-19 13:49:33
|
||||
* @Entity generator.domain.DeviceTypeGrants
|
||||
*/
|
||||
@Mapper
|
||||
public interface DeviceTypeGrantsMapper extends BaseMapper<DeviceTypeGrants> {
|
||||
|
||||
|
||||
}
|
||||
@ -19,6 +19,15 @@ import java.util.List;
|
||||
@Mapper
|
||||
public interface APPDeviceMapper extends BaseMapper<APPDevice> {
|
||||
|
||||
/**
|
||||
* APP用户设备列表
|
||||
*
|
||||
* @param page
|
||||
* @param criteria
|
||||
* @return
|
||||
*/
|
||||
IPage<APPDevice> appDeviceList(Page<APPDevice> page,@Param("criteria") DeviceQueryCriteria criteria);
|
||||
|
||||
|
||||
/**
|
||||
* 分页查询APP/小程序设备
|
||||
@ -27,6 +36,7 @@ public interface APPDeviceMapper extends BaseMapper<APPDevice> {
|
||||
* @param page
|
||||
* @return
|
||||
*/
|
||||
IPage<APPDevice> queryAll(Page<APPDevice> page, @Param("criteria")DeviceQueryCriteria criteria );
|
||||
IPage<APPDevice> queryAll(Page<APPDevice> page, @Param("criteria") DeviceQueryCriteria criteria);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -18,11 +18,15 @@ package com.fuyuanshen.modules.system.mapper.app;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.fuyuanshen.modules.security.service.dto.app.AppRoleDto;
|
||||
import com.fuyuanshen.modules.system.domain.User;
|
||||
import com.fuyuanshen.modules.system.domain.app.APPUser;
|
||||
import com.fuyuanshen.modules.system.domain.dto.UserQueryCriteria;
|
||||
import com.fuyuanshen.modules.system.domain.query.APPUserDto;
|
||||
import com.fuyuanshen.modules.system.domain.query.APPUserQuery;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* @author Zheng Jie
|
||||
@ -44,14 +48,25 @@ public interface APPUserMapper extends BaseMapper<APPUser> {
|
||||
/**
|
||||
* 根据条件查询一个用户
|
||||
*
|
||||
* @param appUserDTO
|
||||
* @param appUserQuery
|
||||
* @return
|
||||
*/
|
||||
APPUser selectByQueryOne(@Param("userQuery") APPUserDto appUserDTO);
|
||||
APPUser selectByQueryOne(@Param("appUserQuery") APPUserQuery appUserQuery);
|
||||
|
||||
AppRoleDto selectRoleByUserLevel(Byte userLevel);
|
||||
|
||||
boolean createAppUser(APPUserDto appUserDTO);
|
||||
APPUser findByUsername(@Param("username") String username);
|
||||
|
||||
void setUsername(String phoneNumber);
|
||||
|
||||
|
||||
|
||||
APPUser appFindByUsername(@Param("username") String username);
|
||||
|
||||
@Select("select * from app_user where username=#{username}")
|
||||
APPUserQuery getByUsername(@Param("username") String username);
|
||||
|
||||
@Select("select * from user where username=#{username} and password=#{password}")
|
||||
User getByUsernameAndPassword(@Param("username") String username, @Param("password") String password);
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
package com.fuyuanshen.modules.system.mapper.app;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.fuyuanshen.modules.system.domain.app.APPDeviceType;
|
||||
import com.fuyuanshen.modules.system.domain.dto.DeviceQueryCriteria;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author 97433
|
||||
* @description 针对表【app_device_type(设备类型表)】的数据库操作Mapper
|
||||
* @createDate 2025-06-24 11:16:18
|
||||
* @Entity system.domain.AppDeviceType
|
||||
*/
|
||||
@Mapper
|
||||
public interface AppDeviceTypeMapper extends BaseMapper<APPDeviceType> {
|
||||
|
||||
/**
|
||||
* 查询设备类型列表
|
||||
*
|
||||
* @param criteria 查询条件
|
||||
* @return 设备类型列表
|
||||
*/
|
||||
List<APPDeviceType> appTypeList(DeviceQueryCriteria criteria);
|
||||
|
||||
}
|
||||
@ -2,35 +2,35 @@ package com.fuyuanshen.modules.system.rest;
|
||||
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.fuyuanshen.annotation.Log;
|
||||
import com.fuyuanshen.exception.BadRequestException;
|
||||
import com.fuyuanshen.modules.system.constant.ResponseMessageConstants;
|
||||
import com.fuyuanshen.modules.system.constant.UserConstants;
|
||||
import com.fuyuanshen.modules.system.domain.Device;
|
||||
import com.fuyuanshen.modules.system.domain.User;
|
||||
import com.fuyuanshen.modules.system.domain.dto.CustomerVo;
|
||||
import com.fuyuanshen.modules.system.domain.dto.DeviceExcelImportDTO;
|
||||
import com.fuyuanshen.modules.system.domain.dto.DeviceForm;
|
||||
import com.fuyuanshen.modules.system.domain.dto.DeviceQueryCriteria;
|
||||
import com.fuyuanshen.modules.system.listener.excel.DeviceImportParams;
|
||||
import com.fuyuanshen.modules.system.listener.excel.UploadDeviceDataListener;
|
||||
import com.fuyuanshen.modules.system.mapper.DeviceMapper;
|
||||
import com.fuyuanshen.modules.system.mapper.DeviceTypeMapper;
|
||||
import com.fuyuanshen.modules.system.mapper.UserMapper;
|
||||
import com.fuyuanshen.modules.system.service.DeviceAssignmentsService;
|
||||
import com.fuyuanshen.modules.system.service.DeviceService;
|
||||
import com.fuyuanshen.modules.system.service.UserService;
|
||||
import com.fuyuanshen.modules.system.service.impl.app.APPUserServiceImpl;
|
||||
import com.fuyuanshen.modules.system.service.impl.DeviceExportService;
|
||||
import com.fuyuanshen.modules.utils.ResponseVO;
|
||||
import com.fuyuanshen.modules.utils.excel.ImportResult;
|
||||
import com.fuyuanshen.utils.FileUtil;
|
||||
import com.fuyuanshen.utils.PageResult;
|
||||
import com.fuyuanshen.utils.SecurityUtils;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import com.fuyuanshen.annotation.Log;
|
||||
import com.fuyuanshen.domain.LocalStorage;
|
||||
import com.fuyuanshen.exception.BadRequestException;
|
||||
import com.fuyuanshen.modules.system.domain.Device;
|
||||
import com.fuyuanshen.modules.system.domain.dto.CustomerVo;
|
||||
import com.fuyuanshen.modules.system.domain.dto.DeviceExcelImportDTO;
|
||||
import com.fuyuanshen.modules.system.domain.dto.DeviceForm;
|
||||
import com.fuyuanshen.modules.system.domain.dto.DeviceQueryCriteria;
|
||||
import com.fuyuanshen.modules.system.listener.excel.UploadDeviceDataListener;
|
||||
import com.fuyuanshen.modules.system.service.DeviceService;
|
||||
import com.fuyuanshen.modules.system.service.impl.DeviceExportService;
|
||||
import com.fuyuanshen.modules.utils.ResponseVO;
|
||||
import com.fuyuanshen.modules.utils.excel.ImportResult;
|
||||
import com.fuyuanshen.utils.FileUtil;
|
||||
import com.fuyuanshen.utils.PageResult;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
@ -50,7 +50,6 @@ import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Description:
|
||||
@ -65,6 +64,7 @@ import java.util.Map;
|
||||
public class DeviceController {
|
||||
|
||||
private final DeviceService deviceService;
|
||||
private final DeviceAssignmentsService deviceAssignmentsService;
|
||||
private final DeviceExportService exportService;
|
||||
private final UserMapper userMapper;
|
||||
private final DeviceMapper deviceMapper;
|
||||
@ -141,12 +141,7 @@ public class DeviceController {
|
||||
@ApiOperation("分配客户")
|
||||
@PutMapping(value = "/assignCustomer")
|
||||
public ResponseVO<Object> assignCustomer(@Validated @RequestBody CustomerVo customerVo) {
|
||||
try {
|
||||
deviceService.assignCustomer(customerVo);
|
||||
} catch (Exception e) {
|
||||
log.error("updateDevice error: " + e.getMessage());
|
||||
return ResponseVO.fail(e.getMessage());
|
||||
}
|
||||
deviceService.assignCustomer(customerVo);
|
||||
return ResponseVO.success(null);
|
||||
}
|
||||
|
||||
@ -163,13 +158,9 @@ public class DeviceController {
|
||||
@ApiOperation("删除设备")
|
||||
@DeleteMapping(value = "/delete")
|
||||
public ResponseVO<Object> deleteDevice(@ApiParam(value = "传ID数组[]") @RequestBody List<Long> ids) {
|
||||
try {
|
||||
deviceService.deleteAll(ids);
|
||||
} catch (Exception e) {
|
||||
log.error("deleteDevice error: " + e.getMessage());
|
||||
return ResponseVO.fail(e.getMessage());
|
||||
}
|
||||
return ResponseVO.success(null);
|
||||
// deviceService.deleteAll(ids);
|
||||
deviceService.deleteAssign(ids);
|
||||
return ResponseVO.success(ResponseMessageConstants.DELETE_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
@ -181,7 +172,8 @@ public class DeviceController {
|
||||
|
||||
// 只能看到自己的创建的设备,以及被分配的设备。
|
||||
if (onlineuser.getTenantId() != null && !onlineuser.getTenantId().equals(UserConstants.SUPER_ADMIN_ID)) {
|
||||
criteria.setTenantId(onlineuser.getTenantId());
|
||||
// criteria.setTenantId(onlineuser.getTenantId());
|
||||
criteria.setCurrentOwnerId(onlineuser.getId());
|
||||
}
|
||||
exportService.export(deviceService.queryAll(criteria), response);
|
||||
}
|
||||
@ -215,29 +207,21 @@ public class DeviceController {
|
||||
ImportResult result = new ImportResult();
|
||||
try {
|
||||
User currentUser = userMapper.findByUsername(SecurityUtils.getCurrentUsername());
|
||||
DeviceImportParams params = DeviceImportParams.builder().ip(ip).deviceService(deviceService).tenantId(currentUser.getTenantId()).file(file).filePath(filePath).deviceMapper(deviceMapper).deviceTypeMapper(deviceTypeMapper).userId(currentUser.getId()).build();
|
||||
|
||||
DeviceImportParams params = DeviceImportParams.builder().ip(ip).deviceService(deviceService).tenantId(currentUser.getTenantId()).file(file).filePath(filePath).deviceMapper(deviceMapper).deviceAssignmentsService(deviceAssignmentsService).deviceTypeMapper(deviceTypeMapper).userId(currentUser.getId()).userMapper(userMapper).build();
|
||||
// 创建监听器
|
||||
UploadDeviceDataListener listener = new UploadDeviceDataListener(params);
|
||||
|
||||
// 读取Excel
|
||||
EasyExcel.read(file.getInputStream(), DeviceExcelImportDTO.class, listener).sheet().doRead();
|
||||
|
||||
// 获取导入结果
|
||||
result = listener.getImportResult();
|
||||
|
||||
// 设置响应消息
|
||||
String message = String.format("成功导入 %d 条数据,失败 %d 条", result.getSuccessCount(), result.getFailureCount());
|
||||
|
||||
// 返回带有正确泛型的响应
|
||||
return ResponseVO.<ImportResult>success(message, result);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("导入设备数据出错: {}", e.getMessage(), e);
|
||||
|
||||
// 在异常情况下,设置默认结果
|
||||
String errorMessage = String.format("导入失败: %s。成功 %d 条,失败 %d 条", e.getMessage(), result.getSuccessCount(), result.getFailureCount());
|
||||
|
||||
// 使用新方法确保类型正确
|
||||
return ResponseVO.<ImportResult>fail(errorMessage, result);
|
||||
}
|
||||
@ -249,7 +233,6 @@ public class DeviceController {
|
||||
try {
|
||||
// 解码Base64字符串
|
||||
byte[] data = Base64.getDecoder().decode(errorData);
|
||||
|
||||
return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"import_errors.xlsx\"").contentType(MediaType.APPLICATION_OCTET_STREAM).body(data);
|
||||
} catch (Exception e) {
|
||||
log.error("下载错误报告失败", e);
|
||||
|
||||
@ -74,4 +74,12 @@ public class DeviceTypeController {
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
}
|
||||
|
||||
|
||||
@GetMapping(value = "/communicationMode")
|
||||
@ApiOperation("获取设备类型通讯方式")
|
||||
public ResponseVO<DeviceType> getCommunicationMode(@ApiParam(value = "设备类型ID", required = true) Long id) {
|
||||
return ResponseVO.success(deviceTypeService.getById(id));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -271,8 +271,8 @@ public class UserController {
|
||||
return ResponseVO.success(null);
|
||||
}
|
||||
|
||||
@Log("修改用户:个人中心")
|
||||
@ApiOperation("修改用户:个人中心")
|
||||
@Log("修改用户:")
|
||||
@ApiOperation("修改用户:")
|
||||
@PutMapping(value = "center")
|
||||
public ResponseVO<Object> centerUser(@Validated(User.Update.class) @RequestBody User resources) {
|
||||
if (!resources.getId().equals(SecurityUtils.getCurrentUserId())) {
|
||||
|
||||
@ -8,6 +8,7 @@ import com.fuyuanshen.modules.system.constant.UserConstants;
|
||||
import com.fuyuanshen.modules.system.domain.Device;
|
||||
import com.fuyuanshen.modules.system.domain.User;
|
||||
import com.fuyuanshen.modules.system.domain.app.APPDevice;
|
||||
import com.fuyuanshen.modules.system.domain.app.APPDeviceType;
|
||||
import com.fuyuanshen.modules.system.domain.dto.CustomerVo;
|
||||
import com.fuyuanshen.modules.system.domain.dto.DeviceExcelImportDTO;
|
||||
import com.fuyuanshen.modules.system.domain.dto.DeviceForm;
|
||||
@ -67,8 +68,39 @@ public class APPDeviceController {
|
||||
private final APPDeviceService appDeviceService;
|
||||
|
||||
|
||||
@PostMapping(value = "/list")
|
||||
@ApiOperation("APP用户设备列表")
|
||||
public ResponseVO<PageResult<APPDevice>> appDeviceList(@RequestBody DeviceQueryCriteria criteria) {
|
||||
Page<APPDevice> page = new Page<>(criteria.getPage(), criteria.getSize());
|
||||
PageResult<APPDevice> devices = null;
|
||||
try {
|
||||
devices = appDeviceService.appDeviceList(page, criteria);
|
||||
} catch (Exception e) {
|
||||
log.error("queryDevice error: " + e.getMessage());
|
||||
return ResponseVO.fail("");
|
||||
}
|
||||
return ResponseVO.success(devices);
|
||||
}
|
||||
|
||||
|
||||
@PostMapping(value = "/typeList")
|
||||
@ApiOperation("APP用户设备类型列表")
|
||||
public ResponseVO<List<APPDeviceType>> appTypeList(@RequestBody DeviceQueryCriteria criteria) {
|
||||
List<APPDeviceType> typeList = appDeviceService.appTypeList(criteria);
|
||||
return ResponseVO.success(typeList);
|
||||
}
|
||||
|
||||
|
||||
@PostMapping(value = "/bind")
|
||||
@ApiOperation("APP用户设备绑定")
|
||||
public ResponseVO<String> appBindDevice(@RequestBody DeviceQueryCriteria criteria) {
|
||||
appDeviceService.appBindDevice(criteria);
|
||||
return ResponseVO.success("绑定成功!");
|
||||
}
|
||||
|
||||
|
||||
@GetMapping
|
||||
@ApiOperation("查看APP用户设备绑定")
|
||||
@ApiOperation("WEB端查看APP用户设备绑定")
|
||||
public ResponseVO<PageResult<APPDevice>> queryAPPDevice(DeviceQueryCriteria criteria) {
|
||||
Page<APPDevice> page = new Page<>(criteria.getPage(), criteria.getSize());
|
||||
PageResult<APPDevice> devices = null;
|
||||
@ -83,7 +115,7 @@ public class APPDeviceController {
|
||||
|
||||
|
||||
@PostMapping(value = "/unbind")
|
||||
@ApiOperation("APP用户设备解绑")
|
||||
@ApiOperation("WEB端APP用户设备解绑")
|
||||
public ResponseVO<String> unbindAPPDevice(@Validated @ModelAttribute APPUnbindDTO deviceForm) {
|
||||
appDeviceService.unbindAPPDevice(deviceForm);
|
||||
return ResponseVO.success("解绑成功!!!");
|
||||
|
||||
@ -15,48 +15,30 @@
|
||||
*/
|
||||
package com.fuyuanshen.modules.system.rest.app;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.fuyuanshen.annotation.Log;
|
||||
import com.fuyuanshen.annotation.rest.AnonymousPostMapping;
|
||||
import com.fuyuanshen.exception.BadRequestException;
|
||||
import com.fuyuanshen.modules.security.service.UserCacheManager;
|
||||
import com.fuyuanshen.modules.security.service.dto.JwtUserDto;
|
||||
import com.fuyuanshen.modules.system.constant.UserConstants;
|
||||
import com.fuyuanshen.modules.system.domain.Dept;
|
||||
import com.fuyuanshen.modules.system.domain.Role;
|
||||
import com.fuyuanshen.modules.system.domain.User;
|
||||
import com.fuyuanshen.modules.system.domain.app.APPUser;
|
||||
import com.fuyuanshen.modules.system.domain.dto.UserPassVo;
|
||||
import com.fuyuanshen.modules.system.domain.dto.DeviceForm;
|
||||
import com.fuyuanshen.modules.system.domain.dto.UserQueryCriteria;
|
||||
import com.fuyuanshen.modules.system.domain.vo.ConsumerVo;
|
||||
import com.fuyuanshen.modules.system.domain.dto.app.APPForgotPasswordDTO;
|
||||
import com.fuyuanshen.modules.system.domain.dto.app.APPUpdateUserDTO;
|
||||
import com.fuyuanshen.modules.system.domain.dto.app.APPUserDTO;
|
||||
import com.fuyuanshen.modules.system.domain.vo.APPUserVo;
|
||||
import com.fuyuanshen.modules.system.enums.UserType;
|
||||
import com.fuyuanshen.modules.system.mapper.UserMapper;
|
||||
import com.fuyuanshen.modules.system.service.*;
|
||||
import com.fuyuanshen.modules.system.service.app.APPUserService;
|
||||
import com.fuyuanshen.modules.utils.ResponseVO;
|
||||
import com.fuyuanshen.utils.PageResult;
|
||||
import com.fuyuanshen.utils.SecurityUtils;
|
||||
import com.fuyuanshen.utils.StringUtils;
|
||||
import com.fuyuanshen.utils.enums.CodeEnum;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author Zheng Jie
|
||||
@ -82,14 +64,74 @@ public class APPUserController {
|
||||
}
|
||||
|
||||
|
||||
@ApiOperation("用户中心")
|
||||
@GetMapping(value = "/get")
|
||||
@PreAuthorize("@el.check('appUser:get')")
|
||||
public ResponseVO<APPUserVo> getAPPUser() {
|
||||
String userName = SecurityUtils.getCurrentUsername();
|
||||
APPUser appUser = appUserService.getLoginData(userName);
|
||||
|
||||
APPUserVo appUserVo = new APPUserVo();
|
||||
appUserVo.setId(appUser.getId());
|
||||
appUserVo.setNickName(appUser.getNickName());
|
||||
appUserVo.setGender(appUser.getGender());
|
||||
appUserVo.setPhone(appUser.getPhone());
|
||||
|
||||
return ResponseVO.success(appUserVo);
|
||||
}
|
||||
|
||||
@Log("app用户注册")
|
||||
@ApiOperation("app用户注册")
|
||||
@AnonymousPostMapping(value = "/register")
|
||||
public ResponseVO<String> APPRegister(@Validated @RequestBody APPUserDTO user) throws Exception {
|
||||
|
||||
//暫定0000
|
||||
if (!"0000".equals(user.getVerificationCode())) {
|
||||
throw new BadRequestException("验证码错误");
|
||||
}
|
||||
appUserService.addUser(user);
|
||||
return ResponseVO.success("success!!!");
|
||||
}
|
||||
|
||||
@Log("发送用户注册验证码")
|
||||
@ApiOperation("发送用户注册验证码")
|
||||
@AnonymousPostMapping(value = "/sendRegisterSms")
|
||||
public ResponseVO<String> sendRegisterSms(@Param("phoneNumber") String phoneNumber) throws Exception {
|
||||
// appUserService.sendSms(phoneNumber);
|
||||
return ResponseVO.success("success!!!");
|
||||
}
|
||||
|
||||
@Log("修改APP用户")
|
||||
@ApiOperation("修改APP用户")
|
||||
@PutMapping
|
||||
@PreAuthorize("@el.check('appUser:edit')")
|
||||
public ResponseVO<String> updateUser(@Validated(APPUser.Update.class) @RequestBody APPUser appUser) throws Exception {
|
||||
appUserService.updateById(appUser);
|
||||
public ResponseVO<String> updateUser(@Validated @ModelAttribute APPUpdateUserDTO appUser) throws Exception {
|
||||
Long userId = SecurityUtils.getCurrentUserId();
|
||||
if(!userId.equals(appUser.getId())){
|
||||
throw new BadRequestException("不能修改他人资料");
|
||||
}
|
||||
|
||||
appUserService.updateUser(appUser);
|
||||
return ResponseVO.success("success!!!");
|
||||
}
|
||||
|
||||
|
||||
@Log("忘记密码")
|
||||
@ApiOperation("忘记密码")
|
||||
@AnonymousPostMapping(value = "/forgotPassword")
|
||||
public ResponseVO<String> forgotPassword(@RequestBody APPForgotPasswordDTO appForgotPasswordDTO) throws Exception {
|
||||
if (!"0000".equals(appForgotPasswordDTO.getVerificationCode())) {
|
||||
throw new BadRequestException("验证码错误");
|
||||
}
|
||||
appUserService.forgotPassword(appForgotPasswordDTO);
|
||||
return ResponseVO.success("success!!!");
|
||||
}
|
||||
|
||||
@Log("发送忘记密码验证码")
|
||||
@ApiOperation("发送忘记密码验证码")
|
||||
@AnonymousPostMapping(value = "/sendForgotPasswordSms")
|
||||
public ResponseVO<String> sendForgotPasswordSms(@Param("phoneNumber") String phoneNumber) throws Exception {
|
||||
// appUserService.sendSms(phoneNumber);
|
||||
return ResponseVO.success("success!!!");
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,6 +16,8 @@
|
||||
package com.fuyuanshen.modules.system.service;
|
||||
|
||||
import com.fuyuanshen.modules.system.domain.User;
|
||||
import com.fuyuanshen.modules.system.domain.app.APPUser;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -31,4 +33,12 @@ public interface DataService {
|
||||
* @return /
|
||||
*/
|
||||
List<Long> getDeptIds(User user);
|
||||
|
||||
/**
|
||||
* 获取数据权限
|
||||
* @param user /
|
||||
* @return /
|
||||
*/
|
||||
List<Long> getDeptIds(APPUser user);
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,13 @@
|
||||
package com.fuyuanshen.modules.system.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.fuyuanshen.modules.system.domain.DeviceAssignments;
|
||||
|
||||
/**
|
||||
* @author 97433
|
||||
* @description 针对表【device_assignments】的数据库操作Service
|
||||
* @createDate 2025-06-19 18:19:13
|
||||
*/
|
||||
public interface DeviceAssignmentsService extends IService<DeviceAssignments> {
|
||||
|
||||
}
|
||||
@ -80,6 +80,13 @@ public interface DeviceService extends IService<Device> {
|
||||
*/
|
||||
void deleteAll(List<Long> ids);
|
||||
|
||||
/**
|
||||
* 删除设备分配记录
|
||||
*
|
||||
* @param ids
|
||||
*/
|
||||
void deleteAssign(List<Long> ids);
|
||||
|
||||
/**
|
||||
* 导出数据
|
||||
*
|
||||
@ -103,4 +110,5 @@ public interface DeviceService extends IService<Device> {
|
||||
*/
|
||||
void unbindDevice(DeviceForm deviceForm);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,14 @@
|
||||
package com.fuyuanshen.modules.system.service;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.fuyuanshen.modules.system.domain.DeviceTypeGrants;
|
||||
|
||||
/**
|
||||
* @author 97433
|
||||
* @description 针对表【device_type_grants】的数据库操作Service
|
||||
* @createDate 2025-06-19 13:49:33
|
||||
*/
|
||||
public interface DeviceTypeGrantsService extends IService<DeviceTypeGrants> {
|
||||
|
||||
}
|
||||
@ -13,39 +13,50 @@ import java.util.List;
|
||||
* @Author: WY
|
||||
* @Date: 2025/5/14
|
||||
**/
|
||||
public interface DeviceTypeService extends IService<DeviceType> {
|
||||
public interface DeviceTypeService extends IService<DeviceType> {
|
||||
|
||||
/**
|
||||
* 查询数据分页
|
||||
*
|
||||
* @param criteria 条件
|
||||
* @param page 分页参数
|
||||
* @param page 分页参数
|
||||
* @return PageResult
|
||||
*/
|
||||
PageResult<DeviceType> queryAll(DeviceTypeQueryCriteria criteria, Page<Object> page);
|
||||
|
||||
/**
|
||||
* 查询所有数据不分页
|
||||
*
|
||||
* @param criteria 条件参数
|
||||
* @return List<DeviceTypeDto>
|
||||
*/
|
||||
List<DeviceType> queryAll(DeviceTypeQueryCriteria criteria);
|
||||
|
||||
|
||||
/**
|
||||
* 查询所有设备类型
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<DeviceType> queryDeviceTypes();
|
||||
|
||||
/**
|
||||
* 创建
|
||||
* 新增设备类型
|
||||
*
|
||||
* @param resources /
|
||||
*/
|
||||
void create(DeviceType resources);
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
*
|
||||
* @param resources /
|
||||
*/
|
||||
void update(DeviceType resources);
|
||||
|
||||
/**
|
||||
* 多选删除
|
||||
*
|
||||
* @param ids /
|
||||
*/
|
||||
void deleteAll(List<Long> ids);
|
||||
|
||||
@ -20,6 +20,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.fuyuanshen.modules.security.service.dto.AuthorityDto;
|
||||
import com.fuyuanshen.modules.system.domain.Role;
|
||||
import com.fuyuanshen.modules.system.domain.User;
|
||||
import com.fuyuanshen.modules.system.domain.app.APPUser;
|
||||
import com.fuyuanshen.modules.system.domain.dto.RoleQueryCriteria;
|
||||
import com.fuyuanshen.utils.PageResult;
|
||||
|
||||
@ -116,6 +117,14 @@ public interface RoleService extends IService<Role> {
|
||||
*/
|
||||
List<AuthorityDto> buildPermissions(User user);
|
||||
|
||||
/**
|
||||
* 获取用户权限信息
|
||||
* @param user 用户信息
|
||||
* @return 权限信息
|
||||
*/
|
||||
List<AuthorityDto> appBuildPermissions(APPUser user);
|
||||
|
||||
|
||||
/**
|
||||
* 验证是否被用户关联
|
||||
* @param ids /
|
||||
|
||||
@ -18,6 +18,7 @@ package com.fuyuanshen.modules.system.service;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.fuyuanshen.modules.system.domain.User;
|
||||
import com.fuyuanshen.modules.system.domain.app.APPUser;
|
||||
import com.fuyuanshen.modules.system.domain.dto.UserQueryCriteria;
|
||||
import com.fuyuanshen.modules.system.domain.vo.ConsumerVo;
|
||||
import com.fuyuanshen.utils.PageResult;
|
||||
@ -96,6 +97,8 @@ public interface UserService extends IService<User> {
|
||||
*/
|
||||
User getLoginData(String userName);
|
||||
|
||||
APPUser appGetLoginData(String userName);
|
||||
|
||||
/**
|
||||
* 修改密码
|
||||
*
|
||||
|
||||
@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.fuyuanshen.modules.system.domain.Device;
|
||||
import com.fuyuanshen.modules.system.domain.app.APPDevice;
|
||||
import com.fuyuanshen.modules.system.domain.app.APPDeviceType;
|
||||
import com.fuyuanshen.modules.system.domain.dto.CustomerVo;
|
||||
import com.fuyuanshen.modules.system.domain.dto.DeviceForm;
|
||||
import com.fuyuanshen.modules.system.domain.dto.DeviceQueryCriteria;
|
||||
@ -22,6 +23,29 @@ import java.util.List;
|
||||
**/
|
||||
public interface APPDeviceService extends IService<APPDevice> {
|
||||
|
||||
/**
|
||||
* APP用户设备列表
|
||||
*
|
||||
* @param criteria
|
||||
*/
|
||||
PageResult<APPDevice> appDeviceList(Page<APPDevice> page, DeviceQueryCriteria criteria);
|
||||
|
||||
|
||||
/**
|
||||
* APP用户设备类型列表
|
||||
*
|
||||
* @param criteria
|
||||
* @return
|
||||
*/
|
||||
List<APPDeviceType> appTypeList(DeviceQueryCriteria criteria);
|
||||
|
||||
/**
|
||||
* APP/小程序用户设备绑定
|
||||
*
|
||||
* @param criteria
|
||||
*/
|
||||
void appBindDevice(DeviceQueryCriteria criteria);
|
||||
|
||||
/**
|
||||
* 分页查询APP/小程序设备绑定
|
||||
*
|
||||
@ -38,4 +62,5 @@ public interface APPDeviceService extends IService<APPDevice> {
|
||||
*/
|
||||
void unbindAPPDevice(APPUnbindDTO deviceForm);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -2,48 +2,35 @@ package com.fuyuanshen.modules.system.service.app;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.fuyuanshen.constants.DeviceConstants;
|
||||
import com.fuyuanshen.constants.ExceptionMessages;
|
||||
import com.fuyuanshen.exception.BadRequestException;
|
||||
import com.fuyuanshen.modules.security.service.UserCacheManager;
|
||||
import com.fuyuanshen.modules.system.constant.UserConstants;
|
||||
import com.fuyuanshen.modules.system.domain.Device;
|
||||
import com.fuyuanshen.modules.system.domain.DeviceType;
|
||||
import com.fuyuanshen.modules.system.domain.User;
|
||||
import com.fuyuanshen.modules.system.domain.app.APPDevice;
|
||||
import com.fuyuanshen.modules.system.domain.dto.CustomerVo;
|
||||
import com.fuyuanshen.modules.system.domain.dto.DeviceForm;
|
||||
import com.fuyuanshen.modules.system.domain.app.APPDeviceType;
|
||||
import com.fuyuanshen.modules.system.domain.dto.DeviceQueryCriteria;
|
||||
import com.fuyuanshen.modules.system.domain.dto.app.APPUnbindDTO;
|
||||
import com.fuyuanshen.modules.system.enums.BindingStatusEnum;
|
||||
import com.fuyuanshen.modules.system.enums.CommunicationModeEnum;
|
||||
import com.fuyuanshen.modules.system.enums.UserType;
|
||||
import com.fuyuanshen.modules.system.mapper.DeviceMapper;
|
||||
import com.fuyuanshen.modules.system.mapper.DeviceTypeMapper;
|
||||
import com.fuyuanshen.modules.system.mapper.UserMapper;
|
||||
import com.fuyuanshen.modules.system.mapper.app.APPDeviceMapper;
|
||||
import com.fuyuanshen.modules.system.service.DeviceService;
|
||||
import com.fuyuanshen.modules.system.service.UserService;
|
||||
import com.fuyuanshen.modules.system.service.impl.DeviceTypeServiceImpl;
|
||||
import com.fuyuanshen.modules.utils.NanoId;
|
||||
import com.fuyuanshen.utils.*;
|
||||
import com.fuyuanshen.modules.system.mapper.app.AppDeviceTypeMapper;
|
||||
import com.fuyuanshen.utils.PageResult;
|
||||
import com.fuyuanshen.utils.SecurityUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
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.*;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@ -58,6 +45,89 @@ public class APPDeviceServiceImpl extends ServiceImpl<APPDeviceMapper, APPDevice
|
||||
|
||||
private final APPDeviceMapper appDeviceMapper;
|
||||
private final DeviceMapper deviceMapper;
|
||||
private final DeviceTypeMapper deviceTypeMapper;
|
||||
private final AppDeviceTypeMapper appDeviceTypeMapper;
|
||||
|
||||
|
||||
/**
|
||||
* APP用户设备列表
|
||||
*
|
||||
* @param criteria
|
||||
*/
|
||||
@Override
|
||||
public PageResult<APPDevice> appDeviceList(Page<APPDevice> page, DeviceQueryCriteria criteria) {
|
||||
IPage<APPDevice> devices = appDeviceMapper.appDeviceList(page, criteria);
|
||||
return new PageResult<>(devices.getRecords(), devices.getTotal());
|
||||
}
|
||||
|
||||
/**
|
||||
* APP用户设备类型列表
|
||||
*
|
||||
* @param criteria
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<APPDeviceType> appTypeList(DeviceQueryCriteria criteria) {
|
||||
return appDeviceTypeMapper.appTypeList(criteria);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* APP/小程序用户设备绑定
|
||||
*
|
||||
* @param criteria
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
public void appBindDevice(DeviceQueryCriteria criteria) {
|
||||
|
||||
List<Device> devices = new ArrayList<>();
|
||||
|
||||
if (criteria.getCommunicationMode().equals(CommunicationModeEnum.BLUETOOTH.getValue())) {
|
||||
devices = deviceMapper.selectList(new QueryWrapper<Device>().eq("device_mac", criteria.getDeviceMac()));
|
||||
if (CollectionUtil.isEmpty(devices)) {
|
||||
throw new BadRequestException("请先将设备入库!!!");
|
||||
}
|
||||
List<APPDevice> appDevices = appDeviceMapper.selectList(new QueryWrapper<APPDevice>()
|
||||
.eq("device_mac", criteria.getDeviceMac()).eq("binding_type", UserType.APP.getValue()));
|
||||
if (CollectionUtil.isNotEmpty(appDevices)) {
|
||||
throw new BadRequestException("该设备已绑定!!!");
|
||||
}
|
||||
}
|
||||
|
||||
if (criteria.getCommunicationMode().equals(CommunicationModeEnum.FOUR_G.getValue())) {
|
||||
devices = deviceMapper.selectList(new QueryWrapper<Device>().eq("device_imei", criteria.getDeviceImei()));
|
||||
if (CollectionUtil.isEmpty(devices)) {
|
||||
throw new BadRequestException("请先将设备入库!!!");
|
||||
}
|
||||
List<APPDevice> appDevices = appDeviceMapper.selectList(new QueryWrapper<APPDevice>()
|
||||
.eq("device_imei", criteria.getDeviceImei()).eq("binding_type", UserType.APP.getValue()));
|
||||
if (CollectionUtil.isNotEmpty(appDevices)) {
|
||||
throw new BadRequestException("该设备已绑定!!!");
|
||||
}
|
||||
}
|
||||
|
||||
Device device = devices.get(0);
|
||||
APPDevice appDevice = new APPDevice();
|
||||
BeanUtil.copyProperties(device, appDevice);
|
||||
appDevice.setBindingType(UserType.APP.getValue());
|
||||
appDevice.setBindingStatus(BindingStatusEnum.BOUND.getCode());
|
||||
Long currentUserId = SecurityUtils.getCurrentUserId();
|
||||
appDevice.setCustomerId(currentUserId);
|
||||
appDevice.setCreateTime(new Timestamp(System.currentTimeMillis()));
|
||||
// 设备类型名称
|
||||
appDevice.setDeviceTypeName(device.getTypeName());
|
||||
appDeviceMapper.insert(appDevice);
|
||||
|
||||
APPDeviceType appDeviceType = appDeviceTypeMapper.selectById(device.getDeviceType());
|
||||
if (appDeviceType == null) {
|
||||
DeviceType deviceType = deviceTypeMapper.selectById(device.getDeviceType());
|
||||
APPDeviceType type = new APPDeviceType();
|
||||
BeanUtil.copyProperties(deviceType, type);
|
||||
appDeviceTypeMapper.insert(type);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@ -83,11 +153,17 @@ public class APPDeviceServiceImpl extends ServiceImpl<APPDeviceMapper, APPDevice
|
||||
@Transactional
|
||||
public void unbindAPPDevice(APPUnbindDTO deviceForm) {
|
||||
|
||||
appDeviceMapper.delete(new QueryWrapper<APPDevice>().eq("device_mac", deviceForm.getDeviceMac()));
|
||||
appDeviceMapper.delete(new QueryWrapper<APPDevice>().eq("device_mac", deviceForm.getDeviceMac()).eq("binding_type", UserType.APP.getValue()));
|
||||
List<Device> devices = deviceMapper.selectList(new QueryWrapper<Device>().eq("device_mac", deviceForm.getDeviceMac()));
|
||||
List<Long> ids = devices.stream()
|
||||
.map(Device::getId)
|
||||
.collect(Collectors.toList());
|
||||
appDeviceTypeMapper.deleteBatchIds(ids);
|
||||
Device device = new Device();
|
||||
device.setId(deviceForm.getCustomerId());
|
||||
device.setBindingStatus(BindingStatusEnum.UNBOUND.getCode());
|
||||
deviceMapper.updateById(device);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -17,10 +17,18 @@ package com.fuyuanshen.modules.system.service.app;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.fuyuanshen.modules.security.service.dto.app.AppRoleDto;
|
||||
import com.fuyuanshen.modules.system.domain.Role;
|
||||
import com.fuyuanshen.modules.system.domain.app.APPUser;
|
||||
import com.fuyuanshen.modules.system.domain.dto.UserQueryCriteria;
|
||||
import com.fuyuanshen.modules.system.domain.dto.app.APPForgotPasswordDTO;
|
||||
import com.fuyuanshen.modules.system.domain.dto.app.APPUpdateUserDTO;
|
||||
import com.fuyuanshen.modules.system.domain.dto.app.APPUserDTO;
|
||||
import com.fuyuanshen.modules.utils.ResponseVO;
|
||||
import com.fuyuanshen.utils.PageResult;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Zheng Jie
|
||||
* @date 2018-11-23
|
||||
@ -36,5 +44,22 @@ public interface APPUserService extends IService<APPUser> {
|
||||
*/
|
||||
PageResult<APPUser> queryAPPUser(UserQueryCriteria criteria, Page<APPUser> page);
|
||||
|
||||
/**
|
||||
* 根据用户名查询
|
||||
*
|
||||
* @param userName /
|
||||
* @return /
|
||||
*/
|
||||
APPUser getLoginData(String userName);
|
||||
|
||||
|
||||
ResponseVO<Object> addUser(APPUserDTO user);
|
||||
|
||||
Integer selectRoleByUserLevel(Set<Role> roles);
|
||||
|
||||
void forgotPassword(APPForgotPasswordDTO appForgotPasswordDTO);
|
||||
|
||||
void sendSms(String phoneNumber);
|
||||
|
||||
void updateUser(APPUpdateUserDTO appUser);
|
||||
}
|
||||
|
||||
@ -0,0 +1,13 @@
|
||||
package com.fuyuanshen.modules.system.service.app;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.fuyuanshen.modules.system.domain.app.APPDeviceType;
|
||||
|
||||
/**
|
||||
* @author 97433
|
||||
* @description 针对表【app_device_type(设备类型表)】的数据库操作Service
|
||||
* @createDate 2025-06-24 11:16:18
|
||||
*/
|
||||
public interface AppDeviceTypeService extends IService<APPDeviceType> {
|
||||
|
||||
}
|
||||
@ -16,6 +16,7 @@
|
||||
package com.fuyuanshen.modules.system.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.fuyuanshen.modules.system.domain.app.APPUser;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import com.fuyuanshen.modules.system.domain.Dept;
|
||||
import com.fuyuanshen.modules.system.domain.Role;
|
||||
@ -93,4 +94,36 @@ public class DataServiceImpl implements DataService {
|
||||
}
|
||||
return deptIds;
|
||||
}
|
||||
/**
|
||||
* 用户角色和用户部门改变时需清理缓存
|
||||
* @param user /
|
||||
* @return /
|
||||
*/
|
||||
@Override
|
||||
public List<Long> getDeptIds(APPUser user) {
|
||||
String key = CacheKey.DATA_APP_USER + user.getId();
|
||||
List<Long> ids = redisUtils.getList(key, Long.class);
|
||||
if (CollUtil.isEmpty(ids)) {
|
||||
Set<Long> deptIds = new HashSet<>();
|
||||
// 查询用户角色
|
||||
List<Role> roleList = roleService.findByUsersId(user.getId());
|
||||
// 获取对应的部门ID
|
||||
for (Role role : roleList) {
|
||||
DataScopeEnum dataScopeEnum = DataScopeEnum.find(role.getDataScope());
|
||||
switch (Objects.requireNonNull(dataScopeEnum)) {
|
||||
case THIS_LEVEL:
|
||||
deptIds.add(user.getDept().getId());
|
||||
break;
|
||||
case CUSTOMIZE:
|
||||
deptIds.addAll(getCustomize(deptIds, role));
|
||||
break;
|
||||
default:
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
ids = new ArrayList<>(deptIds);
|
||||
redisUtils.set(key, ids, 1, TimeUnit.DAYS);
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,18 @@
|
||||
package com.fuyuanshen.modules.system.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.fuyuanshen.modules.system.domain.DeviceAssignments;
|
||||
import com.fuyuanshen.modules.system.mapper.DeviceAssignmentsMapper;
|
||||
import com.fuyuanshen.modules.system.service.DeviceAssignmentsService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @author 97433
|
||||
* @description 针对表【device_assignments】的数据库操作Service实现
|
||||
* @createDate 2025-06-19 18:19:13
|
||||
*/
|
||||
@Service
|
||||
public class DeviceAssignmentsServiceImpl extends ServiceImpl<DeviceAssignmentsMapper, DeviceAssignments>
|
||||
implements DeviceAssignmentsService {
|
||||
|
||||
}
|
||||
@ -41,7 +41,8 @@ public class DeviceExportService {
|
||||
dto.setCustomerName(device.getCustomerName());
|
||||
dto.setDeviceName(device.getDeviceName());
|
||||
dto.setDeviceMac(device.getDeviceMac());
|
||||
dto.setDeviceSn(device.getDeviceSn());
|
||||
// 设备IMEI
|
||||
dto.setDeviceImei(device.getDeviceImei());
|
||||
dto.setLongitude(device.getLongitude());
|
||||
dto.setLatitude(device.getLatitude());
|
||||
dto.setRemark(device.getRemark());
|
||||
|
||||
@ -2,7 +2,7 @@ package com.fuyuanshen.modules.system.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
@ -12,28 +12,29 @@ import com.fuyuanshen.constants.ExceptionMessages;
|
||||
import com.fuyuanshen.exception.BadRequestException;
|
||||
import com.fuyuanshen.modules.security.service.UserCacheManager;
|
||||
import com.fuyuanshen.modules.system.constant.UserConstants;
|
||||
import com.fuyuanshen.modules.system.domain.Device;
|
||||
import com.fuyuanshen.modules.system.domain.DeviceType;
|
||||
import com.fuyuanshen.modules.system.domain.User;
|
||||
import com.fuyuanshen.modules.system.domain.*;
|
||||
import com.fuyuanshen.modules.system.domain.app.APPDevice;
|
||||
import com.fuyuanshen.modules.system.domain.dto.CustomerVo;
|
||||
import com.fuyuanshen.modules.system.domain.dto.DeviceForm;
|
||||
import com.fuyuanshen.modules.system.domain.dto.DeviceQueryCriteria;
|
||||
import com.fuyuanshen.modules.system.enums.BindingStatusEnum;
|
||||
import com.fuyuanshen.modules.system.mapper.DeviceMapper;
|
||||
import com.fuyuanshen.modules.system.mapper.DeviceTypeMapper;
|
||||
import com.fuyuanshen.modules.system.mapper.UserMapper;
|
||||
import com.fuyuanshen.modules.system.enums.DeviceActiveStatusEnum;
|
||||
import com.fuyuanshen.modules.system.enums.DeviceAuthorizationStatus;
|
||||
import com.fuyuanshen.modules.system.enums.DeviceStatusEnum;
|
||||
import com.fuyuanshen.modules.system.mapper.*;
|
||||
import com.fuyuanshen.modules.system.mapper.app.APPDeviceMapper;
|
||||
import com.fuyuanshen.modules.system.service.DeviceAssignmentsService;
|
||||
import com.fuyuanshen.modules.system.service.DeviceService;
|
||||
import com.fuyuanshen.modules.system.service.DeviceTypeGrantsService;
|
||||
import com.fuyuanshen.modules.system.service.UserService;
|
||||
import com.fuyuanshen.modules.utils.AdminCheckUtil;
|
||||
import com.fuyuanshen.modules.utils.NanoId;
|
||||
import com.fuyuanshen.utils.*;
|
||||
import com.fuyuanshen.utils.enums.NanoIdLengthEnum;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
@ -41,6 +42,7 @@ import org.springframework.web.multipart.MultipartFile;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.*;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -54,6 +56,12 @@ import java.util.stream.Collectors;
|
||||
@RequiredArgsConstructor
|
||||
public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> implements DeviceService {
|
||||
|
||||
/**
|
||||
* 初级分配等级
|
||||
*/
|
||||
public static final int LEVEL_PRIMARY = 1;
|
||||
|
||||
|
||||
@Value("${file.device.pic}")
|
||||
private String filePath;
|
||||
@Value("${file.device.ip}")
|
||||
@ -67,6 +75,10 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
|
||||
private final UserCacheManager userCacheManager;
|
||||
|
||||
private final APPDeviceMapper appDeviceMapper;
|
||||
private final DeviceTypeGrantsMapper deviceTypeGrantsMapper;
|
||||
private final DeviceAssignmentsService deviceAssignmentsService;
|
||||
private final DeviceAssignmentsMapper deviceAssignmentsMapper;
|
||||
private final DeviceTypeGrantsService deviceTypeGrantsService;
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
@ -93,7 +105,8 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
|
||||
|
||||
// 只能看到自己的创建的设备,以及被分配的设备。
|
||||
if (onlineuser.getTenantId() != null && !onlineuser.getTenantId().equals(UserConstants.SUPER_ADMIN_ID)) {
|
||||
criteria.setTenantId(onlineuser.getTenantId());
|
||||
// criteria.setTenantId(onlineuser.getTenantId());
|
||||
criteria.setCurrentOwnerId(onlineuser.getId());
|
||||
}
|
||||
|
||||
IPage<Device> devices = deviceMapper.findAll(criteria, page);
|
||||
@ -137,22 +150,33 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
|
||||
public void addDevice(DeviceForm deviceForm) throws Exception {
|
||||
|
||||
// 获取当前登录用户信息
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
String username1 = authentication.getName();
|
||||
// Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
// String username1 = authentication.getName();
|
||||
// 从缓存获取
|
||||
// UserDetails currentUser = SecurityUtils.getCurrentUser();
|
||||
// String username = currentUser.getUsername();
|
||||
// JwtUserDto jwtUserDto = userCacheManager.getUserCache(username);
|
||||
User currentUser = userMapper.findByUsername(SecurityUtils.getCurrentUsername());
|
||||
QueryWrapper<Device> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("device_mac", deviceForm.getDeviceMac());
|
||||
// queryWrapper.eq("tenant_id", currentUser.getTenantId());
|
||||
if ((deviceMapper.selectOne(queryWrapper)) != null) {
|
||||
throw new BadRequestException("设备 mac地址 有误,请仔细核对!!!");
|
||||
|
||||
if (StringUtils.isNotEmpty(deviceForm.getDeviceMac())) {
|
||||
QueryWrapper<Device> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("device_mac", deviceForm.getDeviceMac());
|
||||
// queryWrapper.eq("tenant_id", currentUser.getTenantId());
|
||||
if ((deviceMapper.selectOne(queryWrapper)) != null) {
|
||||
throw new BadRequestException("设备 mac地址 有误,请仔细核对!!!");
|
||||
}
|
||||
}
|
||||
|
||||
QueryWrapper<DeviceTypeGrants> deviceTypeGrantsQueryWrapper = new QueryWrapper<>();
|
||||
deviceTypeGrantsQueryWrapper.eq("customer_id", currentUser.getId());
|
||||
deviceTypeGrantsQueryWrapper.eq("device_type_id", deviceForm.getDeviceType());
|
||||
Long count = deviceTypeGrantsMapper.selectCount(deviceTypeGrantsQueryWrapper);
|
||||
if (count <= 0) {
|
||||
throw new BadRequestException("请先授权设备类型!!!");
|
||||
}
|
||||
|
||||
// 保存图片并获取URL
|
||||
String imageUrl = saveDeviceImage(deviceForm.getFile(), deviceForm.getDeviceMac());
|
||||
|
||||
// 设置图片路径
|
||||
deviceForm.setDevicePic(imageUrl);
|
||||
|
||||
@ -163,10 +187,30 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
|
||||
// 添加租户ID
|
||||
device.setTenantId(currentUser.getTenantId());
|
||||
// 默认状态正常
|
||||
device.setDeviceStatus(1);
|
||||
device.setDeviceStatus(DeviceStatusEnum.NORMAL.getCode());
|
||||
// SnowflakeGenerator snowflakeGenerator = new SnowflakeGenerator();
|
||||
// device.setId(snowflakeGenerator.next());
|
||||
device.setCurrentOwnerId(currentUser.getId());
|
||||
device.setOriginalOwnerId(currentUser.getId());
|
||||
DeviceType deviceType = deviceTypeMapper.selectById(deviceForm.getDeviceType());
|
||||
device.setTypeName(deviceType.getTypeName());
|
||||
|
||||
deviceMapper.insert(device);
|
||||
|
||||
// 新增设备类型记录
|
||||
DeviceAssignments assignments = new DeviceAssignments();
|
||||
assignments.setDeviceId(device.getId());
|
||||
assignments.setAssignedAt(LocalDateTime.now());
|
||||
// 分配者
|
||||
assignments.setAssignerId(currentUser.getId());
|
||||
assignments.setAssignerName(currentUser.getUsername());
|
||||
// 接收者
|
||||
assignments.setAssigneeId(currentUser.getId());
|
||||
assignments.setActive(DeviceActiveStatusEnum.ACTIVE.getCode());
|
||||
String lever = currentUser.getId() + ":";
|
||||
assignments.setLever(lever);
|
||||
deviceAssignmentsService.save(assignments);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -221,6 +265,70 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 分配客户 历史记录版本
|
||||
*
|
||||
* @param customerVo
|
||||
*/
|
||||
|
||||
public void assignCustomer1(CustomerVo customerVo) {
|
||||
|
||||
// 防止管理员误操作
|
||||
User currentUser = userService.findById(SecurityUtils.getCurrentUserId());
|
||||
if (currentUser.getTenantId().equals(UserConstants.SUPER_ADMIN_ID)) {
|
||||
throw new BadRequestException(ExceptionMessages.ADMIN_OPERATION_NOT_ALLOWED);
|
||||
}
|
||||
|
||||
List<DeviceAssignments> assignments = new ArrayList<>();
|
||||
List<DeviceTypeGrants> deviceTypeGrants = new ArrayList<>();
|
||||
List<Device> devices = new ArrayList<>();
|
||||
customerVo.getDeviceIds().forEach(deviceId -> {
|
||||
|
||||
// 阻止重复分配
|
||||
Device device = deviceMapper.selectById(deviceId);
|
||||
if (device.getCustomerId() != null && device.getCustomerId().equals(customerVo.getCustomerId())) {
|
||||
throw new BadRequestException("设备 " + device.getDeviceName() + " 已被分配给客户 " + device.getCustomerName());
|
||||
}
|
||||
|
||||
// 自定义16位id
|
||||
Long generatedId = NanoId.generate(NanoIdLengthEnum.HIGH_CONCURRENCY.getLength());
|
||||
|
||||
// -- 记录分配历史
|
||||
DeviceAssignments deviceAssignments = new DeviceAssignments();
|
||||
deviceAssignments.setId(generatedId);
|
||||
deviceAssignments.setDeviceId(deviceId);
|
||||
deviceAssignments.setFromCustomerId(currentUser.getId());
|
||||
deviceAssignments.setToCustomerId(customerVo.getCustomerId());
|
||||
deviceAssignments.setAssignedAt(LocalDateTime.now());
|
||||
deviceAssignments.setDeviceTypeGranted(DeviceAuthorizationStatus.AUTHORIZED.getValue());
|
||||
assignments.add(deviceAssignments);
|
||||
|
||||
// -- 授权设备类型给客户
|
||||
// QueryWrapper<DeviceTypeGrants> deviceTypeGrantsQueryWrapper = new QueryWrapper<>();
|
||||
// Long count = deviceTypeGrantsMapper.selectCount(deviceTypeGrantsQueryWrapper);
|
||||
DeviceTypeGrants deviceTypeGrant = new DeviceTypeGrants();
|
||||
deviceTypeGrant.setGrantedAt(new Date());
|
||||
// 设备类型
|
||||
deviceTypeGrant.setDeviceTypeId(device.getDeviceType());
|
||||
deviceTypeGrant.setAssignmentId(generatedId);
|
||||
// 被授权的客户
|
||||
deviceTypeGrant.setCustomerId(customerVo.getCustomerId());
|
||||
// 授权方客户
|
||||
deviceTypeGrant.setGrantorCustomerId(currentUser.getId());
|
||||
deviceTypeGrants.add(deviceTypeGrant);
|
||||
|
||||
// -- 更新设备所有者
|
||||
device.setCurrentOwnerId(customerVo.getCustomerId());
|
||||
devices.add(device);
|
||||
});
|
||||
|
||||
deviceAssignmentsService.saveBatch(assignments);
|
||||
deviceTypeGrantsService.saveBatch(deviceTypeGrants);
|
||||
this.updateBatchById(devices);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 分配客户
|
||||
*
|
||||
@ -230,73 +338,144 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void assignCustomer(CustomerVo customerVo) {
|
||||
|
||||
// 防止管理员误操作
|
||||
// 获取当前登录用户
|
||||
User currentUser = userService.findById(SecurityUtils.getCurrentUserId());
|
||||
if (currentUser.getTenantId().equals(UserConstants.SUPER_ADMIN_ID)) {
|
||||
throw new BadRequestException(ExceptionMessages.ADMIN_OPERATION_NOT_ALLOWED);
|
||||
}
|
||||
// 防止管理员误操作
|
||||
AdminCheckUtil.checkIfSuperAdmin(currentUser);
|
||||
// 获取分配用户信息
|
||||
User assignUser = userService.findById(customerVo.getCustomerId());
|
||||
|
||||
User user = userService.findById(customerVo.getCustomerId());
|
||||
// 获取分配设备信息
|
||||
List<Device> devices = deviceMapper.selectBatchIds(customerVo.getDeviceIds());
|
||||
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
|
||||
for (Device device : devices) {
|
||||
device.setCustomerId(user.getId());
|
||||
device.setCustomerName(user.getNickName());
|
||||
device.setUpdateTime(timestamp);
|
||||
}
|
||||
this.updateBatchById(devices);
|
||||
|
||||
// 批量更新设备状态
|
||||
List<DeviceTypeGrants> deviceTypeGrants = new ArrayList<>();
|
||||
for (Device device : devices) {
|
||||
// 获取当前用户的所有祖先用户
|
||||
List<User> ancestorsById = userMapper.findAncestorsById(currentUser.getId());
|
||||
Set<Long> excludedTenantIds = new HashSet<>();
|
||||
if (CollectionUtil.isNotEmpty(ancestorsById)) {
|
||||
// 提取所有需要排除的 tenant_id
|
||||
excludedTenantIds = ancestorsById.stream().map(User::getTenantId).distinct().collect(Collectors.toSet());
|
||||
}
|
||||
excludedTenantIds.add(currentUser.getTenantId());
|
||||
// 构建查询条件:device_mac 相同,并且 tenant_id 不在 excludedTenantIds 列表中
|
||||
Wrapper<Device> wrapper = new QueryWrapper<Device>().eq("device_mac", device.getDeviceMac()).notIn("tenant_id", excludedTenantIds);
|
||||
|
||||
// 构建要更新的数据
|
||||
Device updateDevice = new Device();
|
||||
updateDevice.setDeviceStatus(0);
|
||||
updateDevice.setUpdateTime(new Timestamp(System.currentTimeMillis()));
|
||||
// 如果设备已分配给需要分配的客户,则跳过
|
||||
LambdaQueryWrapper<DeviceAssignments> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(DeviceAssignments::getDeviceId, device.getId()).eq(DeviceAssignments::getAssigneeId, customerVo.getCustomerId()).ne(DeviceAssignments::getActive, DeviceActiveStatusEnum.INACTIVE.getCode());
|
||||
List<DeviceAssignments> deviceAssignments = deviceAssignmentsMapper.selectList(wrapper);
|
||||
if (CollectionUtil.isNotEmpty(deviceAssignments)) {
|
||||
log.info("设备 {} 已分配给客户 {}", device.getDeviceName(), device.getCustomerName());
|
||||
continue;
|
||||
}
|
||||
|
||||
// 更改分配客户
|
||||
QueryWrapper<DeviceAssignments> q = new QueryWrapper<>();
|
||||
q.eq("device_id", device.getId());
|
||||
q.eq("assignee_id", currentUser.getId());
|
||||
q.ne("active", DeviceActiveStatusEnum.INACTIVE.getCode());
|
||||
DeviceAssignments d = new DeviceAssignments();
|
||||
d.setAssigneeName(assignUser.getUsername());
|
||||
deviceAssignmentsMapper.update(d, q);
|
||||
|
||||
// 设备失效
|
||||
// 获取用户的设备记录
|
||||
DeviceAssignments assignment = deviceAssignmentsMapper.selectOne(new LambdaQueryWrapper<DeviceAssignments>().eq(DeviceAssignments::getDeviceId, device.getId()).eq(DeviceAssignments::getAssigneeId, currentUser.getId()).eq(DeviceAssignments::getActive, DeviceActiveStatusEnum.ACTIVE.getCode()));
|
||||
|
||||
LambdaQueryWrapper<DeviceAssignments> q1 = new LambdaQueryWrapper<>();
|
||||
q1.eq(DeviceAssignments::getDeviceId, device.getId()).ne(DeviceAssignments::getAssigneeId, currentUser.getId()).like(DeviceAssignments::getLever, assignment.getLever());
|
||||
|
||||
DeviceAssignments d1 = new DeviceAssignments();
|
||||
d1.setActive(DeviceActiveStatusEnum.INACTIVE.getCode());
|
||||
deviceAssignmentsMapper.update(d1, q1);
|
||||
|
||||
// device.setCustomerId(assignUser.getId());
|
||||
// device.setCustomerName(assignUser.getUsername());
|
||||
|
||||
// 新增设备类型记录
|
||||
DeviceAssignments assignments = new DeviceAssignments();
|
||||
assignments.setDeviceId(device.getId());
|
||||
assignments.setAssignedAt(LocalDateTime.now());
|
||||
// 分配者
|
||||
assignments.setAssignerId(currentUser.getId());
|
||||
assignments.setAssignerName(currentUser.getUsername());
|
||||
// 接收者
|
||||
assignments.setAssigneeId(assignUser.getId());
|
||||
// assignments.setAssigneeName(assignUser.getUsername());
|
||||
assignments.setActive(DeviceActiveStatusEnum.ACTIVE.getCode());
|
||||
String lever = assignment.getLever() + ":" + assignUser.getId();
|
||||
assignments.setLever(lever);
|
||||
deviceAssignmentsService.save(assignments);
|
||||
|
||||
// // 获取当前用户的所有祖先用户
|
||||
// List<User> ancestorsById = userMapper.findAncestorsById(currentUser.getId());
|
||||
// Set<Long> excludedTenantIds = new HashSet<>();
|
||||
// if (CollectionUtil.isNotEmpty(ancestorsById)) {
|
||||
// // 提取所有需要排除的 tenant_id
|
||||
// excludedTenantIds = ancestorsById.stream().map(User::getTenantId).distinct().collect(Collectors.toSet());
|
||||
// }
|
||||
// excludedTenantIds.add(currentUser.getTenantId());
|
||||
// // 构建查询条件:device_mac 相同,并且 tenant_id 不在 excludedTenantIds 列表中
|
||||
// Wrapper<Device> wrapper = new QueryWrapper<Device>().eq("device_mac", device.getDeviceMac()).notIn("tenant_id", excludedTenantIds);
|
||||
//
|
||||
// // 构建要更新的数据
|
||||
// Device updateDevice = new Device();
|
||||
// updateDevice.setDeviceStatus(0);
|
||||
// updateDevice.setUpdateTime(new Timestamp(System.currentTimeMillis()));
|
||||
|
||||
// 根据条件批量更新
|
||||
deviceMapper.update(updateDevice, wrapper);
|
||||
// deviceMapper.update(updateDevice, wrapper);
|
||||
|
||||
// 创建并保存设备类型授权记录
|
||||
createAndSaveDeviceTypeGrants(device, currentUser, customerVo, deviceTypeGrants);
|
||||
}
|
||||
|
||||
// 批量分配
|
||||
Set<DeviceType> deviceTypes = new HashSet<>();
|
||||
for (Device device : devices) {
|
||||
device.setId(null);
|
||||
device.setCustomerName(null);
|
||||
device.setCustomerId(null);
|
||||
device.setTenantId(user.getTenantId());
|
||||
device.setCreateTime(timestamp);
|
||||
device.setCreateBy(currentUser.getUsername());
|
||||
device.setUpdateTime(timestamp);
|
||||
this.updateBatchById(devices);
|
||||
|
||||
// 查询设备类型
|
||||
DeviceType deviceType = deviceTypeMapper.selectById(device.getDeviceType());
|
||||
// SnowflakeGenerator snowflakeGenerator = new SnowflakeGenerator();
|
||||
Long id = NanoId.generate(16);
|
||||
deviceType.setId(id);
|
||||
deviceType.setCreateTime(timestamp);
|
||||
deviceType.setCreateBy(currentUser.getUsername());
|
||||
deviceType.setCustomerId(customerVo.getCustomerId());
|
||||
deviceTypes.add(deviceType);
|
||||
deviceTypeGrantsService.saveBatch(deviceTypeGrants);
|
||||
|
||||
device.setDeviceType(deviceType.getId());
|
||||
}
|
||||
this.saveBatch(devices);
|
||||
deviceTypeService.saveBatch(deviceTypes);
|
||||
//
|
||||
// // 批量分配
|
||||
// Set<DeviceType> deviceTypes = new HashSet<>();
|
||||
// for (Device device : devices) {
|
||||
// device.setId(null);
|
||||
// device.setCustomerName(null);
|
||||
// device.setCustomerId(null);
|
||||
// device.setTenantId(user.getTenantId());
|
||||
// device.setCreateTime(timestamp);
|
||||
// device.setCreateBy(currentUser.getUsername());
|
||||
// device.setUpdateTime(timestamp);
|
||||
//
|
||||
// // 查询设备类型
|
||||
// DeviceType deviceType = deviceTypeMapper.selectById(device.getDeviceType());
|
||||
// // SnowflakeGenerator snowflakeGenerator = new SnowflakeGenerator();
|
||||
// Long id = NanoId.generate(NanoIdLengthEnum.HIGH_CONCURRENCY.getLength());
|
||||
// deviceType.setId(id);
|
||||
// deviceType.setCreateTime(timestamp);
|
||||
// deviceType.setCreateBy(currentUser.getUsername());
|
||||
// deviceType.setCustomerId(customerVo.getCustomerId());
|
||||
// deviceTypes.add(deviceType);
|
||||
//
|
||||
// device.setDeviceType(deviceType.getId());
|
||||
// }
|
||||
// this.saveBatch(devices);
|
||||
// deviceTypeService.saveBatch(deviceTypes);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 创建并保存设备类型授权记录
|
||||
*
|
||||
* @param device 当前设备对象
|
||||
* @param currentUser 当前登录用户
|
||||
* @param customerVo 客户信息
|
||||
* @param deviceTypeGrants 授权记录集合
|
||||
*/
|
||||
private void createAndSaveDeviceTypeGrants(Device device, User currentUser, CustomerVo customerVo, List<DeviceTypeGrants> deviceTypeGrants) {
|
||||
Long generatedId = NanoId.generate(NanoIdLengthEnum.HIGH_CONCURRENCY.getLength());
|
||||
DeviceTypeGrants deviceTypeGrant = new DeviceTypeGrants();
|
||||
deviceTypeGrant.setGrantedAt(new Date());
|
||||
deviceTypeGrant.setDeviceTypeId(device.getDeviceType());
|
||||
deviceTypeGrant.setAssignmentId(generatedId);
|
||||
deviceTypeGrant.setCustomerId(customerVo.getCustomerId());
|
||||
deviceTypeGrant.setGrantorCustomerId(currentUser.getId());
|
||||
deviceTypeGrants.add(deviceTypeGrant);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除设备
|
||||
*
|
||||
@ -306,18 +485,17 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void deleteAll(List<Long> ids) {
|
||||
|
||||
SecurityUtils.getCurrentUserId();
|
||||
|
||||
// Step 1: 查询所有传入的设备(根据 ID)
|
||||
List<Device> allDevices = deviceMapper.selectBatchIds(ids);
|
||||
|
||||
// Step 2: 使用 Java Stream 过滤出 customer_id 不为 null 的设备
|
||||
Set<Long> nonNullCustomerIds = allDevices.stream().filter(device -> device.getCustomerId() != null && device.getDeviceStatus() == 1).map(Device::getId).collect(Collectors.toSet());
|
||||
|
||||
// Step 3: 从原始 ids 中“去掉”这些非空 customer_id 的设备 ID
|
||||
List<Long> remainingIds = ids.stream().filter(id -> !nonNullCustomerIds.contains(id)).collect(Collectors.toList());
|
||||
if (CollectionUtil.isEmpty(remainingIds)) {
|
||||
throw new BadRequestException("已分配的设备不允许删除!!!");
|
||||
}
|
||||
|
||||
List<Device> devices = deviceMapper.selectBatchIds(remainingIds);
|
||||
for (Device device : devices) {
|
||||
String devicePic = device.getDevicePic();
|
||||
@ -336,6 +514,58 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
|
||||
deviceMapper.deleteBatchIds(ids);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除设备分配记录(分配记录id)
|
||||
*
|
||||
* @param ids
|
||||
*/
|
||||
public void deleteAssign1(List<Long> ids) {
|
||||
Long currentUserId = SecurityUtils.getCurrentUserId();
|
||||
// Step 1: 查询所有传入的设备(根据 ID)
|
||||
// List<DeviceAssignments> deviceAssignments = deviceAssignmentsMapper.selectBatchIds(ids);
|
||||
QueryWrapper<DeviceAssignments> wrapper = new QueryWrapper<>();
|
||||
// wrapper.eq("active", DeviceActiveStatusEnum.INACTIVE.getCode());
|
||||
wrapper.in("device_id", ids);
|
||||
wrapper.eq("assigner_id", currentUserId);
|
||||
List<DeviceAssignments> deviceAssignments = deviceAssignmentsMapper.selectList(wrapper);
|
||||
// Step 2: 使用 Java Stream 过滤出 customer_id 不为 null 的设备
|
||||
Set<Long> nonNullCustomerIds = deviceAssignments.stream().filter(device -> !StringUtils.isNotEmpty(device.getAssigneeName())).map(DeviceAssignments::getId).collect(Collectors.toSet());
|
||||
if (CollectionUtil.isEmpty(nonNullCustomerIds)) {
|
||||
throw new BadRequestException("已分配的设备不允许删除!!!");
|
||||
}
|
||||
|
||||
// QueryWrapper<DeviceAssignments> de = new QueryWrapper<>();
|
||||
// wrapper.eq("active", DeviceActiveStatusEnum.INACTIVE.getCode());
|
||||
// wrapper.in("device_id", ids);
|
||||
// wrapper.eq("assignee_id", currentUserId);
|
||||
// deviceAssignmentsMapper.delete(de);
|
||||
|
||||
deviceAssignmentsMapper.deleteBatchIds(nonNullCustomerIds);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除设备分配记录(分配记录id)
|
||||
*
|
||||
* @param ids
|
||||
*/
|
||||
@Override
|
||||
public void deleteAssign(List<Long> ids) {
|
||||
// Step 1: 查询所有传入的设备(根据 ID)
|
||||
List<DeviceAssignments> deviceAssignments = deviceAssignmentsMapper.selectBatchIds(ids);
|
||||
// Step 2: 使用 Java Stream 过滤出 customer_id 不为 null 的设备
|
||||
Set<Long> nonNullCustomerIds = deviceAssignments.stream()
|
||||
.filter(device -> !StringUtils.isNotEmpty(device.getAssigneeName()))
|
||||
.map(DeviceAssignments::getId).collect(Collectors.toSet());
|
||||
if (CollectionUtil.isEmpty(nonNullCustomerIds)) {
|
||||
throw new BadRequestException("已分配的设备不允许删除!!!");
|
||||
}
|
||||
|
||||
deviceAssignmentsMapper.deleteBatchIds(ids);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void download(List<Device> all, HttpServletResponse response) throws IOException {
|
||||
List<Map<String, Object>> list = new ArrayList<>();
|
||||
|
||||
@ -0,0 +1,18 @@
|
||||
package com.fuyuanshen.modules.system.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.fuyuanshen.modules.system.domain.DeviceTypeGrants;
|
||||
import com.fuyuanshen.modules.system.mapper.DeviceTypeGrantsMapper;
|
||||
import com.fuyuanshen.modules.system.service.DeviceTypeGrantsService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @author 97433
|
||||
* @description 针对表【device_type_grants】的数据库操作Service实现
|
||||
* @createDate 2025-06-19 13:49:33
|
||||
*/
|
||||
@Service
|
||||
public class DeviceTypeGrantsServiceImpl extends ServiceImpl<DeviceTypeGrantsMapper, DeviceTypeGrants>
|
||||
implements DeviceTypeGrantsService {
|
||||
|
||||
}
|
||||
@ -3,7 +3,10 @@ package com.fuyuanshen.modules.system.service.impl;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.fuyuanshen.modules.system.domain.DeviceTypeGrants;
|
||||
import com.fuyuanshen.modules.system.mapper.DeviceTypeGrantsMapper;
|
||||
import com.fuyuanshen.modules.utils.NanoId;
|
||||
import com.fuyuanshen.utils.enums.NanoIdLengthEnum;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import com.fuyuanshen.modules.security.service.UserCacheManager;
|
||||
import com.fuyuanshen.modules.security.service.dto.JwtUserDto;
|
||||
@ -23,6 +26,7 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
@ -39,6 +43,7 @@ public class DeviceTypeServiceImpl extends ServiceImpl<DeviceTypeMapper, DeviceT
|
||||
private final DeviceTypeMapper deviceTypeMapper;
|
||||
private final UserMapper userMapper;
|
||||
private final UserCacheManager userCacheManager;
|
||||
private final DeviceTypeGrantsMapper deviceTypeGrantsMapper;
|
||||
|
||||
|
||||
/**
|
||||
@ -51,7 +56,7 @@ public class DeviceTypeServiceImpl extends ServiceImpl<DeviceTypeMapper, DeviceT
|
||||
@Override
|
||||
public PageResult<DeviceType> queryAll(DeviceTypeQueryCriteria criteria, Page<Object> page) {
|
||||
JwtUserDto userCache = userCacheManager.getUserCache(SecurityUtils.getCurrentUsername());
|
||||
|
||||
User currentUser = userMapper.findByUsername(SecurityUtils.getCurrentUsername());
|
||||
// 非超级管理员增加数据隔离
|
||||
// if (userCache.getUser().getTenantId() != null && !userCache.getUser().getTenantId().equals(UserConstants.SUPER_ADMIN_ID)) {
|
||||
// List<User> subUsers = userMapper.findUserTree(userCache.getUser().getId());
|
||||
@ -64,11 +69,14 @@ public class DeviceTypeServiceImpl extends ServiceImpl<DeviceTypeMapper, DeviceT
|
||||
// List<User> users = userMapper.findByTenantId(userCache.getUser().getTenantId());
|
||||
// Set<Long> userIds = users.stream().map(User::getId).collect(Collectors.toSet());
|
||||
// criteria.setCustomerId(userIds);
|
||||
// }
|
||||
QueryWrapper<User> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq("username", SecurityUtils.getCurrentUsername());
|
||||
User user = userMapper.selectOne(wrapper);
|
||||
criteria.setCustomerId(user.getId());
|
||||
// 非超级管理员增加数据隔离(只能看到自己创建的设备类型)
|
||||
if (currentUser.getTenantId() != null && !currentUser.getTenantId().equals(UserConstants.SUPER_ADMIN_ID)) {
|
||||
//
|
||||
QueryWrapper<User> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq("username", SecurityUtils.getCurrentUsername());
|
||||
User user = userMapper.selectOne(wrapper);
|
||||
criteria.setCustomerId(user.getId());
|
||||
}
|
||||
|
||||
return PageUtil.toPage(deviceTypeMapper.findAll(criteria, page));
|
||||
}
|
||||
@ -118,9 +126,19 @@ public class DeviceTypeServiceImpl extends ServiceImpl<DeviceTypeMapper, DeviceT
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void create(DeviceType resources) {
|
||||
resources.setId(NanoId.generate(16));
|
||||
Long deviceTypeId = NanoId.generate(NanoIdLengthEnum.HIGH_CONCURRENCY.getLength());
|
||||
resources.setId(deviceTypeId);
|
||||
resources.setCustomerId(SecurityUtils.getCurrentUserId());
|
||||
resources.setOwnerCustomerId(SecurityUtils.getCurrentUserId());
|
||||
deviceTypeMapper.insert(resources);
|
||||
|
||||
// 自动授权给自己
|
||||
DeviceTypeGrants deviceTypeGrants = new DeviceTypeGrants();
|
||||
deviceTypeGrants.setDeviceTypeId(deviceTypeId);
|
||||
deviceTypeGrants.setCustomerId(SecurityUtils.getCurrentUserId());
|
||||
deviceTypeGrants.setGrantorCustomerId(SecurityUtils.getCurrentUserId());
|
||||
deviceTypeGrants.setGrantedAt(new Date());
|
||||
deviceTypeGrantsMapper.insert(deviceTypeGrants);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -19,6 +19,10 @@ import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.fuyuanshen.modules.system.domain.app.APPMenu;
|
||||
import com.fuyuanshen.modules.system.domain.app.APPRole;
|
||||
import com.fuyuanshen.modules.system.domain.app.APPUser;
|
||||
import com.fuyuanshen.modules.system.mapper.*;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import com.fuyuanshen.exception.BadRequestException;
|
||||
import com.fuyuanshen.modules.security.service.UserCacheManager;
|
||||
@ -27,10 +31,6 @@ import com.fuyuanshen.modules.system.domain.Menu;
|
||||
import com.fuyuanshen.modules.system.domain.Role;
|
||||
import com.fuyuanshen.exception.EntityExistException;
|
||||
import com.fuyuanshen.modules.system.domain.User;
|
||||
import com.fuyuanshen.modules.system.mapper.RoleDeptMapper;
|
||||
import com.fuyuanshen.modules.system.mapper.RoleMapper;
|
||||
import com.fuyuanshen.modules.system.mapper.RoleMenuMapper;
|
||||
import com.fuyuanshen.modules.system.mapper.UserMapper;
|
||||
import com.fuyuanshen.modules.system.service.RoleService;
|
||||
import com.fuyuanshen.modules.system.domain.dto.RoleQueryCriteria;
|
||||
import com.fuyuanshen.utils.*;
|
||||
@ -52,6 +52,7 @@ import java.util.stream.Collectors;
|
||||
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {
|
||||
|
||||
private final RoleMapper roleMapper;
|
||||
private final APPRoleMapper appRoleMapper;
|
||||
private final RoleDeptMapper roleDeptMapper;
|
||||
private final RoleMenuMapper roleMenuMapper;
|
||||
private final RedisUtils redisUtils;
|
||||
@ -193,6 +194,26 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements Ro
|
||||
return authorityDtos;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<AuthorityDto> appBuildPermissions(APPUser user) {
|
||||
String key = CacheKey.ROLE_AUTH + user.getId();
|
||||
List<AuthorityDto> authorityDtos = redisUtils.getList(key, AuthorityDto.class);
|
||||
if (CollUtil.isEmpty(authorityDtos)) {
|
||||
Set<String> permissions = new HashSet<>();
|
||||
// 如果是管理员直接返回
|
||||
if (user.getAdmin() == 1) {
|
||||
permissions.add("admin");
|
||||
return permissions.stream().map(AuthorityDto::new).collect(Collectors.toList());
|
||||
}
|
||||
List<APPRole> roles = appRoleMapper.findByUserId(user.getId());
|
||||
permissions = roles.stream().flatMap(role -> role.getMenus().stream()).map(APPMenu::getPermission).filter(StringUtils::isNotBlank).collect(Collectors.toSet());
|
||||
authorityDtos = permissions.stream().map(AuthorityDto::new).collect(Collectors.toList());
|
||||
redisUtils.set(key, authorityDtos, 1, TimeUnit.HOURS);
|
||||
}
|
||||
return authorityDtos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void download(List<Role> roles, HttpServletResponse response) throws IOException {
|
||||
List<Map<String, Object>> list = new ArrayList<>();
|
||||
|
||||
@ -20,6 +20,8 @@ import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.fuyuanshen.modules.system.domain.app.APPUser;
|
||||
import com.fuyuanshen.modules.system.mapper.app.APPUserMapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import com.fuyuanshen.config.properties.FileProperties;
|
||||
import com.fuyuanshen.constants.RoleConstants;
|
||||
@ -69,6 +71,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
private final UserCacheManager userCacheManager;
|
||||
private final OnlineUserService onlineUserService;
|
||||
private final RoleMapper roleMapper;
|
||||
private final APPUserMapper appUserMapper;
|
||||
|
||||
|
||||
@Override
|
||||
@ -428,6 +431,11 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
return userMapper.findByUsername(userName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public APPUser appGetLoginData(String userName) {
|
||||
return appUserMapper.appFindByUsername(userName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updatePass(String username, String pass) {
|
||||
|
||||
@ -15,46 +15,34 @@
|
||||
*/
|
||||
package com.fuyuanshen.modules.system.service.impl.app;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.crypto.digest.MD5;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.fuyuanshen.config.properties.FileProperties;
|
||||
import com.fuyuanshen.constants.RoleConstants;
|
||||
import com.fuyuanshen.constants.DeviceConstants;
|
||||
import com.fuyuanshen.exception.BadRequestException;
|
||||
import com.fuyuanshen.exception.EntityExistException;
|
||||
import com.fuyuanshen.modules.security.service.OnlineUserService;
|
||||
import com.fuyuanshen.modules.security.service.UserCacheManager;
|
||||
import com.fuyuanshen.modules.system.constant.UserConstants;
|
||||
import com.fuyuanshen.modules.system.domain.Job;
|
||||
import com.fuyuanshen.modules.system.domain.Role;
|
||||
import com.fuyuanshen.modules.system.domain.User;
|
||||
import com.fuyuanshen.modules.system.domain.app.APPUser;
|
||||
import com.fuyuanshen.modules.system.domain.dto.UserQueryCriteria;
|
||||
import com.fuyuanshen.modules.system.domain.query.UserQuery;
|
||||
import com.fuyuanshen.modules.system.domain.vo.ConsumerVo;
|
||||
import com.fuyuanshen.modules.system.mapper.RoleMapper;
|
||||
import com.fuyuanshen.modules.system.mapper.UserJobMapper;
|
||||
import com.fuyuanshen.modules.system.mapper.UserMapper;
|
||||
import com.fuyuanshen.modules.system.mapper.UserRoleMapper;
|
||||
import com.fuyuanshen.modules.system.domain.dto.app.APPForgotPasswordDTO;
|
||||
import com.fuyuanshen.modules.system.domain.dto.app.APPUpdateUserDTO;
|
||||
import com.fuyuanshen.modules.system.domain.dto.app.APPUserDTO;
|
||||
import com.fuyuanshen.modules.system.mapper.app.APPUserMapper;
|
||||
import com.fuyuanshen.modules.system.service.UserService;
|
||||
import com.fuyuanshen.modules.system.service.app.APPUserService;
|
||||
import com.fuyuanshen.modules.utils.ResponseVO;
|
||||
import com.fuyuanshen.utils.*;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.fuyuanshen.constants.RedisConstants.*;
|
||||
|
||||
/**
|
||||
* @author Zheng Jie
|
||||
@ -66,7 +54,21 @@ public class APPUserServiceImpl extends ServiceImpl<APPUserMapper, APPUser> impl
|
||||
|
||||
private final APPUserMapper appUserMapper;
|
||||
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
|
||||
@Autowired
|
||||
private final RedisUtils redisUtils;
|
||||
|
||||
@Value("${file.app_avatar.pic}")
|
||||
private String filePath;
|
||||
@Value("${file.app_avatar.ip}")
|
||||
private String ip;
|
||||
|
||||
/**
|
||||
* 文件访问路径前缀
|
||||
*/
|
||||
public static final String FILE_ACCESS_PREFIX = "images";
|
||||
public static final String FILE_AVATAR_PREFIX = "avatar";
|
||||
/**
|
||||
* 查询APP/小程序用户
|
||||
*
|
||||
@ -83,4 +85,110 @@ public class APPUserServiceImpl extends ServiceImpl<APPUserMapper, APPUser> impl
|
||||
return pageResult ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public APPUser getLoginData(String userName) {
|
||||
return appUserMapper.appFindByUsername(userName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseVO<Object> addUser(APPUserDTO user) {
|
||||
|
||||
String username = user.getPhoneNumber();
|
||||
if (appUserMapper.getByUsername(username) != null) {
|
||||
throw new BadRequestException("该手机号已被注册");
|
||||
}
|
||||
|
||||
/* Object verificationCode = redisUtils.get(APP_REGISTER_SMS_TOKEN + username);
|
||||
if (verificationCode == null) {
|
||||
throw new BadRequestException("验证码已过期");
|
||||
}
|
||||
if(!user.getVerificationCode().equals(verificationCode.toString())){
|
||||
throw new BadRequestException("验证码错误");
|
||||
}*/
|
||||
APPUser appUser = new APPUser();
|
||||
appUser.setUsername(user.getPhoneNumber());
|
||||
|
||||
appUser.setPassword(user.getPassword());
|
||||
appUser.setNickName(user.getPhoneNumber());
|
||||
appUser.setUserLevel((byte) 1);
|
||||
appUser.setPhone(Long.valueOf(user.getPhoneNumber()));
|
||||
appUser.setAdmin((byte) 1);
|
||||
appUser.setEnabled(true);
|
||||
appUser.setUserType(0);
|
||||
System.out.println("--------------------"+appUser);
|
||||
|
||||
|
||||
appUserMapper.insert(appUser);
|
||||
return ResponseVO.success("注册成功");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer selectRoleByUserLevel(Set<Role> roles) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forgotPassword(APPForgotPasswordDTO appForgotPasswordDTO) {
|
||||
String phoneNumber = appForgotPasswordDTO.getPhoneNumber();
|
||||
APPUser appUser = appUserMapper.appFindByUsername(phoneNumber);
|
||||
if (appUser == null) {
|
||||
throw new BadRequestException("手机号不存在");
|
||||
}
|
||||
/*Object verificationCode = redisUtils.get(APP_FORGOT_PASSWORD_SMS_TOKEN + phoneNumber);
|
||||
if (verificationCode == null) {
|
||||
throw new BadRequestException("验证码已过期");
|
||||
}
|
||||
if(!appForgotPasswordDTO.getVerificationCode().equals(verificationCode.toString())){
|
||||
throw new BadRequestException("验证码错误");
|
||||
}*/
|
||||
appUser.setPassword(appForgotPasswordDTO.getPassword());
|
||||
appUserMapper.updateById(appUser);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendSms(String phoneNumber) {
|
||||
if (appUserMapper.appFindByUsername(phoneNumber) == null) {
|
||||
throw new BadRequestException("手机号不存在");
|
||||
}
|
||||
// todo 发送验证码
|
||||
|
||||
redisUtils.set(APP_FORGOT_PASSWORD_SMS_TOKEN + phoneNumber, RandomUtil.randomNumbers(4), 5 * 60);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateUser(APPUpdateUserDTO appUser) {
|
||||
APPUser updUser= new APPUser();
|
||||
updUser.setId(appUser.getId());
|
||||
updUser.setNickName(appUser.getNickName());
|
||||
try {
|
||||
updUser.setAvatarPath(saveUserAvatarImage(appUser.getFile()));
|
||||
}catch (IOException e){
|
||||
throw new BadRequestException("上传头像失败");
|
||||
}
|
||||
updUser.setRegion(appUser.getRegion());
|
||||
updUser.setGender(appUser.getGender());
|
||||
appUserMapper.updateById(updUser);
|
||||
}
|
||||
|
||||
private String saveUserAvatarImage(MultipartFile file) throws IOException {
|
||||
if (file == null || file.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String originalFileName = file.getOriginalFilename();
|
||||
String fileExtension = originalFileName.substring(originalFileName.lastIndexOf(".") + 1);
|
||||
String newFileName = "PS_" + RandomUtil.randomNumbers(8) + "." + fileExtension;
|
||||
|
||||
File newFile = new File(filePath + FILE_AVATAR_PREFIX + File.separator + newFileName);
|
||||
|
||||
if (!newFile.getParentFile().exists()) {
|
||||
newFile.getParentFile().mkdirs();
|
||||
}
|
||||
|
||||
file.transferTo(newFile);
|
||||
|
||||
return ip + DeviceConstants.FILE_ACCESS_PREFIX + "/" + FILE_AVATAR_PREFIX + "/" + newFileName;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,18 @@
|
||||
package com.fuyuanshen.modules.system.service.impl.app;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.fuyuanshen.modules.system.domain.app.APPDeviceType;
|
||||
import com.fuyuanshen.modules.system.mapper.app.AppDeviceTypeMapper;
|
||||
import com.fuyuanshen.modules.system.service.app.AppDeviceTypeService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @author 97433
|
||||
* @description 针对表【app_device_type(设备类型表)】的数据库操作Service实现
|
||||
* @createDate 2025-06-24 11:16:18
|
||||
*/
|
||||
@Service
|
||||
public class AppDeviceTypeServiceImpl extends ServiceImpl<AppDeviceTypeMapper, APPDeviceType>
|
||||
implements AppDeviceTypeService {
|
||||
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
package com.fuyuanshen.modules.utils;
|
||||
|
||||
import com.fuyuanshen.constants.ExceptionMessages;
|
||||
import com.fuyuanshen.exception.BadRequestException;
|
||||
import com.fuyuanshen.modules.system.constant.UserConstants;
|
||||
import com.fuyuanshen.modules.system.domain.User;
|
||||
import com.fuyuanshen.modules.system.service.UserService;
|
||||
import com.fuyuanshen.utils.SecurityUtils;
|
||||
|
||||
/**
|
||||
* @author: 默苍璃
|
||||
* @date: 2025-06-2110:35
|
||||
*/
|
||||
|
||||
public class AdminCheckUtil {
|
||||
|
||||
/**
|
||||
* 检查当前用户是否为超级管理员,如果是则抛出异常,防止误操作
|
||||
*
|
||||
* @param userService UserService 用于获取当前用户信息
|
||||
*/
|
||||
public static void preventAdminMisoperation(UserService userService) {
|
||||
User currentUser = userService.findById(SecurityUtils.getCurrentUserId());
|
||||
if (currentUser.getTenantId().equals(UserConstants.SUPER_ADMIN_ID)) {
|
||||
throw new BadRequestException(ExceptionMessages.ADMIN_OPERATION_NOT_ALLOWED);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查用户是否是超级管理员,如果是则抛出异常
|
||||
*
|
||||
* @param user 当前用户对象
|
||||
*/
|
||||
public static void checkIfSuperAdmin(User user) {
|
||||
if (user.getTenantId().equals(UserConstants.SUPER_ADMIN_ID)) {
|
||||
throw new BadRequestException(ExceptionMessages.ADMIN_OPERATION_NOT_ALLOWED);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -4,9 +4,9 @@ spring:
|
||||
druid:
|
||||
db-type: com.alibaba.druid.pool.DruidDataSource
|
||||
driverClassName: com.p6spy.engine.spy.P6SpyDriver
|
||||
url: jdbc:p6spy:mysql://192.168.2.23:3306/eladmin?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
|
||||
url: jdbc:p6spy:mysql://120.79.224.186:3366/eladmin?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
|
||||
username: root
|
||||
password: root
|
||||
password: 1fys@QWER..
|
||||
# 初始连接数,建议设置为与最小空闲连接数相同
|
||||
initial-size: 20
|
||||
# 最小空闲连接数,保持足够的空闲连接以应对请求
|
||||
@ -53,10 +53,10 @@ spring:
|
||||
|
||||
redis:
|
||||
#数据库索引
|
||||
database: ${REDIS_DB:2}
|
||||
host: ${REDIS_HOST:123.207.99.140}
|
||||
port: ${REDIS_PORT:6379}
|
||||
password: ${REDIS_PWD:ccxx11234}
|
||||
database: ${REDIS_DB:0}
|
||||
host: ${REDIS_HOST:120.79.224.186}
|
||||
port: ${REDIS_PORT:26379}
|
||||
password: ${REDIS_PWD:1fys@QWER..}
|
||||
#连接超时时间
|
||||
timeout: 5000
|
||||
# 连接池配置
|
||||
@ -107,6 +107,8 @@ jwt:
|
||||
token-validity-in-seconds: 14400000
|
||||
# 在线用户key
|
||||
online-key: "online_token:"
|
||||
# app在线用户key
|
||||
app_online-key: "app_online_token:"
|
||||
# 验证码
|
||||
code-key: "captcha_code:"
|
||||
# token 续期检查时间范围(默认30分钟,单位毫秒),在token即将过期的一段时间内用户操作了,则给用户的token续期
|
||||
@ -139,7 +141,20 @@ file:
|
||||
device:
|
||||
pic: C:\eladmin\file\ #设备图片存储路径
|
||||
ip: http://fuyuanshen.com:81/ #服务器地址
|
||||
app_avatar:
|
||||
pic: C:\eladmin\file\ #设备图片存储路径
|
||||
#ip: http://fuyuanshen.com:81/ #服务器地址
|
||||
ip: https://fuyuanshen.com/ #服务器地址
|
||||
|
||||
logging:
|
||||
level:
|
||||
com.fuyuanshen: debug
|
||||
# MQTT配置
|
||||
mqtt:
|
||||
username: admin
|
||||
password: fys123456
|
||||
url: tcp://127.0.0.1:1883
|
||||
subClientId: wuLang_subClient_01
|
||||
subTopic: worker/alert/#,worker/location/#
|
||||
pubTopic: worker/location
|
||||
pubClientId: wuLang_pubClient_01
|
||||
@ -151,3 +151,7 @@ file:
|
||||
pic: /home/eladmin/file/ #设备图片存储路径
|
||||
#ip: http://fuyuanshen.com:81/ #服务器地址
|
||||
ip: https://fuyuanshen.com/ #服务器地址
|
||||
app_avatar:
|
||||
pic: /home/eladmin/app_avatar/ #设备图片存储路径
|
||||
#ip: http://fuyuanshen.com:81/ #服务器地址
|
||||
ip: https://fuyuanshen.com/ #服务器地址
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user