forked from dyf/fys-Multi-tenant
Compare commits
43 Commits
d219105b73
...
jingquan
Author | SHA1 | Date | |
---|---|---|---|
36092932bf | |||
78e2538f71 | |||
faef79e56d | |||
7b1615ce4d | |||
171eeabea1 | |||
cc776300ec | |||
04df7e3ec7 | |||
7be94fe1d2 | |||
6f24759361 | |||
530ee83488 | |||
f938716e2d | |||
bbf1c6cfd5 | |||
082f890009 | |||
800b825892 | |||
cfafbc54f7 | |||
fdb64b1dcc | |||
fbbe90207e | |||
2f38f08538 | |||
eb1552d982 | |||
1eb2502a21 | |||
2815e27240 | |||
f119dd158b | |||
a109f187b9 | |||
b5ebc8855d | |||
99aef4b353 | |||
a423ac0f8b | |||
82b1494bc7 | |||
c3b7849190 | |||
33b718c048 | |||
a708889117 | |||
3250dd3f83 | |||
4cc02e1040 | |||
185d521472 | |||
7e688e16b3 | |||
b876d051d8 | |||
d75658e81e | |||
1dc00f0431 | |||
2a6b9eafb3 | |||
f0bfc4aa35 | |||
ff81b791fc | |||
87f2e3a8b5 | |||
c075c09ee7 | |||
3fb692e7fb |
@ -32,7 +32,7 @@ public class AppDeviceController extends BaseController {
|
||||
private final APPDeviceService appDeviceService;
|
||||
|
||||
/**
|
||||
* 查询文件列表
|
||||
* 查询设备列表
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<AppDeviceVo> list(DeviceQueryCriteria bo, PageQuery pageQuery) {
|
||||
|
@ -6,6 +6,7 @@ import com.fuyuanshen.app.domain.vo.AppFileVo;
|
||||
import com.fuyuanshen.app.service.AppFileService;
|
||||
import com.fuyuanshen.common.core.domain.R;
|
||||
import com.fuyuanshen.common.web.core.BaseController;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@ -44,8 +45,8 @@ public class AppFileController extends BaseController {
|
||||
/**
|
||||
* 文件删除
|
||||
*/
|
||||
@DeleteMapping("/delete")
|
||||
public R<Void> delete(Long[] ids) {
|
||||
@DeleteMapping("/delete/{ids}")
|
||||
public R<Void> delete(@NotEmpty(message = "主键不能为空") @PathVariable Long[] ids) {
|
||||
if(ids == null || ids.length == 0){
|
||||
return R.fail("请选择要删除的文件");
|
||||
}
|
||||
|
@ -29,16 +29,16 @@ public class AppOperationVideoController extends BaseController {
|
||||
* 查询操作视频列表
|
||||
*/
|
||||
@GetMapping("/listOperationVideos")
|
||||
public List<AppOperationVideoVo> listOperationVideos(AppOperationVideoBo bo) {
|
||||
return appOperationVideoService.queryList(bo);
|
||||
public R<List<AppOperationVideoVo>> listOperationVideos(AppOperationVideoBo bo) {
|
||||
return R.ok(appOperationVideoService.queryList(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询操作视频详情信息
|
||||
*/
|
||||
@GetMapping("/getOperationVideoInfo")
|
||||
public AppOperationVideoVo getOperationVideoInfo(AppOperationVideoBo bo) {
|
||||
return appOperationVideoService.queryById(bo.getId());
|
||||
public R<AppOperationVideoVo> getOperationVideoInfo(AppOperationVideoBo bo) {
|
||||
return R.ok(appOperationVideoService.queryById(bo.getId()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -64,8 +64,8 @@ public class AppOperationVideoController extends BaseController {
|
||||
/**
|
||||
* 操作视频删除
|
||||
*/
|
||||
@DeleteMapping("/deleteOperationVideo")
|
||||
public R<Void> deleteOperationVideo(Long[] ids) {
|
||||
return toAjax(appOperationVideoService.deleteWithValidByIds(List.of(ids), true));
|
||||
@DeleteMapping("/deleteOperationVideo/{id}")
|
||||
public R<Void> deleteOperationVideo(@PathVariable Long id) {
|
||||
return toAjax(appOperationVideoService.deleteWithValidByIds(List.of(id), true));
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,6 @@ public class AppFileDto {
|
||||
/**
|
||||
* 文件
|
||||
*/
|
||||
private MultipartFile file;
|
||||
private MultipartFile[] files;
|
||||
|
||||
}
|
||||
|
@ -22,4 +22,5 @@ public class AppSmsLoginBody {
|
||||
*/
|
||||
@NotBlank(message = "租户ID不能为空")
|
||||
private String tenantId;
|
||||
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import com.fuyuanshen.app.domain.bo.AppBusinessFileBo;
|
||||
import com.fuyuanshen.app.domain.dto.AppFileDto;
|
||||
import com.fuyuanshen.app.domain.vo.AppBusinessFileVo;
|
||||
import com.fuyuanshen.app.domain.vo.AppFileVo;
|
||||
import com.fuyuanshen.common.core.exception.ServiceException;
|
||||
import com.fuyuanshen.common.oss.core.OssClient;
|
||||
import com.fuyuanshen.common.oss.factory.OssFactory;
|
||||
import com.fuyuanshen.common.satoken.utils.AppLoginHelper;
|
||||
@ -12,6 +13,7 @@ import com.fuyuanshen.system.service.ISysOssService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -36,20 +38,32 @@ public class AppFileService {
|
||||
|
||||
public Boolean add(AppFileDto bo) {
|
||||
|
||||
// 上传文件
|
||||
SysOssVo upload = sysOssService.upload(bo.getFile());
|
||||
MultipartFile[] files = bo.getFiles();
|
||||
if(files == null || files.length == 0){
|
||||
throw new ServiceException("请选择要上传的文件");
|
||||
}
|
||||
if(files.length > 5){
|
||||
throw new ServiceException("最多只能上传5个文件");
|
||||
}
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
MultipartFile file = files[i];
|
||||
// 上传文件
|
||||
SysOssVo upload = sysOssService.upload(file);
|
||||
|
||||
if (upload == null) {
|
||||
return false;
|
||||
if (upload == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
AppBusinessFileBo appBusinessFileBo = new AppBusinessFileBo();
|
||||
appBusinessFileBo.setFileId(upload.getOssId());
|
||||
appBusinessFileBo.setBusinessId(bo.getDeviceId());
|
||||
appBusinessFileBo.setFileType(bo.getFileType());
|
||||
appBusinessFileBo.setCreateBy(AppLoginHelper.getUserId());
|
||||
appBusinessFileService.insertByBo(appBusinessFileBo);
|
||||
}
|
||||
|
||||
AppBusinessFileBo appBusinessFileBo = new AppBusinessFileBo();
|
||||
appBusinessFileBo.setFileId(upload.getOssId());
|
||||
appBusinessFileBo.setBusinessId(bo.getDeviceId());
|
||||
appBusinessFileBo.setFileType(bo.getFileType());
|
||||
appBusinessFileBo.setCreateBy(AppLoginHelper.getUserId());
|
||||
|
||||
return appBusinessFileService.insertByBo(appBusinessFileBo);
|
||||
return true;
|
||||
}
|
||||
|
||||
public Boolean delete(Long[] ids) {
|
||||
|
@ -0,0 +1,102 @@
|
||||
package com.fuyuanshen.mp.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaIgnore;
|
||||
import cn.dev33.satoken.exception.NotLoginException;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.fuyuanshen.app.model.AppSmsLoginBody;
|
||||
import com.fuyuanshen.app.service.AppLoginService;
|
||||
import com.fuyuanshen.common.core.constant.SystemConstants;
|
||||
import com.fuyuanshen.common.core.domain.R;
|
||||
import com.fuyuanshen.common.core.domain.model.AppLoginUser;
|
||||
import com.fuyuanshen.common.core.domain.model.LoginUser;
|
||||
import com.fuyuanshen.common.core.domain.model.RegisterBody;
|
||||
import com.fuyuanshen.common.core.domain.model.SmsLoginBody;
|
||||
import com.fuyuanshen.common.core.utils.*;
|
||||
import com.fuyuanshen.common.encrypt.annotation.ApiEncrypt;
|
||||
import com.fuyuanshen.common.json.utils.JsonUtils;
|
||||
import com.fuyuanshen.common.satoken.utils.LoginHelper;
|
||||
import com.fuyuanshen.common.tenant.helper.TenantHelper;
|
||||
import com.fuyuanshen.equipment.domain.UserApp;
|
||||
import com.fuyuanshen.equipment.enums.AppUserTypeEnum;
|
||||
import com.fuyuanshen.mp.domian.dto.AuthUserDto;
|
||||
import com.fuyuanshen.mp.service.MPAuthService;
|
||||
import com.fuyuanshen.mp.service.MPService;
|
||||
import com.fuyuanshen.system.domain.bo.SysTenantBo;
|
||||
import com.fuyuanshen.system.domain.vo.SysClientVo;
|
||||
import com.fuyuanshen.system.domain.vo.SysTenantVo;
|
||||
import com.fuyuanshen.system.domain.vo.SysUserVo;
|
||||
import com.fuyuanshen.system.service.ISysClientService;
|
||||
import com.fuyuanshen.system.service.ISysConfigService;
|
||||
import com.fuyuanshen.system.service.ISysTenantService;
|
||||
import com.fuyuanshen.web.domain.vo.LoginTenantVo;
|
||||
import com.fuyuanshen.web.domain.vo.LoginVo;
|
||||
import com.fuyuanshen.web.domain.vo.TenantListVo;
|
||||
import com.fuyuanshen.web.service.IAuthStrategy;
|
||||
import com.fuyuanshen.web.service.SysRegisterService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.sms4j.api.SmsBlend;
|
||||
import org.dromara.sms4j.api.entity.SmsResponse;
|
||||
import org.dromara.sms4j.core.factory.SmsFactory;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* APP认证
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@Slf4j
|
||||
@SaIgnore
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/mp")
|
||||
public class MPAuthController {
|
||||
|
||||
private final AppLoginService loginService;
|
||||
private final SysRegisterService registerService;
|
||||
private final ISysConfigService configService;
|
||||
private final ISysTenantService tenantService;
|
||||
private final ISysClientService clientService;
|
||||
private final MPAuthService mpAuthService;
|
||||
private final MPService mpService;
|
||||
|
||||
|
||||
@Operation(summary = "小程序登录授权")
|
||||
@PostMapping(value = "/login")
|
||||
public ResponseEntity<Object> login(@RequestBody AuthUserDto authUser, HttpServletRequest request) throws Exception {
|
||||
|
||||
Long phoneNumber = authUser.getPhoneNumber();
|
||||
// 判断小程序用户是否存在,不存在创建
|
||||
UserApp mpUser = mpService.getMpUser(phoneNumber);
|
||||
if (mpUser == null) {
|
||||
RegisterBody registerBody = new RegisterBody();
|
||||
registerBody.setUsername(phoneNumber.toString());
|
||||
registerBody.setUserType(AppUserTypeEnum.XCX_USER.getCode());
|
||||
registerBody.setTenantId("894078");
|
||||
registerBody.setPassword("123456");
|
||||
mpAuthService.register(registerBody);
|
||||
}
|
||||
|
||||
// 去登录
|
||||
SysClientVo client = clientService.queryByClientId("ca839698e245d60aa2f0e59bd52b34f8");
|
||||
UserApp user = mpService.loadUserByUsername(phoneNumber.toString());
|
||||
LoginUser loginUser = mpAuthService.buildLoginUser(user);
|
||||
LoginVo login = mpAuthService.login(loginUser, client);
|
||||
|
||||
// 返回登录信息
|
||||
return ResponseEntity.ok(login);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package com.fuyuanshen.mp.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaIgnore;
|
||||
import com.fuyuanshen.common.core.domain.ResponseVO;
|
||||
import com.fuyuanshen.equipment.service.DeviceService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @author: 默苍璃
|
||||
* @date: 2025-07-1208:36
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/mp")
|
||||
@RequiredArgsConstructor
|
||||
@Tag(name = "小程序:相关接口")
|
||||
@SaIgnore
|
||||
public class MPController {
|
||||
|
||||
private final DeviceService deviceService;
|
||||
|
||||
|
||||
@GetMapping("/queryDevice")
|
||||
@Operation(summary = "检查是否存在设备MAC号")
|
||||
public ResponseVO<Boolean> queryDevice(@Parameter(name = "设备mac值") String mac) {
|
||||
return ResponseVO.success(deviceService.queryDevice(mac));
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.mp.domian.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
|
||||
/**
|
||||
* @author Zheng Jie
|
||||
* @date 2018-11-30
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class AuthUserDto {
|
||||
|
||||
@Schema(name = "用户名")
|
||||
private String username;
|
||||
|
||||
@Schema(name = "手机号(APP/小程序 登录)")
|
||||
private Long phoneNumber;
|
||||
|
||||
@Schema(name = "密码")
|
||||
private String password;
|
||||
|
||||
@Schema(name = "验证码")
|
||||
private String code;
|
||||
|
||||
@Schema(name = "验证码的key")
|
||||
private String uuid = "";
|
||||
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package com.fuyuanshen.mp.mapper;
|
||||
|
||||
/**
|
||||
* @author: 默苍璃
|
||||
* @date: 2025-07-1210:16
|
||||
*/
|
||||
public interface MPMapper {
|
||||
}
|
@ -0,0 +1,164 @@
|
||||
package com.fuyuanshen.mp.service;
|
||||
|
||||
import cn.dev33.satoken.exception.NotLoginException;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.lang.Opt;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.crypto.digest.BCrypt;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.fuyuanshen.app.domain.vo.AppUserVo;
|
||||
import com.fuyuanshen.app.service.IAppRoleService;
|
||||
import com.fuyuanshen.common.core.constant.Constants;
|
||||
import com.fuyuanshen.common.core.constant.SystemConstants;
|
||||
import com.fuyuanshen.common.core.constant.TenantConstants;
|
||||
import com.fuyuanshen.common.core.domain.dto.PostDTO;
|
||||
import com.fuyuanshen.common.core.domain.dto.RoleDTO;
|
||||
import com.fuyuanshen.common.core.domain.model.AppLoginUser;
|
||||
import com.fuyuanshen.common.core.domain.model.LoginUser;
|
||||
import com.fuyuanshen.common.core.domain.model.PasswordLoginBody;
|
||||
import com.fuyuanshen.common.core.domain.model.RegisterBody;
|
||||
import com.fuyuanshen.common.core.enums.LoginType;
|
||||
import com.fuyuanshen.common.core.enums.UserType;
|
||||
import com.fuyuanshen.common.core.exception.user.UserException;
|
||||
import com.fuyuanshen.common.core.utils.*;
|
||||
import com.fuyuanshen.common.json.utils.JsonUtils;
|
||||
import com.fuyuanshen.common.log.event.LogininforEvent;
|
||||
import com.fuyuanshen.common.redis.utils.RedisUtils;
|
||||
import com.fuyuanshen.common.satoken.utils.AppLoginHelper;
|
||||
import com.fuyuanshen.common.satoken.utils.LoginHelper;
|
||||
import com.fuyuanshen.common.tenant.exception.TenantException;
|
||||
import com.fuyuanshen.common.tenant.helper.TenantHelper;
|
||||
import com.fuyuanshen.equipment.domain.Device;
|
||||
import com.fuyuanshen.equipment.domain.UserApp;
|
||||
import com.fuyuanshen.equipment.service.AppUserService;
|
||||
import com.fuyuanshen.system.domain.SysUser;
|
||||
import com.fuyuanshen.system.domain.bo.SysUserBo;
|
||||
import com.fuyuanshen.system.domain.vo.*;
|
||||
import com.fuyuanshen.system.service.ISysTenantService;
|
||||
import com.fuyuanshen.system.service.ISysUserService;
|
||||
import com.fuyuanshen.web.domain.vo.LoginVo;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.*;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* 登录校验方法
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
@Service
|
||||
public class MPAuthService {
|
||||
|
||||
private final ISysUserService userService;
|
||||
private final AppUserService appUserService;
|
||||
|
||||
/**
|
||||
* 小程序注册
|
||||
*/
|
||||
public void register(RegisterBody registerBody) {
|
||||
String tenantId = registerBody.getTenantId();
|
||||
String username = registerBody.getUsername();
|
||||
String password = registerBody.getPassword();
|
||||
// 校验用户类型是否存在
|
||||
String userType = UserType.getUserType(registerBody.getUserType()).getUserType();
|
||||
|
||||
UserApp sysUser = new UserApp();
|
||||
sysUser.setUserName(username);
|
||||
sysUser.setNickName(username);
|
||||
sysUser.setPhonenumber(username);
|
||||
sysUser.setTenantId(tenantId);
|
||||
sysUser.setUserType(registerBody.getUserType());
|
||||
sysUser.setPassword(BCrypt.hashpw(password));
|
||||
sysUser.setUserType(userType);
|
||||
|
||||
appUserService.saveMpUser(sysUser);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 记录登录信息
|
||||
*
|
||||
* @param tenantId 租户ID
|
||||
* @param username 用户名
|
||||
* @param status 状态
|
||||
* @param message 消息内容
|
||||
* @return
|
||||
*/
|
||||
private void recordLogininfor(String tenantId, String username, String status, String message) {
|
||||
LogininforEvent logininforEvent = new LogininforEvent();
|
||||
logininforEvent.setTenantId(tenantId);
|
||||
logininforEvent.setUsername(username);
|
||||
logininforEvent.setStatus(status);
|
||||
logininforEvent.setMessage(message);
|
||||
logininforEvent.setRequest(ServletUtils.getRequest());
|
||||
// com.fuyuanshen.web.listener.UserActionListener
|
||||
SpringUtils.context().publishEvent(logininforEvent);
|
||||
}
|
||||
|
||||
|
||||
public LoginVo login(LoginUser loginUser, SysClientVo client) {
|
||||
loginUser.setClientKey(client.getClientKey());
|
||||
loginUser.setDeviceType(client.getDeviceType());
|
||||
SaLoginParameter model = new SaLoginParameter();
|
||||
model.setDeviceType(client.getDeviceType());
|
||||
// 自定义分配 不同用户体系 不同 token 授权时间 不设置默认走全局 yml 配置
|
||||
// 例如: 后台用户30分钟过期 app用户1天过期
|
||||
model.setTimeout(client.getTimeout());
|
||||
model.setActiveTimeout(client.getActiveTimeout());
|
||||
model.setExtra(LoginHelper.CLIENT_KEY, client.getClientId());
|
||||
// 生成token
|
||||
LoginHelper.login(loginUser, model);
|
||||
|
||||
LoginVo loginVo = new LoginVo();
|
||||
loginVo.setAccessToken(StpUtil.getTokenValue());
|
||||
loginVo.setExpireIn(StpUtil.getTokenTimeout());
|
||||
loginVo.setClientId(client.getClientId());
|
||||
return loginVo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建登录用户
|
||||
*/
|
||||
public LoginUser buildLoginUser(UserApp user) {
|
||||
LoginUser loginUser = new LoginUser();
|
||||
Long userId = user.getUserId();
|
||||
loginUser.setTenantId(user.getTenantId());
|
||||
loginUser.setUserId(userId);
|
||||
loginUser.setDeptId(user.getDeptId());
|
||||
loginUser.setUsername(user.getUserName());
|
||||
loginUser.setNickname(user.getNickName());
|
||||
loginUser.setUserType(user.getUserType());
|
||||
// 用户级别
|
||||
// loginUser.setUserLevel(user.getUserLevel());
|
||||
// pid
|
||||
// loginUser.setPid(user.getPid());
|
||||
|
||||
// loginUser.setMenuPermission(permissionService.getMenuPermission(userId));
|
||||
// loginUser.setRolePermission(permissionService.getRolePermission(userId));
|
||||
// if (ObjectUtil.isNotNull(user.getDeptId())) {
|
||||
// Opt<SysDeptVo> deptOpt = Opt.of(user.getDeptId()).map(deptService::selectDeptById);
|
||||
// loginUser.setDeptName(deptOpt.map(SysDeptVo::getDeptName).orElse(StringUtils.EMPTY));
|
||||
// loginUser.setDeptCategory(deptOpt.map(SysDeptVo::getDeptCategory).orElse(StringUtils.EMPTY));
|
||||
// }
|
||||
// List<SysRoleVo> roles = roleService.selectRolesByUserId(userId);
|
||||
// // List<SysPostVo> posts = postService.selectPostsByUserId(userId);
|
||||
// loginUser.setRoles(BeanUtil.copyToList(roles, RoleDTO.class));
|
||||
// loginUser.setPosts(BeanUtil.copyToList(posts, PostDTO.class));
|
||||
return loginUser;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.fuyuanshen.mp.service;
|
||||
|
||||
import com.fuyuanshen.equipment.domain.UserApp;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 登录校验方法
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
|
||||
|
||||
public interface MPService {
|
||||
|
||||
|
||||
/**
|
||||
* 获取小程序用户信息
|
||||
*
|
||||
* @param phoneNumber 手机号
|
||||
*/
|
||||
UserApp getMpUser(Long phoneNumber);
|
||||
|
||||
UserApp loadUserByUsername(String username);
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package com.fuyuanshen.mp.service.impl;
|
||||
|
||||
/**
|
||||
* 登录校验方法
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
|
||||
public class MPAuthServiceImpl {
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package com.fuyuanshen.mp.service.impl;
|
||||
|
||||
import com.fuyuanshen.equipment.domain.UserApp;
|
||||
import com.fuyuanshen.equipment.mapper.UserAppMapper;
|
||||
import com.fuyuanshen.equipment.service.AppUserService;
|
||||
import com.fuyuanshen.mp.service.MPService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 登录校验方法
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class MPServiceImpl implements MPService {
|
||||
|
||||
|
||||
private final AppUserService appUserService;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取小程序用户信息
|
||||
*
|
||||
* @param phoneNumber 手机号
|
||||
*/
|
||||
@Override
|
||||
public UserApp getMpUser(Long phoneNumber) {
|
||||
return appUserService.getMpUser(phoneNumber);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserApp loadUserByUsername(String username) {
|
||||
return appUserService.loadUserByUsername(username);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -111,6 +111,7 @@ public class AuthController {
|
||||
return R.ok(loginVo);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取跳转URL
|
||||
*
|
||||
@ -133,6 +134,7 @@ public class AuthController {
|
||||
return R.ok("操作成功", authorizeUrl);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 前端回调绑定授权(需要token)
|
||||
*
|
||||
|
@ -14,12 +14,10 @@ import com.fuyuanshen.common.core.constant.SystemConstants;
|
||||
import com.fuyuanshen.common.core.domain.model.AppLoginUser;
|
||||
import com.fuyuanshen.common.core.domain.model.SmsLoginBody;
|
||||
import com.fuyuanshen.common.core.enums.LoginType;
|
||||
import com.fuyuanshen.common.core.enums.UserType;
|
||||
import com.fuyuanshen.common.core.exception.user.CaptchaExpireException;
|
||||
import com.fuyuanshen.common.core.exception.user.UserException;
|
||||
import com.fuyuanshen.common.core.utils.MessageUtils;
|
||||
import com.fuyuanshen.common.core.utils.ServletUtils;
|
||||
import com.fuyuanshen.common.core.utils.StringUtils;
|
||||
import com.fuyuanshen.common.core.utils.ValidatorUtils;
|
||||
import com.fuyuanshen.common.core.utils.*;
|
||||
import com.fuyuanshen.common.json.utils.JsonUtils;
|
||||
import com.fuyuanshen.common.redis.utils.RedisUtils;
|
||||
import com.fuyuanshen.common.satoken.utils.AppLoginHelper;
|
||||
@ -60,9 +58,9 @@ public class AppSmsAuthStrategy implements IAuthStrategy {
|
||||
AppUserVo user = loadUserByPhonenumber(phonenumber);
|
||||
if (ObjectUtil.isNull(user)) {
|
||||
//新增Appuser
|
||||
addAppUser(tenantId, phonenumber);
|
||||
|
||||
user = appUserMapper.selectVoOne(new LambdaQueryWrapper<AppUser>().eq(AppUser::getPhonenumber, phonenumber));
|
||||
AppUser appUser = addAppUser(tenantId, phonenumber);
|
||||
MapstructUtils.convert(appUser, user);
|
||||
// user = appUserMapper.selectVoOne(new LambdaQueryWrapper<AppUser>().eq(AppUser::getPhonenumber, phonenumber));
|
||||
// loginService.recordLogininfor(tenantId, phonenumber, Constants.LOGIN_FAIL, MessageUtils.message("user.not.exists", phonenumber));
|
||||
// throw new UserException("user.not.exists", phonenumber);
|
||||
}
|
||||
@ -89,7 +87,7 @@ public class AppSmsAuthStrategy implements IAuthStrategy {
|
||||
return loginVo;
|
||||
}
|
||||
|
||||
private void addAppUser(String tenantId, String phonenumber) {
|
||||
private AppUser addAppUser(String tenantId, String phonenumber) {
|
||||
AppUser appUser = new AppUser();
|
||||
appUser.setPhonenumber(phonenumber);
|
||||
appUser.setUserName(phonenumber);
|
||||
@ -98,6 +96,7 @@ public class AppSmsAuthStrategy implements IAuthStrategy {
|
||||
appUser.setLoginIp(ServletUtils.getClientIP());
|
||||
appUser.setTenantId(tenantId);
|
||||
appUserMapper.insert(appUser);
|
||||
return appUser;
|
||||
}
|
||||
|
||||
|
||||
@ -114,7 +113,9 @@ public class AppSmsAuthStrategy implements IAuthStrategy {
|
||||
}
|
||||
|
||||
private AppUserVo loadUserByPhonenumber(String phonenumber) {
|
||||
AppUserVo user = appUserMapper.selectVoOne(new LambdaQueryWrapper<AppUser>().eq(AppUser::getPhonenumber, phonenumber));
|
||||
AppUserVo user = appUserMapper.selectVoOne(new LambdaQueryWrapper<AppUser>()
|
||||
.eq(AppUser::getPhonenumber, phonenumber)
|
||||
.eq(AppUser::getUserType, UserType.APP_USER.getUserType()));
|
||||
if (ObjectUtil.isNull(user)) {
|
||||
log.info("登录用户:{} 不存在.", phonenumber);
|
||||
// throw new UserException("user.not.exists", phonenumber);
|
||||
@ -126,5 +127,4 @@ public class AppSmsAuthStrategy implements IAuthStrategy {
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -52,9 +52,9 @@ spring:
|
||||
driverClassName: com.mysql.cj.jdbc.Driver
|
||||
# jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562
|
||||
# rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题)
|
||||
url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
|
||||
url: jdbc:mysql://localhost:3306/fys_vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
|
||||
username: root
|
||||
password: root
|
||||
password: Jz_5623_cl1
|
||||
# # 从库数据源
|
||||
# slave:
|
||||
# lazy: true
|
||||
@ -105,9 +105,9 @@ spring.data:
|
||||
# 端口,默认为6379
|
||||
port: 6379
|
||||
# 数据库索引
|
||||
database: 0
|
||||
database: 1
|
||||
# redis 密码必须配置
|
||||
password: fys123
|
||||
password: re_fs_11520631
|
||||
# 连接超时时间
|
||||
timeout: 10s
|
||||
# 是否开启ssl
|
||||
@ -272,3 +272,37 @@ justauth:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: ${justauth.address}/social-callback?source=gitea
|
||||
|
||||
|
||||
# MQTT配置
|
||||
mqtt:
|
||||
username: admin
|
||||
password: #YtvpSfCNG
|
||||
url: tcp://47.120.79.150:2883
|
||||
subClientId: fys_subClient
|
||||
subTopic: worker/alert/#,worker/location/#
|
||||
pubTopic: worker/location
|
||||
pubClientId: fys_pubClient
|
||||
|
||||
|
||||
# 文件存储路径
|
||||
file:
|
||||
mac:
|
||||
path: ~/file/
|
||||
avatar: ~/avatar/
|
||||
linux:
|
||||
path: /home/eladmin/file/
|
||||
avatar: /home/eladmin/avatar/
|
||||
windows:
|
||||
path: C:\eladmin\file\
|
||||
avatar: C:\eladmin\avatar\
|
||||
# 文件大小 /M
|
||||
maxSize: 100
|
||||
avatarMaxSize: 5
|
||||
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/ #服务器地址
|
@ -1,7 +1,7 @@
|
||||
# 开发环境配置
|
||||
server:
|
||||
# 服务器的HTTP端口,默认为8080
|
||||
port: 8001
|
||||
port: 8000
|
||||
servlet:
|
||||
# 应用的访问路径
|
||||
context-path: /
|
||||
|
@ -21,7 +21,13 @@ public enum UserType {
|
||||
/**
|
||||
* 移动客户端用户
|
||||
*/
|
||||
APP_USER("app_user");
|
||||
APP_USER("app_user"),
|
||||
|
||||
/**
|
||||
* 小程序 用户
|
||||
*/
|
||||
XCX_USER("xcx_user");
|
||||
|
||||
|
||||
/**
|
||||
* 用户类型标识(用于 token、权限识别等)
|
||||
|
@ -37,7 +37,7 @@ public enum BusinessType {
|
||||
EXPORT,
|
||||
|
||||
/**
|
||||
* 导入
|
||||
*
|
||||
*/
|
||||
IMPORT,
|
||||
|
||||
|
@ -17,8 +17,8 @@ public class TestSMSController {
|
||||
public void testSend() {
|
||||
// 在创建完SmsBlend实例后,再未手动调用注销的情况下框架会持有该实例,可以直接通过指定configId来获取想要的配置,如果你想使用
|
||||
// 负载均衡形式获取实例,只要使用getSmsBlend的无参重载方法即可,如果你仅有一个配置,也可以使用该方法
|
||||
SmsBlend smsBlend = SmsFactory.getSmsBlend("alibaba");
|
||||
SmsResponse smsResponse = smsBlend.sendMessage("18656573389", "123");
|
||||
SmsBlend smsBlend = SmsFactory.getSmsBlend("config1");
|
||||
SmsResponse smsResponse = smsBlend.sendMessage("18656573389", "1234");
|
||||
}
|
||||
|
||||
}
|
@ -2,6 +2,7 @@ package com.fuyuanshen.app.controller;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.fuyuanshen.common.core.enums.UserType;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.*;
|
||||
@ -36,12 +37,14 @@ public class AppUserController extends BaseController {
|
||||
|
||||
private final IAppUserService appUserService;
|
||||
|
||||
|
||||
/**
|
||||
* 查询APP用户信息列表
|
||||
*/
|
||||
// @SaCheckPermission("app:user:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<AppUserVo> list(AppUserBo bo, PageQuery pageQuery) {
|
||||
bo.setUserType(UserType.APP_USER.getUserType());
|
||||
return appUserService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
|
@ -6,8 +6,20 @@ import com.fuyuanshen.app.domain.APPDeviceType;
|
||||
import com.fuyuanshen.app.domain.dto.APPUnbindDTO;
|
||||
import com.fuyuanshen.app.domain.query.APPDeviceQueryCriteria;
|
||||
import com.fuyuanshen.app.service.equipment.APPDeviceService;
|
||||
import com.fuyuanshen.common.core.domain.R;
|
||||
import com.fuyuanshen.common.core.domain.ResponseVO;
|
||||
import com.fuyuanshen.common.core.validate.EditGroup;
|
||||
import com.fuyuanshen.common.idempotent.annotation.RepeatSubmit;
|
||||
import com.fuyuanshen.common.log.annotation.Log;
|
||||
import com.fuyuanshen.common.log.enums.BusinessType;
|
||||
import com.fuyuanshen.common.mybatis.core.page.PageQuery;
|
||||
import com.fuyuanshen.common.mybatis.core.page.TableDataInfo;
|
||||
import com.fuyuanshen.common.web.core.BaseController;
|
||||
import com.fuyuanshen.equipment.domain.bo.UserAppBo;
|
||||
import com.fuyuanshen.equipment.domain.query.DeviceQueryCriteria;
|
||||
import com.fuyuanshen.equipment.domain.vo.AppDeviceVo;
|
||||
import com.fuyuanshen.equipment.service.AppUserService;
|
||||
import com.fuyuanshen.equipment.service.DeviceService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@ -27,9 +39,11 @@ import java.util.List;
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/api/app/device")
|
||||
public class APPDeviceController {
|
||||
public class APPDeviceController extends BaseController {
|
||||
|
||||
private final APPDeviceService appDeviceService;
|
||||
private final AppUserService appUserService;
|
||||
private final DeviceService deviceService;
|
||||
|
||||
|
||||
@PostMapping(value = "/list")
|
||||
@ -59,21 +73,41 @@ public class APPDeviceController {
|
||||
|
||||
@GetMapping
|
||||
@Operation(summary = "WEB端查看APP客户设备绑定")
|
||||
public TableDataInfo<APPDevice> queryAPPDevice(APPDeviceQueryCriteria criteria) {
|
||||
Page<APPDevice> page = new Page<>(criteria.getPage(), criteria.getSize());
|
||||
TableDataInfo<APPDevice> devices = null;
|
||||
devices = appDeviceService.queryAll(page, criteria);
|
||||
return devices;
|
||||
public TableDataInfo<AppDeviceVo> queryAPPDevice(DeviceQueryCriteria bo, PageQuery pageQuery) {
|
||||
return deviceService.queryAppDeviceList(bo, pageQuery);
|
||||
}
|
||||
|
||||
|
||||
@PostMapping(value = "/unbind")
|
||||
// @PostMapping(value = "/unbind")
|
||||
// @Operation(summary = "设备解绑")
|
||||
// public ResponseVO<String> unbindAPPDevice(@Validated @ModelAttribute APPUnbindDTO deviceForm) {
|
||||
// appDeviceService.unbindAPPDevice(deviceForm);
|
||||
// return ResponseVO.success("解绑成功!!!");
|
||||
// }
|
||||
|
||||
/**
|
||||
* app设备解绑
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "设备解绑")
|
||||
public ResponseVO<String> unbindAPPDevice(@Validated @ModelAttribute APPUnbindDTO deviceForm) {
|
||||
appDeviceService.unbindAPPDevice(deviceForm);
|
||||
return ResponseVO.success("解绑成功!!!");
|
||||
@DeleteMapping("/unBind")
|
||||
public R<Void> unBind(Long id) {
|
||||
return toAjax(deviceService.unBindDevice(id));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 修改APP用户信息
|
||||
*/
|
||||
// @SaCheckPermission("app:user:edit")
|
||||
@Log(title = "APP用户信息", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping()
|
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody UserAppBo bo) {
|
||||
return toAjax(appUserService.updateByBo(bo));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,75 @@
|
||||
// package com.fuyuanshen.app.controller.mp;
|
||||
//
|
||||
// import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
// import lombok.RequiredArgsConstructor;
|
||||
// import lombok.extern.slf4j.Slf4j;
|
||||
// import org.springframework.http.ResponseEntity;
|
||||
// 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 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
|
||||
// @Tag(name = "小程序:相关接口")
|
||||
// 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));
|
||||
// // }
|
||||
//
|
||||
//
|
||||
// }
|
@ -6,6 +6,11 @@ import lombok.Data;
|
||||
public class AppFileVo {
|
||||
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 业务id
|
||||
*/
|
||||
private String businessId;
|
||||
/**
|
||||
* 文件id
|
||||
*/
|
||||
|
@ -1,6 +1,9 @@
|
||||
package com.fuyuanshen.app.domain.vo;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fuyuanshen.app.domain.AppUser;
|
||||
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
|
||||
@ -120,4 +123,10 @@ public class AppUserVo implements Serializable {
|
||||
* 部门ID
|
||||
*/
|
||||
private Long deptId;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import com.fuyuanshen.app.domain.dto.APPUnbindDTO;
|
||||
import com.fuyuanshen.app.domain.query.APPDeviceQueryCriteria;
|
||||
import com.fuyuanshen.app.domain.vo.APPDeviceTypeVo;
|
||||
import com.fuyuanshen.common.mybatis.core.page.TableDataInfo;
|
||||
import com.fuyuanshen.equipment.domain.query.DeviceQueryCriteria;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -62,4 +63,14 @@ public interface APPDeviceService extends IService<APPDevice> {
|
||||
List<APPDeviceTypeVo> getTypeList();
|
||||
|
||||
void reName(APPReNameDTO reNameDTO);
|
||||
|
||||
/**
|
||||
* WEB端查看APP客户设备绑定
|
||||
*
|
||||
* @param criteria
|
||||
* @return
|
||||
*/
|
||||
TableDataInfo<APPDevice> queryAppDeviceList(DeviceQueryCriteria criteria);
|
||||
|
||||
|
||||
}
|
||||
|
@ -23,6 +23,8 @@ import com.fuyuanshen.common.satoken.utils.AppLoginHelper;
|
||||
import com.fuyuanshen.common.satoken.utils.LoginHelper;
|
||||
import com.fuyuanshen.equipment.domain.Device;
|
||||
import com.fuyuanshen.equipment.domain.DeviceType;
|
||||
import com.fuyuanshen.equipment.domain.query.DeviceQueryCriteria;
|
||||
import com.fuyuanshen.equipment.domain.vo.AppDeviceVo;
|
||||
import com.fuyuanshen.equipment.enums.BindingStatusEnum;
|
||||
import com.fuyuanshen.equipment.enums.CommunicationModeEnum;
|
||||
import com.fuyuanshen.equipment.mapper.DeviceMapper;
|
||||
@ -210,4 +212,20 @@ public class APPDeviceServiceImpl extends ServiceImpl<APPDeviceMapper, APPDevice
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* WEB端查看APP客户设备绑定
|
||||
*
|
||||
* @param criteria
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<APPDevice> queryAppDeviceList(DeviceQueryCriteria criteria) {
|
||||
|
||||
// Page<AppDeviceVo> result = baseMapper.queryAppDeviceList(pageQuery.build(), bo);
|
||||
// return TableDataInfo.build(result);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -5,16 +5,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<mapper namespace="com.fuyuanshen.app.mapper.AppBusinessFileMapper">
|
||||
|
||||
<select id="queryAppFileList" resultType="com.fuyuanshen.app.domain.vo.AppFileVo">
|
||||
select a.business_id id,a.file_id,b.file_name,b.url fileUrl from app_business_file a left join sys_oss b on a.file_id = b.oss_id
|
||||
where
|
||||
select a.id,a.business_id,a.file_id,b.file_name,b.url fileUrl from app_business_file a left join sys_oss b on a.file_id = b.oss_id
|
||||
where 1=1
|
||||
<if test="businessId != null">
|
||||
and a.business_id = #{businessId}
|
||||
</if>
|
||||
<if test="fileId != null">
|
||||
and a.file_id = #{fileId}
|
||||
</if>
|
||||
<if test="fileType != null">
|
||||
and a.file_type = #{fileType}
|
||||
</if>
|
||||
<if test="createBy != null">
|
||||
a.create_by = #{createBy}
|
||||
and a.create_by = #{createBy}
|
||||
</if>
|
||||
order by a.create_time desc
|
||||
</select>
|
||||
|
@ -79,17 +79,19 @@
|
||||
<if test="criteria.createTime != null and criteria.createTime.size() != 0">
|
||||
and d.create_time between #{criteria.createTime[0]} and #{criteria.createTime[1]}
|
||||
</if>
|
||||
<if test="criteria.tenantId != null">
|
||||
AND tenant_id = #{criteria.tenantId}
|
||||
</if>
|
||||
and d.customer_id = #{criteria.customerId}
|
||||
</where>
|
||||
order by d.create_time desc
|
||||
</select>
|
||||
|
||||
<select id="getTypeList" resultType="com.fuyuanshen.app.domain.vo.APPDeviceTypeVo">
|
||||
SELECT dt.id, dt.type_name, dt.communication_mode FROM device_type dt
|
||||
WHERE EXISTS(select 1 from device d where d.device_type = dt.id and d.binding_user_id = #{userId} AND d.binding_status = 1 )
|
||||
SELECT dt.id, dt.type_name, dt.communication_mode
|
||||
FROM device_type dt
|
||||
WHERE EXISTS(select 1
|
||||
from device d
|
||||
where d.device_type = dt.id
|
||||
and d.binding_user_id = #{userId}
|
||||
AND d.binding_status = 1)
|
||||
</select>
|
||||
|
||||
|
||||
|
@ -3,6 +3,7 @@ package com.fuyuanshen.customer.controller;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.crypto.digest.BCrypt;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.fuyuanshen.common.core.domain.R;
|
||||
import com.fuyuanshen.common.core.domain.ResponseVO;
|
||||
import com.fuyuanshen.common.core.utils.StringUtils;
|
||||
import com.fuyuanshen.common.mybatis.core.page.TableDataInfo;
|
||||
@ -51,43 +52,43 @@ public class CustomerController {
|
||||
|
||||
@GetMapping(value = "/allCustomer")
|
||||
@Operation(summary = "查询所有客户")
|
||||
public ResponseVO<List<Customer>> queryAllCustomer(UserQueryCriteria criteria) {
|
||||
public R<List<Customer>> queryAllCustomer(UserQueryCriteria criteria) {
|
||||
List<Customer> customers = customerService.queryAllCustomers(criteria);
|
||||
return ResponseVO.success(customers);
|
||||
return R.ok(customers);
|
||||
}
|
||||
|
||||
|
||||
// @Log("新增客户")
|
||||
@Operation(summary = "新增客户")
|
||||
@PostMapping(value = "/addCustomer")
|
||||
public ResponseVO<Object> addCustomer(@Validated @RequestBody Customer customer) throws BadRequestException {
|
||||
public R<Void> addCustomer(@Validated @RequestBody Customer customer) throws BadRequestException {
|
||||
if (StringUtils.isBlank(customer.getPassword())) {
|
||||
throw new BadRequestException("账号密码不能为空");
|
||||
}
|
||||
customer.setPassword(BCrypt.hashpw(customer.getPassword()));
|
||||
customerService.addCustomer(customer);
|
||||
return ResponseVO.success("新增客户成功!!!");
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
|
||||
// @Log("修改客户")
|
||||
@Operation(summary = "修改客户")
|
||||
@PutMapping(value = "updateCustomer")
|
||||
public ResponseVO<Object> updateCustomer(@RequestBody Customer resources) throws Exception {
|
||||
public R<Void> updateCustomer(@RequestBody Customer resources) throws Exception {
|
||||
customerService.updateCustomer(resources);
|
||||
return ResponseVO.success(null);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
|
||||
// @Log("删除客户")
|
||||
@Operation(summary = "删除客户")
|
||||
@DeleteMapping(value = "/deleteCustomer")
|
||||
public ResponseVO<Object> deleteCustomer(@RequestBody Set<Long> ids) throws BadRequestException {
|
||||
public R<Void> deleteCustomer(@RequestBody Set<Long> ids) throws BadRequestException {
|
||||
if (CollectionUtil.isEmpty(ids)) {
|
||||
throw new BadRequestException("请选择要删除的客户");
|
||||
}
|
||||
customerService.delete(ids);
|
||||
return ResponseVO.success(null);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
|
||||
|
@ -103,6 +103,11 @@
|
||||
<artifactId>fys-common-websocket</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>javacv-platform</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
@ -0,0 +1,244 @@
|
||||
package com.fuyuanshen.demo.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaIgnore;
|
||||
import com.fuyuanshen.common.core.domain.R;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.bytedeco.javacv.FFmpegFrameGrabber;
|
||||
import org.bytedeco.javacv.Frame;
|
||||
import org.bytedeco.javacv.Java2DFrameUtils;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/video")
|
||||
public class VideoUploadController {
|
||||
|
||||
// 可配置项:建议从 application.yml 中读取
|
||||
private static final int MAX_VIDEO_SIZE = 10 * 1024 * 1024; // 10 MB
|
||||
private static final int FRAME_RATE = 15; // 每秒抽15帧
|
||||
private static final int DURATION = 2; // 抽2秒
|
||||
private static final int TOTAL_FRAMES = FRAME_RATE * DURATION;
|
||||
private static final int WIDTH = 160;
|
||||
private static final int HEIGHT = 80;
|
||||
private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
|
||||
|
||||
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||
@SaIgnore
|
||||
public R<List<String>> upload(@RequestParam("file") MultipartFile file) {
|
||||
if (file == null || file.isEmpty()) {
|
||||
return R.fail("上传文件不能为空");
|
||||
}
|
||||
|
||||
if (!isVideo(file.getOriginalFilename())) {
|
||||
return R.fail("只允许上传视频文件");
|
||||
}
|
||||
|
||||
if (file.getSize() > MAX_VIDEO_SIZE) {
|
||||
return R.fail("视频大小不能超过10MB");
|
||||
}
|
||||
|
||||
File tempFile = null;
|
||||
try {
|
||||
// 创建临时文件保存上传的视频
|
||||
tempFile = createTempVideoFile(file);
|
||||
|
||||
|
||||
List<BufferedImage> frames = extractFramesFromVideo(tempFile);
|
||||
if (frames.isEmpty()) {
|
||||
return R.fail("无法提取任何帧");
|
||||
}
|
||||
|
||||
// ✅ 新增:保存帧为图片
|
||||
//saveFramesToLocal(frames, "extracted_frame");
|
||||
|
||||
byte[] binaryData = convertFramesToRGB565(frames);
|
||||
// String base64Data = Base64.getEncoder().encodeToString(binaryData);
|
||||
//
|
||||
// return R.ok(base64Data);
|
||||
// 构造响应头
|
||||
// 将二进制数据转为 Hex 字符串
|
||||
// 转换为 Hex 字符串列表
|
||||
List<String> hexList = bytesToHexList(binaryData);
|
||||
|
||||
return R.ok(hexList);
|
||||
|
||||
} catch (Exception e) {
|
||||
return R.fail("视频处理失败:" + e.getMessage());
|
||||
} finally {
|
||||
deleteTempFile(tempFile);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* rgb565 转 hex
|
||||
*/
|
||||
private List<String> bytesToHexList(byte[] bytes) {
|
||||
List<String> hexList = new ArrayList<>();
|
||||
for (byte b : bytes) {
|
||||
int value = b & 0xFF;
|
||||
char high = HEX_ARRAY[value >>> 4];
|
||||
char low = HEX_ARRAY[value & 0x0F];
|
||||
hexList.add(String.valueOf(high) + low);
|
||||
}
|
||||
return hexList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建临时文件并保存上传的视频
|
||||
*/
|
||||
private File createTempVideoFile(MultipartFile file) throws Exception {
|
||||
File tempFile = Files.createTempFile("upload-", ".mp4").toFile();
|
||||
file.transferTo(tempFile);
|
||||
return tempFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从视频中按时间均匀提取指定数量的帧
|
||||
*/
|
||||
private List<BufferedImage> extractFramesFromVideo(File videoFile) throws Exception {
|
||||
List<BufferedImage> frames = new ArrayList<>();
|
||||
|
||||
try (FFmpegFrameGrabber grabber = FFmpegFrameGrabber.createDefault(videoFile)) {
|
||||
grabber.start();
|
||||
|
||||
// 获取视频总帧数和帧率
|
||||
long totalFramesInVideo = grabber.getLengthInFrames();
|
||||
int fps = (int) Math.round(grabber.getFrameRate());
|
||||
if (fps <= 0) fps = 30;
|
||||
|
||||
double durationSeconds = (double) totalFramesInVideo / fps;
|
||||
|
||||
if (durationSeconds < DURATION) {
|
||||
throw new IllegalArgumentException("视频太短,至少需要 " + DURATION + " 秒");
|
||||
}
|
||||
|
||||
// 计算每帧之间的间隔(浮点以实现更精确跳转)
|
||||
double frameInterval = (double) totalFramesInVideo / TOTAL_FRAMES;
|
||||
|
||||
for (int i = 0; i < TOTAL_FRAMES; i++) {
|
||||
int targetFrameNumber = (int) Math.round(i * frameInterval);
|
||||
|
||||
// 避免设置无效帧号
|
||||
if (targetFrameNumber >= totalFramesInVideo) {
|
||||
throw new IllegalArgumentException("目标帧超出范围: " + targetFrameNumber + " ");
|
||||
}
|
||||
|
||||
grabber.setFrameNumber(targetFrameNumber);
|
||||
Frame frame = grabber.grab();
|
||||
|
||||
if (frame != null && frame.image != null) {
|
||||
BufferedImage bufferedImage = Java2DFrameUtils.toBufferedImage(frame);
|
||||
frames.add(cropImage(bufferedImage, WIDTH, HEIGHT));
|
||||
} else {
|
||||
throw new IllegalArgumentException("无法获取第 " + targetFrameNumber + "帧 ");
|
||||
}
|
||||
}
|
||||
|
||||
grabber.stop();
|
||||
}
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将抽取的帧保存到本地,用于调试
|
||||
*/
|
||||
private void saveFramesToLocal(List<BufferedImage> frames, String prefix) {
|
||||
// 指定输出目录
|
||||
File outputDir = new File("output_frames");
|
||||
if (!outputDir.exists()) {
|
||||
outputDir.mkdirs();
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
for (BufferedImage frame : frames) {
|
||||
try {
|
||||
File outputImage = new File(outputDir, prefix + "_" + (index++) + ".png");
|
||||
ImageIO.write(frame, "png", outputImage);
|
||||
System.out.println("保存帧图片成功: " + outputImage.getAbsolutePath());
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException("保存帧图片失败 " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将所有帧转换为 RGB565 格式字节数组
|
||||
*/
|
||||
private byte[] convertFramesToRGB565(List<BufferedImage> frames) throws Exception {
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
|
||||
for (BufferedImage image : frames) {
|
||||
byte[] rgb565Bytes = convertToRGB565(image);
|
||||
byteArrayOutputStream.write(rgb565Bytes);
|
||||
}
|
||||
|
||||
return byteArrayOutputStream.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否是支持的视频格式
|
||||
*/
|
||||
private boolean isVideo(String filename) {
|
||||
String ext = filename.substring(filename.lastIndexOf('.')).toLowerCase();
|
||||
return Arrays.asList(".mp4", ".avi", ".mov", ".mkv").contains(ext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 裁剪图像到目标尺寸
|
||||
*/
|
||||
private BufferedImage cropImage(BufferedImage img, int targetWidth, int targetHeight) {
|
||||
int w = Math.min(img.getWidth(), targetWidth);
|
||||
int h = Math.min(img.getHeight(), targetHeight);
|
||||
return img.getSubimage(0, 0, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 BufferedImage 转换为 RGB565 格式的字节数组
|
||||
*/
|
||||
private byte[] convertToRGB565(BufferedImage image) {
|
||||
int width = image.getWidth();
|
||||
int height = image.getHeight();
|
||||
byte[] result = new byte[width * height * 2]; // RGB565: 2 bytes per pixel
|
||||
int index = 0;
|
||||
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
int rgb = image.getRGB(x, y);
|
||||
int r = ((rgb >> 16) & 0xFF) >> 3;
|
||||
int g = ((rgb >> 8) & 0xFF) >> 2;
|
||||
int b = (rgb & 0xFF) >> 3;
|
||||
short pixel = (short) ((r << 11) | (g << 5) | b);
|
||||
|
||||
result[index++] = (byte) (pixel >> 8); // High byte first
|
||||
result[index++] = (byte) pixel;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除临时文件
|
||||
*/
|
||||
private void deleteTempFile(File file) {
|
||||
if (file != null && file.exists()) {
|
||||
if (!file.delete()) {
|
||||
throw new IllegalArgumentException("无法删除临时文件: " + file.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -27,7 +27,7 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
@Tag(name = "设备管理", description = "设备:设备管理")
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/api/app/device")
|
||||
@RequestMapping("/api/app/device1")
|
||||
public class DeviceAPPController extends BaseController {
|
||||
|
||||
private final AppUserService appUserService;
|
||||
@ -44,6 +44,11 @@ public class DeviceAPPController extends BaseController {
|
||||
return toAjax(appUserService.updateByBo(bo));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -4,11 +4,13 @@ package com.fuyuanshen.equipment.controller;
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.fuyuanshen.common.core.constant.ResponseMessageConstants;
|
||||
import com.fuyuanshen.common.core.domain.R;
|
||||
import com.fuyuanshen.common.core.domain.ResponseVO;
|
||||
import com.fuyuanshen.common.core.domain.model.LoginUser;
|
||||
import com.fuyuanshen.common.core.utils.file.FileUtil;
|
||||
import com.fuyuanshen.common.mybatis.core.page.TableDataInfo;
|
||||
import com.fuyuanshen.common.satoken.utils.LoginHelper;
|
||||
import com.fuyuanshen.common.web.core.BaseController;
|
||||
import com.fuyuanshen.customer.mapper.CustomerMapper;
|
||||
import com.fuyuanshen.equipment.domain.Device;
|
||||
import com.fuyuanshen.equipment.domain.dto.DeviceExcelImportDTO;
|
||||
@ -21,6 +23,7 @@ import com.fuyuanshen.equipment.excel.UploadDeviceDataListener;
|
||||
import com.fuyuanshen.equipment.mapper.DeviceMapper;
|
||||
import com.fuyuanshen.equipment.mapper.DeviceTypeMapper;
|
||||
import com.fuyuanshen.equipment.service.DeviceService;
|
||||
import com.fuyuanshen.equipment.service.DeviceTypeService;
|
||||
import com.fuyuanshen.equipment.service.impl.DeviceExportService;
|
||||
import com.fuyuanshen.system.service.ISysOssService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
@ -48,12 +51,13 @@ import java.util.List;
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/api/device")
|
||||
public class DeviceController {
|
||||
public class DeviceController extends BaseController {
|
||||
|
||||
private final ISysOssService ossService;
|
||||
private final DeviceService deviceService;
|
||||
private final DeviceMapper deviceMapper;
|
||||
private final CustomerMapper customerMapper;
|
||||
private final DeviceTypeService deviceTypeService;
|
||||
private final DeviceTypeMapper deviceTypeMapper;
|
||||
|
||||
private final DeviceExportService exportService;
|
||||
@ -70,106 +74,106 @@ public class DeviceController {
|
||||
// @Log("新增设备")
|
||||
@Operation(summary = "新增设备")
|
||||
@PostMapping(value = "/add")
|
||||
public ResponseVO<Object> addDevice(@Validated @ModelAttribute DeviceForm deviceForm) {
|
||||
public R<Void> addDevice(@Validated @ModelAttribute DeviceForm deviceForm) {
|
||||
try {
|
||||
deviceService.addDevice(deviceForm);
|
||||
} catch (Exception e) {
|
||||
log.error("addDevice error: " + e.getMessage());
|
||||
return ResponseVO.fail(e.getMessage());
|
||||
return R.fail(e.getMessage());
|
||||
}
|
||||
return ResponseVO.success(null);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
|
||||
// @Log("修改设备")
|
||||
@Operation(summary = "修改设备")
|
||||
@PutMapping(value = "/update")
|
||||
public ResponseVO<Object> updateDevice(@Validated @ModelAttribute DeviceForm deviceForm) {
|
||||
public R<Void> updateDevice(@Validated @ModelAttribute DeviceForm deviceForm) {
|
||||
try {
|
||||
deviceService.update(deviceForm);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
log.error("updateDevice error: " + e.getMessage());
|
||||
return ResponseVO.fail("出错了");
|
||||
return R.fail(e.getMessage());
|
||||
}
|
||||
return ResponseVO.success(null);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
|
||||
@Operation(summary = "设备详情")
|
||||
@GetMapping(value = "/detail/{id}")
|
||||
public ResponseVO<Object> getDevice(@PathVariable Long id) {
|
||||
public R<Device> getDevice(@PathVariable Long id) {
|
||||
Device device = deviceService.getById(id);
|
||||
return ResponseVO.success(device);
|
||||
return R.ok(device);
|
||||
}
|
||||
|
||||
|
||||
// @Log("删除设备")
|
||||
@Operation(summary = "删除设备")
|
||||
@DeleteMapping(value = "/delete")
|
||||
public ResponseVO<Object> deleteDevice(@Parameter(name = "传ID数组[]") @RequestBody List<Long> ids) {
|
||||
public R<Void> deleteDevice(@Parameter(name = "传ID数组[]") @RequestBody List<Long> ids) {
|
||||
deviceService.deleteAll(ids);
|
||||
return ResponseVO.success(ResponseMessageConstants.DELETE_SUCCESS);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
|
||||
@Operation(summary = "设备定位")
|
||||
@GetMapping(value = "/locateDevice")
|
||||
public ResponseVO<Object> locateDevice(DeviceQueryCriteria criteria) throws IOException {
|
||||
public R<List<Device>> locateDevice(DeviceQueryCriteria criteria) throws IOException {
|
||||
List<Device> devices = deviceService.queryAllDevices(criteria);
|
||||
return ResponseVO.success(devices);
|
||||
return R.ok(devices);
|
||||
}
|
||||
|
||||
|
||||
// @Log("分配客户")
|
||||
@Operation(summary = "分配客户")
|
||||
@PutMapping(value = "/assignCustomer")
|
||||
public ResponseVO<Object> assignCustomer(@Validated @RequestBody CustomerVo customerVo) {
|
||||
public R<Void> assignCustomer(@Validated @RequestBody CustomerVo customerVo) {
|
||||
deviceService.assignCustomer(customerVo);
|
||||
return ResponseVO.success(null);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
|
||||
// @Log("撤回设备")
|
||||
@Operation(summary = "撤回分配设备")
|
||||
@PostMapping(value = "/withdraw")
|
||||
public ResponseVO<Object> withdrawDevice(@RequestBody List<Long> ids) {
|
||||
public R<Void> withdrawDevice(@RequestBody List<Long> ids) {
|
||||
try {
|
||||
deviceService.withdrawDevice(ids);
|
||||
} catch (Exception e) {
|
||||
log.error("updateDevice error: " + e.getMessage());
|
||||
return ResponseVO.fail("出错了");
|
||||
return R.fail(e.getMessage());
|
||||
}
|
||||
return ResponseVO.success(null);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param deviceForm
|
||||
* @param id
|
||||
* @return
|
||||
* @ModelAttribute 主要用于将请求参数绑定到 Java 对象上,它会从 HTTP 请求的查询参数(Query Parameters)
|
||||
* 或表单数据(Form Data)中提取值,并自动填充到指定的对象属性中。
|
||||
*/
|
||||
// @Log("解绑设备")
|
||||
@Operation(summary = "解绑设备")
|
||||
@PostMapping(value = "/unbind")
|
||||
public ResponseVO<Object> unbindDevice(@Validated @ModelAttribute DeviceForm deviceForm) {
|
||||
deviceService.unbindDevice(deviceForm);
|
||||
return ResponseVO.success("解绑成功!!!");
|
||||
@Operation(summary = "WEB端解绑设备")
|
||||
@GetMapping(value = "/unbind")
|
||||
public R<Void> unbindDevice(@Validated Long id) {
|
||||
return toAjax(deviceService.webUnBindDevice(id));
|
||||
}
|
||||
|
||||
|
||||
@Operation(summary = "导出数据设备")
|
||||
@GetMapping(value = "/download")
|
||||
public void exportDevice(HttpServletResponse response, DeviceQueryCriteria criteria) throws IOException {
|
||||
public R<Void> exportDevice(HttpServletResponse response, DeviceQueryCriteria criteria) throws IOException {
|
||||
List<Device> devices = deviceService.queryAll(criteria);
|
||||
exportService.export(devices, response);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
|
||||
@Operation(summary = "导入设备数据")
|
||||
@PostMapping(value = "/import", consumes = "multipart/form-data")
|
||||
public ResponseVO<ImportResult> importData(@Parameter(name = "文件", required = true) @RequestPart("file") MultipartFile file) throws BadRequestException {
|
||||
public R<ImportResult> importData(@Parameter(name = "文件", required = true) @RequestPart("file") MultipartFile file) throws BadRequestException {
|
||||
|
||||
String suffix = FileUtil.getExtensionName(file.getOriginalFilename());
|
||||
if (!("xlsx".equalsIgnoreCase(suffix))) {
|
||||
@ -179,7 +183,11 @@ public class DeviceController {
|
||||
ImportResult result = new ImportResult();
|
||||
try {
|
||||
LoginUser loginUser = LoginHelper.getLoginUser();
|
||||
DeviceImportParams params = DeviceImportParams.builder().ossService(ossService).deviceService(deviceService).tenantId(loginUser.getTenantId()).file(file).filePath("").deviceMapper(deviceMapper).deviceTypeMapper(deviceTypeMapper).userId(loginUser.getUserId()).customerMapper(customerMapper).build();
|
||||
DeviceImportParams params = DeviceImportParams.builder().ossService(ossService)
|
||||
.deviceService(deviceService).tenantId(loginUser.getTenantId())
|
||||
.file(file).filePath("").deviceMapper(deviceMapper).deviceTypeService(deviceTypeService)
|
||||
.deviceTypeMapper(deviceTypeMapper).userId(loginUser.getUserId())
|
||||
.customerMapper(customerMapper).build();
|
||||
// 创建监听器
|
||||
UploadDeviceDataListener listener = new UploadDeviceDataListener(params);
|
||||
// 读取Excel
|
||||
@ -189,13 +197,13 @@ public class DeviceController {
|
||||
// 设置响应消息
|
||||
String message = String.format("成功导入 %d 条数据,失败 %d 条", result.getSuccessCount(), result.getFailureCount());
|
||||
// 返回带有正确泛型的响应
|
||||
return ResponseVO.<ImportResult>success(message, result);
|
||||
return R.ok(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);
|
||||
return R.fail(errorMessage, result);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.fuyuanshen.equipment.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.fuyuanshen.common.core.domain.R;
|
||||
import com.fuyuanshen.common.core.domain.ResponseVO;
|
||||
import com.fuyuanshen.common.mybatis.core.page.TableDataInfo;
|
||||
import com.fuyuanshen.equipment.domain.DeviceType;
|
||||
@ -40,43 +41,45 @@ public class DeviceTypeController {
|
||||
|
||||
@GetMapping(value = "/all")
|
||||
@Operation(summary = "查询所有设备类型")
|
||||
public ResponseVO<Object> queryDeviceTypes() {
|
||||
public R<List<DeviceType>> queryDeviceTypes() {
|
||||
List<DeviceType> deviceTypes = deviceTypeService.queryDeviceTypes();
|
||||
return ResponseVO.success(deviceTypes);
|
||||
return R.ok(deviceTypes);
|
||||
}
|
||||
|
||||
|
||||
// @Log("新增设备类型")
|
||||
@Operation(summary = "新增设备类型")
|
||||
@PostMapping(value = "/add")
|
||||
public ResponseVO<Object> createDeviceType(@Validated @RequestBody DeviceType resources) {
|
||||
public R<Void> createDeviceType(@Validated @RequestBody DeviceType resources) {
|
||||
deviceTypeService.create(resources);
|
||||
return ResponseVO.success(null);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
|
||||
// @Log("修改设备类型")
|
||||
@Operation(summary = "修改设备类型")
|
||||
@PutMapping(value = "/update")
|
||||
public ResponseVO<Object> updateDeviceType(@Validated @RequestBody DeviceTypeForm resources) {
|
||||
public R<Void> updateDeviceType(@Validated @RequestBody DeviceTypeForm resources) {
|
||||
deviceTypeService.update(resources);
|
||||
return ResponseVO.success(null);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
|
||||
// @Log("删除设备类型")
|
||||
@Operation(summary = "删除设备类型")
|
||||
@DeleteMapping(value = "/delete")
|
||||
public ResponseVO<Object> deleteDeviceType(@Parameter(name = "传ID数组[]") @RequestBody List<Long> ids) {
|
||||
public R<Void> deleteDeviceType(@Parameter(name = "传ID数组[]") @RequestBody List<Long> ids) {
|
||||
deviceTypeService.deleteAll(ids);
|
||||
return ResponseVO.success("删除成功!!!");
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
|
||||
@GetMapping(value = "/communicationMode")
|
||||
@Operation(summary = "获取设备类型通讯方式")
|
||||
public ResponseVO<DeviceType> getCommunicationMode(@Parameter(name = "设备类型ID", required = true) Long id) {
|
||||
return ResponseVO.success(deviceTypeService.getCommunicationMode(id));
|
||||
public R<DeviceType> getCommunicationMode(@Parameter(name = "设备类型ID", required = true) Long id) {
|
||||
DeviceType communicationMode = deviceTypeService.getCommunicationMode(id);
|
||||
return R.ok(communicationMode);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,106 @@
|
||||
package com.fuyuanshen.equipment.domain;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.bean.copier.CopyOptions;
|
||||
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.common.tenant.core.TenantEntity;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Description: 设备表
|
||||
* @Author: WY
|
||||
* @Date: 2025/5/16
|
||||
**/
|
||||
@Data
|
||||
@TableName("app_device")
|
||||
public class APPDevice1 extends TenantEntity {
|
||||
|
||||
@TableId(value = "app_device_id", type = IdType.AUTO)
|
||||
@Schema(name = "ID")
|
||||
private Long id;
|
||||
|
||||
@Schema(name = "设备类型")
|
||||
private Long deviceType;
|
||||
|
||||
@Schema(name = "设备类型名称")
|
||||
private String deviceTypeName;
|
||||
|
||||
@Schema(name = "客户号")
|
||||
private Long customerId;
|
||||
|
||||
@Schema(name = "所属客户")
|
||||
private String customerName;
|
||||
|
||||
/*@Schema(name = "设备编号")
|
||||
private String deviceNo;*/
|
||||
|
||||
@Schema(name = "设备名称")
|
||||
private String deviceName;
|
||||
|
||||
@Schema(name = "设备图片")
|
||||
private String devicePic;
|
||||
|
||||
@Schema(name = "设备MAC")
|
||||
private String deviceMac;
|
||||
|
||||
@Schema(name = "设备IMEI")
|
||||
private String deviceImei;
|
||||
|
||||
@Schema(name = "设备SN")
|
||||
private String deviceSn;
|
||||
|
||||
@Schema(name = "经度")
|
||||
private String longitude;
|
||||
|
||||
@Schema(name = "纬度")
|
||||
private String latitude;
|
||||
|
||||
@Schema(name = "备注")
|
||||
private String remark;
|
||||
|
||||
@TableField(exist = false)
|
||||
@Schema(name = "设备类型名称")
|
||||
private String typeName;
|
||||
|
||||
/**
|
||||
* 租户ID
|
||||
*/
|
||||
@TableField(value = "tenant_id")
|
||||
@Schema(hidden = true)
|
||||
private String tenantId;
|
||||
|
||||
/**
|
||||
* 设备状态
|
||||
* 0 失效
|
||||
* 1 正常
|
||||
*/
|
||||
@Schema(name = "设备状态")
|
||||
private Integer deviceStatus;
|
||||
|
||||
/**
|
||||
* 绑定状态
|
||||
* 0 未绑定
|
||||
* 1 已绑定
|
||||
*/
|
||||
@Schema(name = "绑定状态")
|
||||
private Integer bindingStatus;
|
||||
|
||||
/**
|
||||
* 绑定类型
|
||||
* 0 APP
|
||||
* 1 小程序
|
||||
*/
|
||||
@Schema(name = "绑定类型")
|
||||
private Integer bindingType;
|
||||
|
||||
|
||||
public void copy(APPDevice1 source) {
|
||||
BeanUtil.copyProperties(source, this, CopyOptions.create().setIgnoreNullValue(true));
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -9,6 +9,8 @@ import com.fuyuanshen.common.tenant.core.TenantEntity;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @Description: 设备表
|
||||
* @Author: WY
|
||||
@ -59,7 +61,7 @@ public class Device extends TenantEntity {
|
||||
@Schema(name = "原始设备")
|
||||
private Long originalDeviceId;
|
||||
|
||||
@Schema( name = "设备编号")
|
||||
@Schema(name = "设备编号")
|
||||
private String deviceNo;
|
||||
|
||||
@Schema(name = "设备名称")
|
||||
@ -71,6 +73,9 @@ public class Device extends TenantEntity {
|
||||
@Schema(name = "设备MAC")
|
||||
private String deviceMac;
|
||||
|
||||
@Schema(name = "蓝牙名称")
|
||||
private String bluetoothName;
|
||||
|
||||
@Schema(name = "设备IMEI")
|
||||
private String deviceImei;
|
||||
|
||||
@ -94,6 +99,9 @@ public class Device extends TenantEntity {
|
||||
@Schema(name = "设备状态")
|
||||
private Integer deviceStatus;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 绑定状态
|
||||
* 0 未绑定
|
||||
@ -108,4 +116,6 @@ public class Device extends TenantEntity {
|
||||
private String createByName;
|
||||
|
||||
private Long bindingUserId;
|
||||
|
||||
private Date bindingTime;
|
||||
}
|
||||
|
@ -30,6 +30,11 @@ public class UserApp extends TenantEntity {
|
||||
@TableId(value = "user_id")
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 部门ID
|
||||
*/
|
||||
private Long deptId;
|
||||
|
||||
/**
|
||||
* 用户账号
|
||||
*/
|
||||
@ -42,6 +47,7 @@ public class UserApp extends TenantEntity {
|
||||
|
||||
/**
|
||||
* 用户类型(app_user系统用户)
|
||||
* 用户类型(app_user手机端,xcx_user小程序)
|
||||
*/
|
||||
private String userType;
|
||||
|
||||
|
@ -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.fuyuanshen.equipment.converter.IgnoreFailedImageConverter;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.net.URL;
|
||||
@ -42,6 +43,10 @@ public class DeviceExcelExportDTO {
|
||||
@ColumnWidth(20)
|
||||
private String deviceMac;
|
||||
|
||||
@ExcelProperty("蓝牙名称")
|
||||
@ColumnWidth(20)
|
||||
private String bluetoothName;
|
||||
|
||||
@ExcelProperty("设备IMEI")
|
||||
@ColumnWidth(20)
|
||||
private String deviceImei;
|
||||
|
@ -40,6 +40,10 @@ public class DeviceForm {
|
||||
@Schema(title = "设备MAC")
|
||||
private String deviceMac;
|
||||
|
||||
@Schema(name = "蓝牙名称")
|
||||
private String bluetoothName;
|
||||
|
||||
|
||||
@Schema(title = "设备IMEI")
|
||||
private String deviceImei;
|
||||
|
||||
|
@ -0,0 +1,65 @@
|
||||
package com.fuyuanshen.equipment.domain.query;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @Description:
|
||||
* @Author: WY
|
||||
* @Date: 2025/5/16
|
||||
**/
|
||||
@Data
|
||||
public class APPDeviceQueryCriteria1 {
|
||||
|
||||
@Schema(name = "设备名称")
|
||||
private String deviceName;
|
||||
|
||||
@Schema(name = "设备类型")
|
||||
private Long deviceType;
|
||||
|
||||
@Schema(name = "设备MAC")
|
||||
private String deviceMac;
|
||||
|
||||
@Schema(name = "设备IMEI")
|
||||
private String deviceImei;
|
||||
|
||||
@Schema(name = "设备SN")
|
||||
private String deviceSn;
|
||||
|
||||
/**
|
||||
* 设备状态
|
||||
* 0 失效
|
||||
* 1 正常
|
||||
*/
|
||||
@Schema(name = "设备状态 0 失效 1 正常 ")
|
||||
private Integer deviceStatus;
|
||||
|
||||
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'")
|
||||
@Schema(name = "创建时间")
|
||||
private List<Timestamp> createTime;
|
||||
|
||||
@Schema(name = "页码", example = "1")
|
||||
private Integer page = 1;
|
||||
|
||||
@Schema(name = "每页数据量", example = "10")
|
||||
private Integer size = 10;
|
||||
|
||||
@Schema(name = "客户id")
|
||||
private Long customerId;
|
||||
private Set<Long> customerIds;
|
||||
|
||||
@Schema(name = "当前所有者")
|
||||
private Long currentOwnerId;
|
||||
|
||||
@Schema(name = "租户ID")
|
||||
private Long tenantId;
|
||||
|
||||
@Schema(name = "通讯方式", example = "0:4G;1:蓝牙")
|
||||
private Integer communicationMode;
|
||||
|
||||
}
|
@ -29,7 +29,24 @@ public class AppDeviceVo {
|
||||
private Integer communicationMode;
|
||||
|
||||
/**
|
||||
* 设备图片
|
||||
* 设备图片
|
||||
*/
|
||||
private String devicePic;
|
||||
|
||||
/**
|
||||
* 设备类型
|
||||
*/
|
||||
private String typeName;
|
||||
|
||||
/**
|
||||
* 蓝牙名称
|
||||
*/
|
||||
private String bluetoothName;
|
||||
|
||||
/**
|
||||
* 设备状态
|
||||
* 0 失效
|
||||
* 1 正常
|
||||
*/
|
||||
private Integer deviceStatus;
|
||||
}
|
||||
|
@ -0,0 +1,38 @@
|
||||
package com.fuyuanshen.equipment.enums;
|
||||
|
||||
/**
|
||||
* 用户类型枚举
|
||||
*
|
||||
* @author: 默苍璃
|
||||
* @date: 2025-07-1210:31
|
||||
*/
|
||||
public enum AppUserTypeEnum {
|
||||
|
||||
APP_USER("app_user", "系统用户"),
|
||||
XCX_USER("xcx_user", "小程序用户");
|
||||
|
||||
private final String code;
|
||||
private final String description;
|
||||
|
||||
AppUserTypeEnum(String code, String description) {
|
||||
this.code = code;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "UserType{" +
|
||||
"code='" + code + '\'' +
|
||||
", description='" + description + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
}
|
@ -4,6 +4,7 @@ import com.fuyuanshen.customer.mapper.CustomerMapper;
|
||||
import com.fuyuanshen.equipment.mapper.DeviceMapper;
|
||||
import com.fuyuanshen.equipment.mapper.DeviceTypeMapper;
|
||||
import com.fuyuanshen.equipment.service.DeviceService;
|
||||
import com.fuyuanshen.equipment.service.DeviceTypeService;
|
||||
import com.fuyuanshen.system.service.ISysOssService;
|
||||
import lombok.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
@ -23,6 +24,7 @@ public class DeviceImportParams {
|
||||
private DeviceMapper deviceMapper;
|
||||
private CustomerMapper customerMapper;
|
||||
private DeviceTypeMapper deviceTypeMapper;
|
||||
private DeviceTypeService deviceTypeService;
|
||||
private ISysOssService ossService;
|
||||
private MultipartFile file;
|
||||
private String filePath;
|
||||
|
@ -1,12 +1,10 @@
|
||||
package com.fuyuanshen.equipment.excel;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.alibaba.excel.context.AnalysisContext;
|
||||
import com.alibaba.excel.read.listener.ReadListener;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.fuyuanshen.common.core.domain.model.LoginUser;
|
||||
import com.fuyuanshen.common.satoken.utils.LoginHelper;
|
||||
import com.fuyuanshen.equipment.constants.DeviceConstants;
|
||||
@ -14,7 +12,7 @@ import com.fuyuanshen.equipment.domain.Device;
|
||||
import com.fuyuanshen.equipment.domain.DeviceType;
|
||||
import com.fuyuanshen.equipment.domain.dto.DeviceExcelImportDTO;
|
||||
import com.fuyuanshen.equipment.domain.dto.ImportResult;
|
||||
import com.fuyuanshen.equipment.domain.query.DeviceQueryCriteria;
|
||||
import com.fuyuanshen.equipment.domain.form.DeviceForm;
|
||||
import com.fuyuanshen.equipment.handler.ImageWriteHandler;
|
||||
import com.fuyuanshen.system.domain.vo.SysOssVo;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -30,13 +28,13 @@ import java.util.*;
|
||||
public class UploadDeviceDataListener implements ReadListener<DeviceExcelImportDTO> {
|
||||
|
||||
// 存储图片数据的映射
|
||||
private final Map<Integer, byte[]> rowImageMap = new HashMap<>();
|
||||
private Map<Integer, byte[]> rowImageMap = new HashMap<>();
|
||||
|
||||
private final DeviceImportParams params;
|
||||
private DeviceImportParams params;
|
||||
|
||||
private final Map<Integer, Device> rowDeviceMap = new HashMap<>();
|
||||
private final Map<Integer, DeviceExcelImportDTO> rowDtoMap = new HashMap<>();
|
||||
private final List<Integer> rowIndexList = new ArrayList<>();
|
||||
private Map<Integer, Device> rowDeviceMap = new HashMap<>();
|
||||
private Map<Integer, DeviceExcelImportDTO> rowDtoMap = new HashMap<>();
|
||||
private List<Integer> rowIndexList = new ArrayList<>();
|
||||
|
||||
private int successCount = 0;
|
||||
private int failureCount = 0;
|
||||
@ -105,7 +103,6 @@ public class UploadDeviceDataListener implements ReadListener<DeviceExcelImportD
|
||||
.sheet("失败数据").doWrite(failedRecordsWithImages);
|
||||
|
||||
// 生成访问URL
|
||||
// String errorExcelUrl = params.getIp() + DeviceConstants.FILE_ACCESS_PREFIX + "/" + DeviceConstants.ERROR_REPORT_DIR + "/" + fileName;
|
||||
SysOssVo upload = params.getOssService().upload(errorFile);
|
||||
result.setErrorExcelUrl(upload.getUrl());
|
||||
log.info("错误报告已保存: {}", errorFile.getAbsolutePath());
|
||||
@ -151,27 +148,18 @@ public class UploadDeviceDataListener implements ReadListener<DeviceExcelImportD
|
||||
Device device = rowDeviceMap.get(rowIndex);
|
||||
DeviceExcelImportDTO originalDto = rowDtoMap.get(rowIndex);
|
||||
try {
|
||||
// DeviceQueryCriteria criteria = new DeviceQueryCriteria();
|
||||
// criteria.setDeviceMac(device.getDeviceMac());
|
||||
// criteria.setTenantId(params.getTenantId());
|
||||
// List<Device> deviceList = params.getDeviceMapper().findAll(criteria);
|
||||
// if (!deviceList.isEmpty()) {
|
||||
// throw new RuntimeException("设备MAC重复");
|
||||
// }
|
||||
// device.setTenantId(params.getTenantId());
|
||||
|
||||
// 设备类型
|
||||
QueryWrapper<DeviceType> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq("type_name", device.getTypeName());
|
||||
// wrapper.eq("customer_id", params.getUserId());
|
||||
List<DeviceType> deviceTypes = params.getDeviceTypeMapper().selectList(wrapper);
|
||||
if (CollectionUtil.isNotEmpty(deviceTypes)) {
|
||||
device.setDeviceType(deviceTypes.get(0).getId());
|
||||
}
|
||||
device.setCurrentOwnerId(loginUser.getUserId());
|
||||
device.setOriginalOwnerId(loginUser.getUserId());
|
||||
device.setCreateByName(loginUser.getNickname());
|
||||
params.getDeviceService().save(device);
|
||||
DeviceType deviceType = params.getDeviceTypeService().queryByName(device.getTypeName());
|
||||
// params.getDeviceService().save(device);
|
||||
DeviceForm deviceForm = new DeviceForm();
|
||||
deviceForm.setDeviceName(device.getDeviceName());
|
||||
deviceForm.setDeviceType(deviceType.getId());
|
||||
deviceForm.setRemark(device.getRemark());
|
||||
deviceForm.setDeviceMac(device.getDeviceMac());
|
||||
deviceForm.setDeviceImei(device.getDeviceImei());
|
||||
deviceForm.setBluetoothName(device.getBluetoothName());
|
||||
deviceForm.setDevicePic(device.getDevicePic());
|
||||
params.getDeviceService().addDevice(deviceForm);
|
||||
successCount++;
|
||||
log.info("行 {} 数据插入成功", rowIndex);
|
||||
} catch (Exception e) {
|
||||
@ -225,10 +213,8 @@ public class UploadDeviceDataListener implements ReadListener<DeviceExcelImportD
|
||||
private String getCellValue(XSSFSheet sheet, int rowIndex, int colIndex) {
|
||||
XSSFRow row = sheet.getRow(rowIndex);
|
||||
if (row == null) return null;
|
||||
|
||||
XSSFCell cell = row.getCell(colIndex);
|
||||
if (cell == null) return null;
|
||||
|
||||
return cell.toString();
|
||||
}
|
||||
|
||||
@ -240,18 +226,6 @@ public class UploadDeviceDataListener implements ReadListener<DeviceExcelImportD
|
||||
try {
|
||||
String fileExtension = "jpg";
|
||||
String newFileName = "PS_" + new Random(8) + "." + fileExtension;
|
||||
// String targetDirPath = params.getFilePath() + DeviceConstants.FILE_ACCESS_ISOLATION;
|
||||
// File targetDir = new File(targetDirPath);
|
||||
//
|
||||
// if (!targetDir.exists() && !targetDir.mkdirs()) {
|
||||
// log.error("无法创建目录: {}", targetDirPath);
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// File newFile = new File(targetDir, newFileName);
|
||||
// Files.write(newFile.toPath(), imageData);
|
||||
//
|
||||
// return params.getIp() + DeviceConstants.FILE_ACCESS_PREFIX + "/" + DeviceConstants.FILE_ACCESS_ISOLATION + "/" + newFileName;
|
||||
SysOssVo upload = params.getOssService().upload(imageData, newFileName);
|
||||
return upload.getUrl();
|
||||
} catch (Exception e) {
|
||||
|
@ -32,7 +32,25 @@ public interface DeviceMapper extends BaseMapper<Device> {
|
||||
|
||||
List<Device> findAllDevices(@Param("criteria") DeviceQueryCriteria criteria);
|
||||
|
||||
Page<AppDeviceVo> queryAppDeviceList(Page<AppDeviceVo> page,@Param("criteria") DeviceQueryCriteria criteria);
|
||||
/**
|
||||
* 根据条件查询
|
||||
*
|
||||
* @param criteria
|
||||
* @return
|
||||
*/
|
||||
List<Device> findDevices(@Param("criteria") DeviceQueryCriteria criteria);
|
||||
|
||||
/**
|
||||
* 查询APP绑定设备列表
|
||||
*
|
||||
* @param criteria
|
||||
* @return
|
||||
*/
|
||||
Page<AppDeviceVo> queryAppBindDeviceList(Page<AppDeviceVo> page, @Param("criteria") DeviceQueryCriteria criteria);
|
||||
|
||||
|
||||
Page<AppDeviceVo> queryAppDeviceList(Page<AppDeviceVo> page, @Param("criteria") DeviceQueryCriteria criteria);
|
||||
|
||||
/**
|
||||
* 获取分配设备的客户
|
||||
*
|
||||
|
@ -27,7 +27,6 @@ public interface DeviceTypeMapper extends BaseMapper<DeviceType> {
|
||||
*/
|
||||
IPage<DeviceType> findAll(@Param("criteria") DeviceTypeQueryCriteria criteria, Page<DeviceType> page);
|
||||
|
||||
|
||||
/**
|
||||
* 查询所有设备类型
|
||||
*
|
||||
@ -44,4 +43,12 @@ public interface DeviceTypeMapper extends BaseMapper<DeviceType> {
|
||||
*/
|
||||
DeviceType getAssignType(@Param("deviceType") Long deviceType, @Param("customerId") Long customerId);
|
||||
|
||||
/**
|
||||
* 根据名称查询设备类型
|
||||
*
|
||||
* @param criteria
|
||||
* @return
|
||||
*/
|
||||
DeviceType queryByName(@Param("criteria") DeviceTypeQueryCriteria criteria);
|
||||
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package com.fuyuanshen.equipment.service;
|
||||
|
||||
import com.fuyuanshen.common.mybatis.core.page.PageQuery;
|
||||
import com.fuyuanshen.common.mybatis.core.page.TableDataInfo;
|
||||
import com.fuyuanshen.equipment.domain.UserApp;
|
||||
import com.fuyuanshen.equipment.domain.bo.UserAppBo;
|
||||
|
||||
import java.util.Collection;
|
||||
@ -23,5 +24,23 @@ public interface AppUserService {
|
||||
*/
|
||||
Boolean updateByBo(UserAppBo bo);
|
||||
|
||||
/**
|
||||
* 查询小程序用户信息
|
||||
*
|
||||
* @param phoneNumber
|
||||
* @return
|
||||
*/
|
||||
UserApp getMpUser(Long phoneNumber);
|
||||
|
||||
UserApp loadUserByUsername(String username);
|
||||
|
||||
/**
|
||||
* 新增小程序用户信息
|
||||
*
|
||||
* @param userApp
|
||||
* @return
|
||||
*/
|
||||
void saveMpUser(UserApp userApp);
|
||||
|
||||
|
||||
}
|
||||
|
@ -91,4 +91,19 @@ public interface DeviceService extends IService<Device> {
|
||||
|
||||
int unBindDevice(Long id);
|
||||
|
||||
/**
|
||||
* 检查设备MAC值是否存在
|
||||
*
|
||||
* @param mac
|
||||
* @return
|
||||
*/
|
||||
Boolean queryDevice(String mac);
|
||||
|
||||
/**
|
||||
* WEB端解绑设备
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
int webUnBindDevice(Long id);
|
||||
}
|
||||
|
@ -41,6 +41,14 @@ public interface DeviceTypeService extends IService<DeviceType> {
|
||||
*/
|
||||
List<DeviceType> queryDeviceTypes();
|
||||
|
||||
/**
|
||||
* 根据设备类型名称查询设备类型
|
||||
*
|
||||
* @param typeName 条件参数
|
||||
* @return List<DeviceTypeDto>
|
||||
*/
|
||||
DeviceType queryByName(String typeName);
|
||||
|
||||
/**
|
||||
* 新增设备类型
|
||||
*
|
||||
|
@ -43,6 +43,8 @@ public class DeviceExportService {
|
||||
dto.setDeviceMac(device.getDeviceMac());
|
||||
// 设备IMEI
|
||||
dto.setDeviceImei(device.getDeviceImei());
|
||||
// 蓝牙名称
|
||||
dto.setBluetoothName(device.getBluetoothName());
|
||||
dto.setLongitude(device.getLongitude());
|
||||
dto.setLatitude(device.getLatitude());
|
||||
dto.setRemark(device.getRemark());
|
||||
|
@ -3,7 +3,6 @@ package com.fuyuanshen.equipment.service.impl;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.lang.UUID;
|
||||
import cn.hutool.core.lang.generator.SnowflakeGenerator;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
@ -11,6 +10,8 @@ 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.common.core.domain.model.LoginUser;
|
||||
import com.fuyuanshen.common.core.exception.BadRequestException;
|
||||
import com.fuyuanshen.common.core.utils.StringUtils;
|
||||
import com.fuyuanshen.common.mybatis.core.page.PageQuery;
|
||||
import com.fuyuanshen.common.mybatis.core.page.TableDataInfo;
|
||||
import com.fuyuanshen.common.satoken.utils.AppLoginHelper;
|
||||
@ -32,7 +33,6 @@ import com.fuyuanshen.equipment.domain.vo.CustomerVo;
|
||||
import com.fuyuanshen.equipment.enums.BindingStatusEnum;
|
||||
import com.fuyuanshen.equipment.enums.CommunicationModeEnum;
|
||||
import com.fuyuanshen.equipment.enums.DeviceActiveStatusEnum;
|
||||
import com.fuyuanshen.equipment.enums.DeviceStatusEnum;
|
||||
import com.fuyuanshen.equipment.mapper.DeviceAssignmentsMapper;
|
||||
import com.fuyuanshen.equipment.mapper.DeviceMapper;
|
||||
import com.fuyuanshen.equipment.mapper.DeviceTypeGrantsMapper;
|
||||
@ -42,7 +42,6 @@ import com.fuyuanshen.equipment.service.DeviceService;
|
||||
import com.fuyuanshen.equipment.service.DeviceTypeGrantsService;
|
||||
import com.fuyuanshen.system.domain.vo.SysOssVo;
|
||||
import com.fuyuanshen.system.service.ISysOssService;
|
||||
import com.fuyuanshen.system.service.ISysUserService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@ -54,7 +53,10 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @Description:
|
||||
@ -113,6 +115,7 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
|
||||
|
||||
@Override
|
||||
public List<Device> queryAll(DeviceQueryCriteria criteria) {
|
||||
criteria.setCurrentOwnerId(LoginHelper.getUserId());
|
||||
return deviceMapper.findAll(criteria);
|
||||
}
|
||||
|
||||
@ -142,6 +145,9 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
|
||||
queryCriteria.setDeviceTypeId(deviceForm.getDeviceType());
|
||||
queryCriteria.setCustomerId(LoginHelper.getUserId());
|
||||
DeviceTypeGrants typeGrants = deviceTypeGrantsMapper.selectById(queryCriteria.getDeviceTypeId());
|
||||
if (typeGrants == null) {
|
||||
throw new Exception("设备类型不存在!!!");
|
||||
}
|
||||
DeviceType deviceTypes = deviceTypeMapper.selectById(typeGrants.getDeviceTypeId());
|
||||
if (deviceTypes == null) {
|
||||
throw new Exception("设备类型不存在!!!");
|
||||
@ -207,16 +213,12 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
|
||||
if (deviceTypes.isEmpty()) {
|
||||
throw new Exception("设备类型不存在!!!");
|
||||
}
|
||||
|
||||
DeviceQueryCriteria queryCriteria = new DeviceQueryCriteria();
|
||||
queryCriteria.setDeviceId(deviceAssignments.getDeviceId());
|
||||
queryCriteria.setCustomerId(LoginHelper.getUserId());
|
||||
queryCriteria.setCurrentOwnerId(LoginHelper.getUserId());
|
||||
List<Device> devices = deviceMapper.findAll(queryCriteria);
|
||||
if (devices.isEmpty()) {
|
||||
Device device = deviceMapper.selectById(deviceAssignments.getDeviceId());
|
||||
if (device == null) {
|
||||
throw new Exception("设备不存在!!!");
|
||||
}
|
||||
Device device = devices.get(0);
|
||||
// 设备类型
|
||||
Long deviceType = device.getDeviceType();
|
||||
|
||||
// 处理上传的图片
|
||||
if (deviceForm.getFile() != null) {
|
||||
@ -228,6 +230,7 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
|
||||
// 更新字段
|
||||
BeanUtil.copyProperties(deviceForm, device, true);
|
||||
device.setId(deviceAssignments.getDeviceId());
|
||||
device.setDeviceType(deviceType);
|
||||
device.setUpdateTime(new Timestamp(System.currentTimeMillis()));
|
||||
deviceMapper.updateById(device);
|
||||
}
|
||||
@ -272,20 +275,23 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
|
||||
public void deleteAll(List<Long> ids) {
|
||||
List<Long> invalidIds = new ArrayList<>();
|
||||
|
||||
for (Long id : ids) {
|
||||
DeviceAssignments deviceAssignment = deviceAssignmentsMapper.selectById(id);
|
||||
Device deviceType = deviceMapper.selectById(deviceAssignment.getDeviceId());
|
||||
|
||||
if (StringUtils.isNotEmpty(deviceAssignment.getAssigneeName())) {
|
||||
throw new BadRequestException(deviceType.getDeviceName() + ":设备已分配,请先解绑设备!!!");
|
||||
}
|
||||
|
||||
// 接收者
|
||||
if (Objects.equals(deviceAssignment.getAssigneeId(), deviceType.getOriginalOwnerId())) {
|
||||
invalidIds.add(deviceAssignment.getDeviceId());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
deviceAssignmentsMapper.deleteByIds(ids);
|
||||
//
|
||||
// for (Long id : ids) {
|
||||
//
|
||||
// Device deviceType = deviceMapper.selectById(id);
|
||||
// if (deviceType == null || !Objects.equals(deviceType.getCurrentOwnerId(), LoginHelper.getUserId())) {
|
||||
// invalidIds.add(id);
|
||||
// }
|
||||
// }
|
||||
// if (!invalidIds.isEmpty()) {
|
||||
// throw new RuntimeException("以下设备无法删除(ID 不存在或无权限): " + invalidIds);
|
||||
// }
|
||||
//
|
||||
// deviceMapper.deleteByIds(ids);
|
||||
deviceMapper.deleteByIds(invalidIds);
|
||||
}
|
||||
|
||||
|
||||
@ -312,6 +318,12 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
|
||||
// 批量更新设备状态
|
||||
List<DeviceTypeGrants> deviceTypeGrants = new ArrayList<>();
|
||||
for (DeviceAssignments assignment : assignments) {
|
||||
|
||||
if (assignment.getToCustomerId() != null) {
|
||||
log.info("设备已经分配客户!!!");
|
||||
continue;
|
||||
}
|
||||
|
||||
Device device = deviceMapper.selectById(assignment.getDeviceId());
|
||||
|
||||
// 如果设备已分配给需要分配的客户,则跳过
|
||||
@ -326,6 +338,7 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
|
||||
|
||||
// 更改分配客户
|
||||
assignment.setAssigneeName(assignUser.getNickName());
|
||||
assignment.setToCustomerId(customerVo.getCustomerId());
|
||||
deviceAssignmentsMapper.updateById(assignment);
|
||||
|
||||
// 设备失效
|
||||
@ -356,7 +369,9 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
|
||||
deviceAssignmentsService.save(dam);
|
||||
|
||||
// 判断设备类型是否存在
|
||||
DeviceTypeGrants dtg = deviceTypeGrantsMapper.selectOne(new LambdaQueryWrapper<DeviceTypeGrants>().eq(DeviceTypeGrants::getDeviceTypeId, device.getId()));
|
||||
DeviceTypeGrants dtg = deviceTypeGrantsMapper.selectOne(new LambdaQueryWrapper<DeviceTypeGrants>()
|
||||
.eq(DeviceTypeGrants::getDeviceTypeId, device.getDeviceType())
|
||||
.eq(DeviceTypeGrants::getCustomerId, assignUser.getCustomerId()));
|
||||
if (dtg != null) {
|
||||
continue;
|
||||
}
|
||||
@ -397,51 +412,82 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 撤回设备
|
||||
*
|
||||
* @param ids
|
||||
*/
|
||||
// @Override
|
||||
// public void withdrawDevice(List<Long> ids) {
|
||||
// ids.forEach((id) -> {
|
||||
// List<Device> deviceChain = getDeviceChain(id);
|
||||
// deviceChain.forEach((device) -> {
|
||||
// device.setDeviceStatus(DeviceStatusEnum.INVALID.getCode());
|
||||
// deviceMapper.updateById(device);
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// ids.forEach((id) -> {
|
||||
// Device device = new Device();
|
||||
// device.setId(id);
|
||||
// device.setCustomerId(null);
|
||||
// device.setCustomerName("");
|
||||
// deviceMapper.updateById(device);
|
||||
// });
|
||||
//
|
||||
// }
|
||||
//
|
||||
//
|
||||
// public List<Device> getDeviceChain(Long originalDeviceId) {
|
||||
// List<Device> chain = new ArrayList<>();
|
||||
// Set<Long> visited = new HashSet<>(); // 防止循环引用
|
||||
// findNext(chain, visited, originalDeviceId);
|
||||
// return chain;
|
||||
// }
|
||||
//
|
||||
// private void findNext(List<Device> chain, Set<Long> visited, Long currentOriginalDeviceId) {
|
||||
// if (visited.contains(currentOriginalDeviceId)) {
|
||||
// log.info("检测到循环引用,终止递归");
|
||||
// return;
|
||||
// }
|
||||
// visited.add(currentOriginalDeviceId);
|
||||
//
|
||||
// List<Device> devices = deviceMapper.findByOriginalDeviceId(currentOriginalDeviceId);
|
||||
// for (Device device : devices) {
|
||||
// chain.add(device);
|
||||
// findNext(chain, visited, device.getId());
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* 撤回设备
|
||||
*
|
||||
* @param ids
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
public void withdrawDevice(List<Long> ids) {
|
||||
ids.forEach((id) -> {
|
||||
List<Device> deviceChain = getDeviceChain(id);
|
||||
deviceChain.forEach((device) -> {
|
||||
device.setDeviceStatus(DeviceStatusEnum.INVALID.getCode());
|
||||
deviceMapper.updateById(device);
|
||||
});
|
||||
});
|
||||
|
||||
ids.forEach((id) -> {
|
||||
Device device = new Device();
|
||||
device.setId(id);
|
||||
device.setCustomerId(null);
|
||||
device.setCustomerName("");
|
||||
deviceMapper.updateById(device);
|
||||
});
|
||||
for (Long id : ids) {
|
||||
DeviceAssignments assignment = deviceAssignmentsMapper.selectById(id);
|
||||
Device device = deviceMapper.selectById(assignment.getDeviceId());
|
||||
// 接收者
|
||||
assignment.setAssigneeName("");
|
||||
assignment.setToCustomerId(null);
|
||||
deviceAssignmentsMapper.updateById(assignment);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public List<Device> getDeviceChain(Long originalDeviceId) {
|
||||
List<Device> chain = new ArrayList<>();
|
||||
Set<Long> visited = new HashSet<>(); // 防止循环引用
|
||||
findNext(chain, visited, originalDeviceId);
|
||||
return chain;
|
||||
}
|
||||
|
||||
private void findNext(List<Device> chain, Set<Long> visited, Long currentOriginalDeviceId) {
|
||||
if (visited.contains(currentOriginalDeviceId)) {
|
||||
log.info("检测到循环引用,终止递归");
|
||||
return;
|
||||
// 获取所有已分配的设备
|
||||
DeviceAssignmentQuery dq = DeviceAssignmentQuery.builder().deviceId(device.getId())
|
||||
.active(DeviceActiveStatusEnum.ACTIVE.getCode()).lever(assignment.getLever() + USER_ID_SEPARATOR).build();
|
||||
// 查询分配
|
||||
List<DeviceAssignments> assignmentsList = deviceAssignmentsMapper.deviceAssignmentsMapper(dq);
|
||||
for (DeviceAssignments assignments : assignmentsList) {
|
||||
assignments.setActive(DeviceActiveStatusEnum.INACTIVE.getCode());
|
||||
deviceAssignmentsMapper.updateById(assignments);
|
||||
}
|
||||
}
|
||||
visited.add(currentOriginalDeviceId);
|
||||
|
||||
List<Device> devices = deviceMapper.findByOriginalDeviceId(currentOriginalDeviceId);
|
||||
for (Device device : devices) {
|
||||
chain.add(device);
|
||||
findNext(chain, visited, device.getId());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -459,9 +505,11 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
|
||||
|
||||
@Override
|
||||
public TableDataInfo<AppDeviceVo> queryAppDeviceList(DeviceQueryCriteria bo, PageQuery pageQuery) {
|
||||
Long userId = AppLoginHelper.getUserId();
|
||||
bo.setBindingUserId(userId);
|
||||
Page<AppDeviceVo> result = baseMapper.queryAppDeviceList(pageQuery.build(), bo);
|
||||
if (bo.getBindingUserId() == null) {
|
||||
Long userId = AppLoginHelper.getUserId();
|
||||
bo.setBindingUserId(userId);
|
||||
}
|
||||
Page<AppDeviceVo> result = baseMapper.queryAppBindDeviceList(pageQuery.build(), bo);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
@ -485,8 +533,9 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
|
||||
UpdateWrapper<Device> deviceUpdateWrapper = new UpdateWrapper<>();
|
||||
deviceUpdateWrapper.eq("id", device.getId())
|
||||
.set("binding_status", BindingStatusEnum.BOUND.getCode())
|
||||
.set("binding_user_id", userId);
|
||||
;
|
||||
.set("binding_user_id", userId)
|
||||
.set("binding_time", new Date());
|
||||
|
||||
|
||||
return baseMapper.update(null, deviceUpdateWrapper);
|
||||
} else if (mode == CommunicationModeEnum.BLUETOOTH.getValue()) {
|
||||
@ -504,8 +553,9 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
|
||||
UpdateWrapper<Device> deviceUpdateWrapper = new UpdateWrapper<>();
|
||||
deviceUpdateWrapper.eq("id", device.getId())
|
||||
.set("binding_status", BindingStatusEnum.BOUND.getCode())
|
||||
.set("binding_user_id", userId);
|
||||
return baseMapper.update(null, qw);
|
||||
.set("binding_user_id", userId)
|
||||
.set("binding_time", new Date());
|
||||
return baseMapper.update(null, deviceUpdateWrapper);
|
||||
} else {
|
||||
throw new RuntimeException("通讯方式错误");
|
||||
}
|
||||
@ -522,8 +572,45 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
|
||||
// String mode = deviceType.getCommunicationMode();
|
||||
UpdateWrapper<Device> deviceUpdateWrapper = new UpdateWrapper<>();
|
||||
deviceUpdateWrapper.eq("id", device.getId())
|
||||
.set("binding_status", BindingStatusEnum.UNBOUND.getCode());
|
||||
.set("binding_status", BindingStatusEnum.UNBOUND.getCode())
|
||||
.set("binding_user_id", null)
|
||||
.set("binding_time", null);
|
||||
return baseMapper.update(null, deviceUpdateWrapper);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* WEB端解绑设备
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int webUnBindDevice(Long id) {
|
||||
DeviceAssignments deviceAssignment = deviceAssignmentsMapper.selectById(id);
|
||||
if (deviceAssignment == null) {
|
||||
throw new RuntimeException("请先将设备入库!!!");
|
||||
}
|
||||
return unBindDevice(deviceAssignment.getDeviceId());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询设备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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -78,6 +78,21 @@ public class DeviceTypeServiceImpl extends ServiceImpl<DeviceTypeMapper, DeviceT
|
||||
return deviceTypeMapper.findAll(criteria);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据设备类型名称查询设备类型
|
||||
*
|
||||
* @param typeName 条件参数
|
||||
* @return List<DeviceTypeDto>
|
||||
*/
|
||||
@Override
|
||||
public DeviceType queryByName(String typeName) {
|
||||
DeviceTypeQueryCriteria criteria = new DeviceTypeQueryCriteria();
|
||||
criteria.setCustomerId(LoginHelper.getUserId());
|
||||
criteria.setTypeName(typeName);
|
||||
DeviceType deviceType = deviceTypeMapper.queryByName(criteria);
|
||||
return deviceType;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 新增设备类型
|
||||
|
@ -1,8 +1,10 @@
|
||||
package com.fuyuanshen.equipment.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.fuyuanshen.common.core.utils.MapstructUtils;
|
||||
import com.fuyuanshen.equipment.domain.UserApp;
|
||||
import com.fuyuanshen.equipment.domain.bo.UserAppBo;
|
||||
import com.fuyuanshen.equipment.enums.AppUserTypeEnum;
|
||||
import com.fuyuanshen.equipment.mapper.UserAppMapper;
|
||||
import com.fuyuanshen.equipment.service.AppUserService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@ -22,7 +24,7 @@ import java.util.Collection;
|
||||
@Service
|
||||
public class UserAppServiceImpl implements AppUserService {
|
||||
|
||||
private final UserAppMapper baseMapper;
|
||||
private final UserAppMapper userAppMapper;
|
||||
|
||||
|
||||
/**
|
||||
@ -34,7 +36,42 @@ public class UserAppServiceImpl implements AppUserService {
|
||||
@Override
|
||||
public Boolean updateByBo(UserAppBo bo) {
|
||||
UserApp update = MapstructUtils.convert(bo, UserApp.class);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
return userAppMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询小程序用户信息
|
||||
*
|
||||
* @param phoneNumber
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public UserApp getMpUser(Long phoneNumber) {
|
||||
QueryWrapper<UserApp> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("phonenumber", phoneNumber);
|
||||
queryWrapper.eq("user_type", AppUserTypeEnum.XCX_USER.getCode());
|
||||
return userAppMapper.selectOne(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserApp loadUserByUsername(String username) {
|
||||
QueryWrapper<UserApp> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("user_name", username);
|
||||
queryWrapper.eq("user_type", AppUserTypeEnum.XCX_USER.getCode());
|
||||
return userAppMapper.selectOne(queryWrapper);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 新增小程序用户信息
|
||||
*
|
||||
* @param userApp
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public void saveMpUser(UserApp userApp) {
|
||||
userAppMapper.insert(userApp);
|
||||
}
|
||||
|
||||
|
||||
|
@ -0,0 +1,239 @@
|
||||
package com.fuyuanshen.equipment.utils.c;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 可靠点阵生成工具 - 终极版
|
||||
*
|
||||
* @author: 默苍璃
|
||||
* @date: 2025-07-15
|
||||
*/
|
||||
public class ReliableTextToBitmap {
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
String unit = "繁體繁體繁體";
|
||||
String department = "A研B发C";
|
||||
String name = "12李34四56";
|
||||
|
||||
byte[] unitBytes = textToBitmapBytes(unit);
|
||||
byte[] deptBytes = textToBitmapBytes(department);
|
||||
byte[] nameBytes = textToBitmapBytes(name);
|
||||
|
||||
generateCFile(unitBytes, deptBytes, nameBytes, "display_data.c");
|
||||
|
||||
// 生成预览图片
|
||||
generatePreviewImage(unitBytes, "unit_image.png");
|
||||
generatePreviewImage(deptBytes, "department_image.png");
|
||||
generatePreviewImage(nameBytes, "name_image.png");
|
||||
}
|
||||
|
||||
// 专门生成预览图片的方法
|
||||
private static void generatePreviewImage(byte[] data, String filename) {
|
||||
try {
|
||||
BufferedImage image = convertByteArrayToImage(data, 12);
|
||||
ImageIO.write(image, "PNG", new File(filename));
|
||||
System.out.println("成功生成预览图片: " + filename);
|
||||
} catch (IOException e) {
|
||||
System.err.println("图片生成失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 可靠的字节数组转图像方法
|
||||
*/
|
||||
public static BufferedImage convertByteArrayToImage(byte[] data, int height) {
|
||||
if (data == null || data.length == 0) {
|
||||
return new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
|
||||
}
|
||||
|
||||
// 计算宽度
|
||||
int width = (data.length * 8) / height;
|
||||
|
||||
// 创建RGB图像
|
||||
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||
|
||||
// 设置白色背景
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
image.setRGB(x, y, Color.WHITE.getRGB());
|
||||
}
|
||||
}
|
||||
|
||||
// 直接设置像素点
|
||||
int bitIndex = 0;
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
int value = data[i] & 0xFF;
|
||||
for (int bit = 7; bit >= 0; bit--) { // 高位在前
|
||||
boolean isBlack = ((value >> bit) & 1) == 1;
|
||||
if (isBlack) {
|
||||
int x = bitIndex % width;
|
||||
int y = bitIndex / width;
|
||||
if (y < height) { // 确保不越界
|
||||
image.setRGB(x, y, Color.BLACK.getRGB());
|
||||
}
|
||||
}
|
||||
bitIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* 可靠的点阵生成方法
|
||||
*/
|
||||
public static byte[] textToBitmapBytes(String text) {
|
||||
if (text == null || text.isEmpty()) {
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
// 1. 创建画布 - 使用RGB类型避免问题
|
||||
Font font = new Font("宋体", Font.PLAIN, 12);
|
||||
BufferedImage image = createTextImage(text, font);
|
||||
|
||||
// 2. 直接提取点阵数据
|
||||
return extractBitmapData(image);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建文本图像 - 最可靠的方法
|
||||
*/
|
||||
private static BufferedImage createTextImage(String text, Font font) {
|
||||
// 创建临时图像获取字体度量
|
||||
BufferedImage tempImage = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D tempG = tempImage.createGraphics();
|
||||
tempG.setFont(font);
|
||||
FontMetrics metrics = tempG.getFontMetrics();
|
||||
|
||||
// 计算文本宽度
|
||||
int totalWidth = metrics.stringWidth(text);
|
||||
|
||||
// 宽度对齐到8的倍数
|
||||
int width = (int) Math.ceil(totalWidth / 8.0) * 8;
|
||||
int height = 12;
|
||||
|
||||
// 创建RGB图像
|
||||
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D g = image.createGraphics();
|
||||
|
||||
// 设置白色背景
|
||||
g.setColor(Color.WHITE);
|
||||
g.fillRect(0, 0, width, height);
|
||||
|
||||
// 设置黑色文本
|
||||
g.setColor(Color.BLACK);
|
||||
g.setFont(font);
|
||||
|
||||
// 关闭抗锯齿 - 确保清晰度
|
||||
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
|
||||
RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
|
||||
|
||||
// 绘制文本 - 精确居中
|
||||
int y = (height - metrics.getHeight()) / 2 + metrics.getAscent();
|
||||
g.drawString(text, 0, y);
|
||||
|
||||
g.dispose();
|
||||
tempG.dispose();
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* 提取点阵数据 - 简单可靠的方法
|
||||
*/
|
||||
private static byte[] extractBitmapData(BufferedImage image) {
|
||||
int width = image.getWidth();
|
||||
int height = image.getHeight();
|
||||
|
||||
List<Byte> byteList = new ArrayList<>();
|
||||
int currentByte = 0;
|
||||
int bitCount = 0;
|
||||
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
// 获取像素颜色
|
||||
Color color = new Color(image.getRGB(x, y));
|
||||
|
||||
// 简单阈值判断 - 灰度小于128为黑色
|
||||
int gray = (color.getRed() + color.getGreen() + color.getBlue()) / 3;
|
||||
boolean isBlack = gray < 128;
|
||||
|
||||
// 高位优先打包
|
||||
currentByte = (currentByte << 1) | (isBlack ? 1 : 0);
|
||||
bitCount++;
|
||||
|
||||
if (bitCount == 8) {
|
||||
byteList.add((byte) currentByte);
|
||||
currentByte = 0;
|
||||
bitCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理最后不满8位的部分
|
||||
if (bitCount > 0) {
|
||||
currentByte <<= (8 - bitCount);
|
||||
byteList.add((byte) currentByte);
|
||||
}
|
||||
|
||||
return byteListToArray(byteList);
|
||||
}
|
||||
|
||||
private static byte[] byteListToArray(List<Byte> byteList) {
|
||||
byte[] result = new byte[byteList.size()];
|
||||
for (int i = 0; i < byteList.size(); i++) {
|
||||
result[i] = byteList.get(i);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void generateCFile(byte[] unit, byte[] department, byte[] name, String filename) throws IOException {
|
||||
try (FileWriter writer = new FileWriter(filename)) {
|
||||
writer.write("/**\n");
|
||||
writer.write(" * 点阵显示数据 - 可靠生成\n");
|
||||
writer.write(" * 宽度计算公式: width = (数组长度 * 8) / 12\n");
|
||||
writer.write(" */\n\n");
|
||||
writer.write("#include <stdint.h>\n\n");
|
||||
|
||||
// 单位数据
|
||||
writer.write(String.format("// 单位: %d 字节, 宽度: %d 像素\n",
|
||||
unit.length, (unit.length * 8) / 12));
|
||||
writer.write("const uint8_t unit[] = {\n ");
|
||||
writeByteArray(writer, unit);
|
||||
writer.write("\n};\n\n");
|
||||
|
||||
// 部门数据
|
||||
writer.write(String.format("// 部门: %d 字节, 宽度: %d 像素\n",
|
||||
department.length, (department.length * 8) / 12));
|
||||
writer.write("const uint8_t department[] = {\n ");
|
||||
writeByteArray(writer, department);
|
||||
writer.write("\n};\n\n");
|
||||
|
||||
// 姓名数据
|
||||
writer.write(String.format("// 姓名: %d 字节, 宽度: %d 像素\n",
|
||||
name.length, (name.length * 8) / 12));
|
||||
writer.write("const uint8_t name[] = {\n ");
|
||||
writeByteArray(writer, name);
|
||||
writer.write("\n};\n");
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeByteArray(FileWriter writer, byte[] data) throws IOException {
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
int value = data[i] & 0xFF;
|
||||
writer.write(String.format("0x%02X", value));
|
||||
|
||||
if (i < data.length - 1) {
|
||||
writer.write(", ");
|
||||
if ((i + 1) % 12 == 0) writer.write("\n ");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -5,7 +5,7 @@
|
||||
<id column="id" property="id"/>
|
||||
<result column="device_type" property="deviceType"/>
|
||||
<result column="customer_id" property="customerId"/>
|
||||
<!--<result column="device_no" property="deviceNo"/>-->
|
||||
<result column="device_no" property="deviceNo"/>
|
||||
<result column="device_name" property="deviceName"/>
|
||||
<result column="device_pic" property="devicePic"/>
|
||||
<result column="device_mac" property="deviceMac"/>
|
||||
@ -36,48 +36,12 @@
|
||||
d.device_imei, d.longitude, d.latitude, d.tenant_id
|
||||
</sql>
|
||||
|
||||
<!-- 分页查询设备 -->
|
||||
<select id="findAll1" resultType="com.fuyuanshen.equipment.domain.Device">
|
||||
select d.* , t.type_name
|
||||
FROM device d
|
||||
LEFT JOIN device_type t ON d.device_type = t.id
|
||||
<where>
|
||||
<!-- 时间范围等其他条件保持原样 -->
|
||||
<if test="criteria.deviceName != null and criteria.deviceName.trim() != ''">
|
||||
and d.device_name like concat('%', TRIM(#{criteria.deviceName}), '%')
|
||||
</if>
|
||||
<if test="criteria.deviceMac != null">
|
||||
and d.device_mac = #{criteria.deviceMac}
|
||||
</if>
|
||||
<if test="criteria.deviceImei != null">
|
||||
and d.device_imei = #{criteria.deviceImei}
|
||||
</if>
|
||||
<if test="criteria.deviceType != null">
|
||||
and d.device_type = #{criteria.deviceType}
|
||||
</if>
|
||||
<if test="criteria.deviceStatus != null">
|
||||
and d.device_status = #{criteria.deviceStatus}
|
||||
</if>
|
||||
<if test="criteria.currentOwnerId != null">
|
||||
and d.current_owner_id = #{criteria.currentOwnerId}
|
||||
</if>
|
||||
<if test="criteria.params.beginTime != null and criteria.params.endTime != null">
|
||||
and d.create_time between #{criteria.params.beginTime} and #{criteria.params.endTime}
|
||||
</if>
|
||||
<if test="criteria.tenantId != null">
|
||||
AND tenant_id = #{criteria.tenantId}
|
||||
</if>
|
||||
</where>
|
||||
order by d.create_time desc
|
||||
</select>
|
||||
|
||||
|
||||
<!-- 分页查询设备 -->
|
||||
<select id="findAll" resultType="com.fuyuanshen.equipment.domain.Device">
|
||||
select
|
||||
da.id AS id,d.device_name,
|
||||
da.id AS id,d.device_name,d.bluetooth_name,
|
||||
d.device_pic, d.device_mac, d.device_sn, d.update_by,d.device_imei,
|
||||
d.update_time, dg.id AS device_type, d.remark, d.binding_status,d.type_name AS typeName,
|
||||
d.update_time, dg.id AS device_type, d.remark, d.binding_status,t.type_name AS typeName,
|
||||
da.assignee_id AS customerId, da.assignee_name AS customerName, da.active AS deviceStatus,
|
||||
da.create_time AS create_time , da.assigner_name AS createByName , da.id AS assignId
|
||||
from device d
|
||||
@ -105,14 +69,14 @@
|
||||
and da.create_time between #{criteria.params.beginTime} and #{criteria.params.endTime}
|
||||
</if>
|
||||
AND da.assignee_id = #{criteria.currentOwnerId}
|
||||
|
||||
AND dg.customer_id = #{criteria.currentOwnerId}
|
||||
</where>
|
||||
ORDER BY da.create_time DESC
|
||||
</select>
|
||||
|
||||
<select id="findAllDevices" resultType="com.fuyuanshen.equipment.domain.Device">
|
||||
select
|
||||
d.id, d.customer_id, d.device_name,
|
||||
d.id, d.customer_id, d.device_name,d.bluetooth_name,
|
||||
d.device_pic, d.device_mac, d.device_sn, d.create_by, d.update_by,
|
||||
d.create_time, d.update_time, d.longitude, d.latitude, d.remark
|
||||
from device d
|
||||
@ -133,17 +97,91 @@
|
||||
order by d.id desc
|
||||
</select>
|
||||
|
||||
<!-- 根据条件查询 -->
|
||||
<select id="findDevices" resultType="com.fuyuanshen.equipment.domain.Device"
|
||||
parameterType="com.fuyuanshen.equipment.domain.query.DeviceQueryCriteria">
|
||||
SELECT d.*
|
||||
FROM device d
|
||||
<where>
|
||||
<!-- 时间范围等其他条件保持原样 -->
|
||||
<if test="criteria.deviceName != null and criteria.deviceName.trim() != ''">
|
||||
and d.device_name like concat('%', TRIM(#{criteria.deviceName}), '%')
|
||||
</if>
|
||||
<if test="criteria.deviceMac != null">
|
||||
and d.device_mac = #{criteria.deviceMac}
|
||||
</if>
|
||||
<if test="criteria.deviceImei != null">
|
||||
and d.device_imei = #{criteria.deviceImei}
|
||||
</if>
|
||||
<if test="criteria.deviceType != null">
|
||||
and d.device_type = #{criteria.deviceType}
|
||||
</if>
|
||||
<if test="criteria.deviceStatus != null">
|
||||
and d.device_status = #{criteria.deviceStatus}
|
||||
</if>
|
||||
<if test="criteria.currentOwnerId != null">
|
||||
and d.current_owner_id = #{criteria.currentOwnerId}
|
||||
</if>
|
||||
<if test="criteria.params.beginTime != null and criteria.params.endTime != null">
|
||||
and d.create_time between #{criteria.params.beginTime} and #{criteria.params.endTime}
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<!-- 查询APP绑定设备列表 -->
|
||||
<select id="queryAppBindDeviceList" resultType="com.fuyuanshen.equipment.domain.vo.AppDeviceVo">
|
||||
select d.id, d.device_name, d.device_name,
|
||||
d.device_name,
|
||||
d.device_mac,
|
||||
d.device_sn,
|
||||
d.device_imei,
|
||||
d.device_pic,
|
||||
dt.type_name,
|
||||
dt.communication_mode,
|
||||
d.bluetooth_name
|
||||
from device d
|
||||
inner join device_type dt on d.device_type = dt.id
|
||||
where d.binding_user_id = #{criteria.bindingUserId}
|
||||
<if test="criteria.deviceType != null">
|
||||
and d.device_type = #{criteria.deviceType}
|
||||
</if>
|
||||
<if test="criteria.deviceName != null">
|
||||
and d.device_name = #{criteria.deviceName}
|
||||
</if>
|
||||
<if test="criteria.deviceMac != null">
|
||||
and d.device_mac = #{criteria.deviceMac}
|
||||
</if>
|
||||
<if test="criteria.deviceImei != null">
|
||||
and d.device_imei = #{criteria.deviceImei}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
|
||||
<select id="queryAppDeviceList" resultType="com.fuyuanshen.equipment.domain.vo.AppDeviceVo">
|
||||
select d.id,
|
||||
d.device_name,
|
||||
d.device_mac,
|
||||
d.device_sn,
|
||||
d.device_imei,
|
||||
d.device_mac,
|
||||
dt.communication_mode
|
||||
d.device_name,
|
||||
d.device_mac,
|
||||
d.device_sn,
|
||||
d.device_imei,
|
||||
d.device_pic,
|
||||
dt.type_name,
|
||||
dt.communication_mode,
|
||||
d.bluetooth_name
|
||||
from device d
|
||||
inner join device_type dt on d.device_type = dt.id
|
||||
inner join device_type dt on d.device_type = dt.id
|
||||
where d.binding_user_id = #{criteria.bindingUserId}
|
||||
<if test="criteria.deviceType != null">
|
||||
and d.device_type = #{criteria.deviceType}
|
||||
</if>
|
||||
<if test="criteria.deviceName != null">
|
||||
and d.device_name = #{criteria.deviceName}
|
||||
</if>
|
||||
<if test="criteria.deviceMac != null">
|
||||
and d.device_mac = #{criteria.deviceMac}
|
||||
</if>
|
||||
<if test="criteria.deviceImei != null">
|
||||
and d.device_imei = #{criteria.deviceImei}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<!-- 获取分配设备的客户 -->
|
||||
|
@ -42,4 +42,14 @@
|
||||
WHERE owner_customer_id = #{customerId}
|
||||
AND original_device_id = #{deviceType}
|
||||
</select>
|
||||
|
||||
<!-- 根据名称查询设备类型 -->
|
||||
<select id="queryByName" resultMap="BaseResultMap"
|
||||
parameterType="com.fuyuanshen.equipment.domain.query.DeviceTypeQueryCriteria">
|
||||
SELECT dt.*, dg.id AS grant_id
|
||||
FROM device_type dt
|
||||
JOIN device_type_grants dg ON dt.id = dg.device_type_id
|
||||
WHERE dt.type_name = #{criteria.typeName}
|
||||
AND dg.customer_id = #{criteria.customerId}
|
||||
</select>
|
||||
</mapper>
|
@ -26,6 +26,9 @@ public class MqttConfiguration {
|
||||
options.setUserName(mqttPropertiesConfig.getUsername());
|
||||
options.setPassword(mqttPropertiesConfig.getPassword().toCharArray());
|
||||
options.setServerURIs(new String[]{mqttPropertiesConfig.getUrl()});
|
||||
options.setAutomaticReconnect(true); // 启用自动重连
|
||||
options.setConnectionTimeout(10); // 设置连接超时时间
|
||||
options.setKeepAliveInterval(60); // 设置心跳间隔
|
||||
factory.setConnectionOptions(options);
|
||||
return factory;
|
||||
}
|
||||
|
12
pom.xml
12
pom.xml
@ -37,6 +37,8 @@
|
||||
<lombok.version>1.18.36</lombok.version>
|
||||
<bouncycastle.version>1.80</bouncycastle.version>
|
||||
<justauth.version>1.16.7</justauth.version>
|
||||
|
||||
<javacv-platform.version>1.5.7</javacv-platform.version>
|
||||
<!-- 离线IP地址定位库 -->
|
||||
<ip2region.version>2.7.0</ip2region.version>
|
||||
|
||||
@ -94,6 +96,10 @@
|
||||
<monitor.username>fys</monitor.username>
|
||||
<monitor.password>123456</monitor.password>
|
||||
</properties>
|
||||
<!-- <activation> -->
|
||||
<!-- <!– 默认环境 –> -->
|
||||
<!-- <activeByDefault>true</activeByDefault> -->
|
||||
<!-- </activation> -->
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
@ -138,6 +144,12 @@
|
||||
<version>${justauth.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>javacv-platform</artifactId>
|
||||
<version>${javacv-platform.version}</version> <!-- 使用合适的版本号 -->
|
||||
</dependency>
|
||||
|
||||
<!-- common 的依赖配置-->
|
||||
<dependency>
|
||||
<groupId>com.fuyuanshen</groupId>
|
||||
|
Reference in New Issue
Block a user