20260518:1、分享设备删除只删除当前分享记录;2、大屏enter登录,去掉输入框默认账号密码

This commit is contained in:
George 2026-05-18 21:37:40 +08:00
parent 982ab8a56a
commit 32c0c86584
7 changed files with 213 additions and 48 deletions

View File

@ -149,6 +149,7 @@ public class DevicePropFetchConsumer {
if (StringUtils.isNotEmpty(tcpObject)) {
// 原有的事务ID处理逻辑
log.info("tcpObject[{}],处理Modbus tcp事务ID", tcpObject);
String tcpRuntimeCacheKey = RedisKeyBuilder.buildModbusTcpRuntimeCacheKey(subSerialNumber);
for (String command : commandList) {
String tranNo = command.substring(0, 4);
@ -156,12 +157,14 @@ public class DevicePropFetchConsumer {
Object stringHashValue = redisCache.getStringHashValue(tcpRuntimeCacheKey, String.valueOf(i));
if (Objects.nonNull(stringHashValue)) {
tcpCommandList.add(command);
log.info("command[{}],添加Modbus原指令", command);
continue;
}
String modbusTcpId = redisCache.getCacheModbusTcpId(modbusJobList.get(0).getSubSerialNumber());
String hexString = String.format("%04x", Integer.parseInt(modbusTcpId));
String newTcpData = hexString + command.substring(4);
redisCache.cacheModbusTcpData(subSerialNumber, modbusTcpId, newTcpData);
log.info("command[{}],添加Modbus修改后的指令", newTcpData);
tcpCommandList.add(newTcpData);
}
}
@ -172,14 +175,15 @@ public class DevicePropFetchConsumer {
} else {
modbusPollMsg.setCommandList(tcpCommandList);
}
DeviceStatusVO deviceStatusVO = deviceService.selectDeviceStatusAndTransportStatus(modbusPollMsg.getSerialNumber());
String serialNumber = modbusPollMsg.getSerialNumber();
DeviceStatusVO deviceStatusVO = deviceService.selectDeviceStatusAndTransportStatus(serialNumber);
modbusPollMsg.setTransport(deviceStatusVO.getTransport());
Session session = sessionStore.getSession(modbusPollMsg.getSerialNumber());
Session session = sessionStore.getSession(serialNumber);
if (enabled && Objects.isNull(session)) {
log.info("设备:[{}],不在线", modbusPollMsg.getSerialNumber());
log.info("设备:[{}],不在线", serialNumber);
return modbusPollMsg;
}
log.info("执行modbus轮询指令:[{}]", JSON.toJSONString(commandList));
log.info("jobId[{}],serialNumber[{}],执行modbus轮询指令:[{}]", jobId, serialNumber, JSON.toJSONString(modbusPollMsg.getCommandList()));
return modbusPollMsg;
}

View File

@ -1,14 +1,13 @@
package com.fastbee.iot.mapper;
import java.util.List;
import com.fastbee.common.core.domain.entity.SysUser;
import com.fastbee.framework.mybatis.mapper.BaseMapperX;
import com.fastbee.iot.domain.DeviceUser;
import com.fastbee.iot.model.UserIdDeviceIdModel;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* 设备用户Mapper接口
*
@ -57,6 +56,14 @@ public interface DeviceUserMapper {
*/
public int updateDeviceUser(DeviceUser deviceUser);
/**
* 批量修改设备用户
*
* @param deviceUserList 设备用户
* @return 结果
*/
int updateDeviceUserBatch(List<DeviceUser> deviceUserList);
/**
* 删除设备用户
*

View File

@ -342,12 +342,14 @@ public class DeviceServiceImpl implements IDeviceService {
Device device = deviceMapper.selectDeviceByDeviceId(deviceId);
SysUser user = getLoginUser().getUser();
Long sceneUserId;
Long deptUserId = user.getDept().getDeptUserId();
if (null == user.getDeptId()) {
sceneUserId = user.getUserId();
} else {
sceneUserId = user.getDept().getDeptUserId();
sceneUserId = deptUserId;
}
// 2.3版本更改 设备管理者和设备拥有者为true,普通用户如果不是设备所有者,只能删除设备用户和用户自己的设备关联分组信息
// 删除当前层级分配记录,将设备改回到上一级
boolean isGeneralUser;
if (isAdmin(user.getUserId())) {
isGeneralUser = false;
@ -355,7 +357,7 @@ public class DeviceServiceImpl implements IDeviceService {
// 终端用户和非设备所属机构用户不允许删除设备
if (null == user.getDeptId()) {
isGeneralUser = true;
} else if (!Objects.equals(device.getTenantId(), user.getDept().getDeptUserId())) {
} else if (!Objects.equals(device.getTenantId(), deptUserId)) {
isGeneralUser = true;
} else {
isGeneralUser = false;
@ -398,6 +400,23 @@ public class DeviceServiceImpl implements IDeviceService {
// 删除用户分组中的设备 普通用户,且不是设备所有者。
deviceMapper.deleteDeviceGroupByDeviceId(new UserIdDeviceIdModel(user.getUserId(), deviceId));
} else {
// 删除当前层级分配记录,将设备改回到上一级
DeviceRecord params = new DeviceRecord();
params.setDeviceId(deviceId);
params.setType(DeviceRecordTypeEnum.ASSIGNMENT_DETAIL.getType());
params.setTargetDeptId(user.getDeptId());
List<DeviceRecord> deviceRecords = deviceRecordMapper.selectDeviceRecordList(params);
if (!CollectionUtils.isEmpty(deviceRecords)) {
DeviceRecord deviceRecord = deviceRecords.get(0);
if (deviceRecord.getTargetDeptId().equals(user.getDeptId())) {
deviceRecordMapper.deleteDeviceRecordById(deviceRecord.getId());
int result = deviceMapper.updateTenantIdByDeptIds(deviceRecord.getTenantId(), deviceRecord.getTenantName(), Collections.singletonList(deviceId));
if (result > 0) {
return AjaxResult.success("已解除设备分享关系");
}
}
}
if (null != shareSceneIds && shareSceneIds.length > 0) {
sceneService.deleteSceneBySceneIds(shareSceneIds);
}
@ -1896,24 +1915,31 @@ public class DeviceServiceImpl implements IDeviceService {
@Override
public AjaxResult assignment(Long deptId, String deviceIds) {
SysUser user = getLoginUser().getUser();
SysDept sysDept = sysDeptMapper.selectDeptById(deptId);
if (null == sysDept || null == sysDept.getDeptUserId()) {
SysUser currSysUser = getLoginUser().getUser();
// 目标机构
SysDept destSysDept = sysDeptMapper.selectDeptById(deptId);
if (null == destSysDept || null == destSysDept.getDeptUserId()) {
return AjaxResult.error("机构不存在或未绑定管理员,请调整后重试!");
}
Long deptUserId = sysDept.getDeptUserId();
SysUser sysUser = userService.selectUserById(deptUserId);
if (null == sysUser) {
Long destDeptUserId = destSysDept.getDeptUserId();
SysUser destSysUser = userService.selectUserById(destDeptUserId);
if (null == destSysUser) {
return AjaxResult.error("机构管理员不存在");
}
List<Long> deviceIdList = Arrays.stream(deviceIds.split(",")).map(d -> Long.parseLong(d.trim())).distinct()
List<Long> deviceIdList = Arrays.stream(deviceIds.split(","))
.map(d -> Long.parseLong(d.trim())).distinct()
.collect(Collectors.toList());
int result = deviceMapper.updateTenantIdByDeptIds(deptUserId, sysUser.getUserName(), deviceIdList);
int result = deviceMapper.updateTenantIdByDeptIds(destDeptUserId, destSysUser.getUserName(), deviceIdList);
DeviceRecord deviceRecord = new DeviceRecord();
deviceRecord.setOperateDeptId(user.getDeptId()).setTargetDeptId(deptId).setTargetDeptId(deptId)
Long currDeptUserId = currSysUser.getDept().getDeptUserId();
Long currDeptId = currSysUser.getDeptId();
deviceRecord.setOperateDeptId(currDeptId)
.setTargetDeptId(deptId)
.setDistributeType(DeviceDistributeTypeEnum.SELECT.getType())
.setType(DeviceRecordTypeEnum.ASSIGNMENT.getType()).setTotal(deviceIdList.size())
.setTenantId(user.getDept().getDeptUserId()).setTenantName(user.getDept().getDeptUserName());
.setType(DeviceRecordTypeEnum.ASSIGNMENT.getType())
.setTotal(deviceIdList.size())
.setTenantId(currDeptUserId)
.setTenantName(currSysUser.getDept().getDeptUserName());
if (result > 0) {
deviceRecord.setStatus(StatusEnum.SUCCESS.getStatus());
deviceRecord.setSuccessQuantity(deviceIdList.size());
@ -1923,54 +1949,63 @@ public class DeviceServiceImpl implements IDeviceService {
deviceRecord.setSuccessQuantity(0);
deviceRecord.setFailQuantity(deviceIdList.size());
}
deviceRecord.setCreateBy(user.getUserName());
deviceRecord.setCreateBy(currSysUser.getUserName());
int insertRecordStatus = deviceRecordMapper.insertDeviceRecord(deviceRecord);
List<DeviceRecord> deviceRecordList = new ArrayList<>();
List<Device> deviceList = deviceMapper.selectDeviceListByDeviceIds(deviceIdList);
for (Device device : deviceList) {
DeviceRecord deviceRecord1 = new DeviceRecord();
deviceRecord1.setOperateDeptId(user.getDeptId()).setTargetDeptId(deptId).setDeviceId(device.getDeviceId())
.setProductId(device.getProductId()).setSerialNumber(device.getSerialNumber())
.setType(DeviceRecordTypeEnum.ASSIGNMENT_DETAIL.getType()).setParentId(deviceRecord.getId())
DeviceRecord deviceRecordDetail = new DeviceRecord();
deviceRecordDetail.setOperateDeptId(currDeptId)
.setTargetDeptId(deptId)
.setDeviceId(device.getDeviceId())
.setProductId(device.getProductId())
.setSerialNumber(device.getSerialNumber())
.setType(DeviceRecordTypeEnum.ASSIGNMENT_DETAIL.getType())
.setParentId(deviceRecord.getId())
.setDistributeType(DeviceDistributeTypeEnum.SELECT.getType())
.setTenantId(user.getDept().getDeptUserId()).setTenantName(user.getDept().getDeptUserName());
deviceRecord1
.setStatus(insertRecordStatus > 0 ? StatusEnum.SUCCESS.getStatus() : StatusEnum.FAIL.getStatus());
deviceRecord1.setCreateBy(user.getUserName());
deviceRecordList.add(deviceRecord1);
.setTenantId(currDeptUserId)
.setTenantName(currSysUser.getDept().getDeptUserName())
.setStatus(insertRecordStatus > 0 ? StatusEnum.SUCCESS.getStatus() : StatusEnum.FAIL.getStatus())
.setCreateBy(currSysUser.getUserName());
deviceRecordList.add(deviceRecordDetail);
}
// 批量插入设备分配记录
deviceRecordMapper.insertBatch(deviceRecordList);
return result > 0 ? AjaxResult.success("分配设备成功") : AjaxResult.error("分配设备失败");
}
@Override
public AjaxResult recovery(String deviceIds, Long recoveryDeptId) {
LoginUser loginUser = getLoginUser();
Long deptId = loginUser.getDeptId();
SysDept sysDept = sysDeptMapper.selectDeptById(deptId);
if (null == sysDept || null == sysDept.getDeptUserId()) {
SysUser currSysUser = getLoginUser().getUser();
Long currDeptId = currSysUser.getDeptId();
SysDept currSysDept = sysDeptMapper.selectDeptById(currDeptId);
if (null == currSysDept || null == currSysDept.getDeptUserId()) {
return AjaxResult.error("机构不存在或未绑定管理员,请调整后重试!");
}
Long deptUserId = sysDept.getDeptUserId();
SysUser sysUser = userService.selectUserById(deptUserId);
Long currDeptUserId = currSysDept.getDeptUserId();
SysUser sysUser = userService.selectUserById(currDeptUserId);
if (null == sysUser) {
return AjaxResult.error("机构管理员不存在");
}
List<Long> deviceIdList = Arrays.stream(deviceIds.split(",")).map(d -> Long.parseLong(d.trim())).distinct()
List<Long> deviceIdList = Arrays.stream(deviceIds.split(","))
.map(d -> Long.parseLong(d.trim())).distinct()
.collect(Collectors.toList());
int result = deviceMapper.updateTenantIdByDeptIds(deptUserId, sysUser.getUserName(), deviceIdList);
int result = deviceMapper.updateTenantIdByDeptIds(currDeptUserId, sysUser.getUserName(), deviceIdList);
List<DeviceRecord> deviceRecordList = new ArrayList<>();
List<Device> deviceList = deviceMapper.selectDeviceListByDeviceIds(deviceIdList);
for (Device device : deviceList) {
DeviceRecord deviceRecord1 = new DeviceRecord();
deviceRecord1.setOperateDeptId(deptId).setTargetDeptId(recoveryDeptId).setDeviceId(device.getDeviceId())
.setProductId(device.getProductId()).setSerialNumber(device.getSerialNumber())
DeviceRecord deviceRecord = new DeviceRecord();
deviceRecord.setOperateDeptId(currDeptId)
.setTargetDeptId(recoveryDeptId)
.setDeviceId(device.getDeviceId())
.setProductId(device.getProductId())
.setSerialNumber(device.getSerialNumber())
.setType(DeviceRecordTypeEnum.RECOVERY.getType())
.setTenantId(loginUser.getUser().getDept().getDeptUserId())
.setTenantName(loginUser.getUser().getDept().getDeptUserName());
deviceRecord1.setStatus(result > 0 ? StatusEnum.SUCCESS.getStatus() : StatusEnum.FAIL.getStatus());
deviceRecord1.setCreateBy(loginUser.getUsername());
deviceRecordList.add(deviceRecord1);
.setTenantId(currSysUser.getDept().getDeptUserId())
.setTenantName(currSysUser.getDept().getDeptUserName())
.setStatus(result > 0 ? StatusEnum.SUCCESS.getStatus() : StatusEnum.FAIL.getStatus())
.setCreateBy(currSysUser.getUserName());
deviceRecordList.add(deviceRecord);
}
deviceRecordMapper.insertBatch(deviceRecordList);
return result > 0 ? AjaxResult.success("回收设备成功") : AjaxResult.error("回收设备失败");

View File

@ -52,6 +52,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
and create_time between #{params.beginTime} and #{params.endTime}
</if>
</where>
order by create_time desc
</select>
<select id="selectDeviceRecordById" parameterType="Long" resultMap="DeviceRecordResult">

View File

@ -125,6 +125,22 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where device_id = #{deviceId} and user_id = #{userId}
</update>
<update id="updateDeviceUserBatch" parameterType="java.util.List">
<foreach collection="list" item="item" separator=";">
update iot_device_user
<trim prefix="SET" suffixOverrides=",">
<if test="item.userId != null">user_id = #{item.userId},</if>
<if test="item.userName != null">user_id = #{item.userName},</if>
<if test="item.phonenumber != null">phonenumber = #{item.phonenumber},</if>
<if test="item.delFlag != null">del_flag = #{item.delFlag},</if>
<if test="item.updateBy != null">update_by = #{item.updateBy},</if>
<if test="item.updateTime != null">update_time = #{item.updateTime},</if>
<if test="item.remark != null">remark = #{item.remark},</if>
</trim>
where device_id = #{item.deviceId}
</foreach>
</update>
<delete id="deleteDeviceUserByDeviceId" parameterType="com.fastbee.iot.model.UserIdDeviceIdModel">
delete from iot_device_user
<where>

View File

@ -0,0 +1,101 @@
# FastBee 驾驶舱制作指南
> 5分钟上手,只讲操作,不讲原理
---
## 一、登录
1. 打开 yack-view 地址
2. 用管理后台的账号密码登录
---
## 二、新建大屏
1. 点击「新建项目」
2. 输入名字,比如「车间监控大屏」
3. 点「确定」
---
## 三、做界面
编辑器左侧是组件库,拖拽到中间画布:
| 组件 | 用来做什么 |
|-----|-----------|
| 柱状图 | 对比数据高低 |
| 折线图 | 看趋势变化 |
| 饼图 | 看占比 |
| 仪表盘 | 看完成率 |
| 数字翻牌 | 显示单个关键数字 |
| 边框 | 装饰用 |
**操作:**
- 拖拽移动位置
- 拉边框角落调整大小
- 点组件 → 右侧修改内容
---
## 四、接入真实数据(重点)
点击组件 → 右侧「数据」标签:
### 方式1:静态数据
手动输入数字,适用于演示。直接改 JSON 里的数值。
### 方式2:对接 FastBee 数据(常用)
选择「Ajax 请求」:
```
请求地址: /prod-api/接口路径
刷新间隔: 30秒(数据多久更新一次)
```
**常用接口:**
| 你想展示 | 接口路径 |
|---------|---------|
| 设备在线数 | /device/online/count |
| 设备列表 | /device/list |
| 设备统计数据 | /device/stat |
| 告警列表 | /alert/list |
| 产品列表 | /product/list |
> 具体接口去 FastBee 管理后台的 Swagger 文档里查
### 方式3:数据池(多个图表用同一份数据)
1. 先创建一个数据池,配好 Ajax
2. 其他组件选「数据池」,绑定到这个池
---
## 五、保存和预览
- 顶部「💾 保存」:保存修改
- 顶部「👁 预览」:看实际效果
---
## 六、发布分享
1. 项目列表点「发布」
2. 复制生成的链接发给别人
---
## 七、常见问题
**Q:图表显示空白**
> 检查数据源配置对不对,接口能不能调通
**Q:数据不刷新**
> 确保点了「刷新间隔」,设置具体秒数
---
> 有问题找开发人员

View File

@ -55,6 +55,7 @@
size="large"
:model="formInline"
:rules="rules"
@keyup.enter="handleSubmit"
>
<n-form-item path="username">
<n-input
@ -169,8 +170,8 @@ const systemStore = useSystemStore()
const t = window['$t']
const formInline = reactive({
username: 'admin',
password: 'admin123',
username: '',
password: '',
code: '',
uuid: ''
})