帝可得 - 设备管理
一. 需求说明
设备管理主要涉及到三个功能模块,业务流程如下:
-
新增设备类型: 允许管理员定义新的售货机型号,包括其规格和容量。
-
新增设备: 在新的设备类型定义后,系统应允许添加新的售货机实例,并将它们分配到特定的点位。
-
新增货道: 对于每个新添加的设备,系统应支持定义新的货道,后期用于关联相应的商品SKU。
graph TD A[登录系统] A --> B[新增设备类型] B --> C[新增设备] C --> D[新增货道]
对于设备和其他管理数据,下面是示意图:
-
关系字段:vm_type_id、node_id、vm_id
-
数据字典:vm_status(0未投放、1运营、3撤机)
-
冗余字段:addr、business_type、region_id、partner_id(简化查询接口、提高查询效率)
二. 生成基础代码
2.1 需求
使用若依代码生成器,生成设备类型、设备、货道前后端基础代码,并导入到项目中
2.2 步骤
2.2.1 创建目录菜单
2.2.2 添加数据字典
2.2.3 配置代码生成信息
导入表
设备类型代码配置
设备代码设置
售货机管道代码改造,售货机没有特有的页面原型,只在设备管理中有货道设置页面,所以需要修改字段信息,默认就行
2.2.4 下载代码并导入项目
执行sql
前后端代码
重启项目,查看增删改查有没有问题
这里的设备照片不显示很正常,因为我们的阿里云OSS没有设备照片😂修改完就可以显示照片了
三. 设备类型改造
参考页面原型,完成基础布局展示改造
Element Plus官网:一个 Vue 3 UI 框架 | Element Plus
实现
在vmType/index.vue视图组件中修改
搜索
重置
修改
删除
行
列
个
测试新增成功
四. 设备管理改造
4.1 基础页面改造
4.1.1 需求
参考页面原型,完成基础布局展示改造
4.1.2 实现
-
刷新设备表数据,使设备的详细地址和点位地址对应好
update tb_vending_machine set partner_id=2 where id=80;
update tb_vending_machine set addr=(select address from tb_node where id = 1) where node_id=1;
update tb_vending_machine set addr=(select address from tb_node where id = 2) where node_id=2;
-
在vm/index.vue视图组件中修改
-
修改合作商和设备状态的展示方式
使用后端进行搜索查询返回的话会很麻烦,所以这里可以让后端查询所有的合作商和设备状态返回前端进行存储,使用v-for进行遍历,v-if进行判断,如果查询到的id等于当前行id的话,就拿到名称返回到页面进行展示
-
在vm/index.vue视图组件中修改
parseTime(form.lastSupplyTime, '{y}-{m}-{d} {h}:{i}:{s}') 可以修改日期展示格式
搜索
重置
{{ item.name }}
{{ item.partnerName }}
修改
{{ form.innerCode == null ? '系统自动生成' : form.innerCode }}
{{ parseTime(form.lastSupplyTime, '{y}-{m}-{d} {h}:{i}:{s}') }}
{{ item.name }}
{{ form.channelMaxCapacity }}
{{ item.partnerName }}
{{ item.regionName }}
{{ form.addr }}
4.2 新增设备改造
4.2.1 需求
新增设备时,补充设备表其他字段信息,还需要根据售货机类型创建所属货道
我们了解到在新增设备时,添加设备和货道表,还包含点位和设备类型的查询,共涉及到四张表的操作。
这个过程需要我们仔细处理每个字段,确保数据的一致性和完整性
4.2.2 实现
-
VendingMachineServiceImpl
@Autowired
private INodeService nodeService;
@Autowired
private IVmTypeService vmTypeService;
@Autowired
private IChannelService channelService;
/**
* 新增设备管理
*
* @param vendingMachine 设备管理
* @return 结果
*/
@Transactional
@Override
public int insertVendingMachine(VendingMachine vendingMachine) {
//1. 新增设备
//1-1 生成8位编号,补充货道编号
String innerCode = UUIDUtils.getUUID();
vendingMachine.setInnerCode(innerCode); // 售货机编号
//1-2 查询售货机类型表,补充设备容量
VmType vmType = vmTypeService.selectVmTypeById(vendingMachine.getVmTypeId());
vendingMachine.setChannelMaxCapacity(vmType.getChannelMaxCapacity());
//1-3 查询点位表,补充 区域、点位、合作商等信息
Node node = nodeService.selectNodeById(vendingMachine.getNodeId());
BeanUtil.copyProperties(node, vendingMachine, "id");
vendingMachine.setAddr(node.getAddress());
//1-4 设备状态
vendingMachine.setVmStatus(DkdContants.VM_STATUS_NODEPLOY);// 0-未投放(数据库有默认值,这个不写也不影响)
vendingMachine.setCreateTime(DateUtils.getNowDate());// 创建时间
vendingMachine.setUpdateTime(DateUtils.getNowDate());// 更新时间
//1-5 保存
int result = vendingMachineMapper.insertVendingMachine(vendingMachine);
//2. 新增货道
//2-1 声明货道集合
List channelList = new ArrayList<>();
//2-2 双层for循环
for (int i = 1; i <= vmType.getVmRow(); i++) { // 外层行
for (int j = 1; j <= vmType.getVmCol(); j++) {// 内层列
//2-3 封装channel
Channel channel = new Channel();
channel.setChannelCode(i + "-" + j);// 货道编号
channel.setVmId(vendingMachine.getId());// 售货机id
channel.setInnerCode(vendingMachine.getInnerCode());// 售货机编号
channel.setMaxCapacity(vmType.getChannelMaxCapacity());// 货道最大容量
channel.setCreateTime(DateUtils.getNowDate());// 创建时间
channel.setUpdateTime(DateUtils.getNowDate());// 更新时间
channelList.add(channel);
}
}
//2-4 批量新增
channelService.batchInsertChannel(channelList);
return result;
}
-
ChannelMapper接口
/**
* 批量新增售货机货道
* @param channelList
* @return 结果
*/
public int batchInsertChannel(List channelList);
ChannelMapper.xml
INSERT INTO tb_channel (
channel_code, vm_id, inner_code, max_capacity, current_capacity, last_supply_time, create_time, update_time
) VALUES
(
#{channel.channelCode},
#{channel.vmId},
#{channel.innerCode},
#{channel.maxCapacity},
#{channel.currentCapacity},
#{channel.lastSupplyTime},
#{channel.createTime},
#{channel.updateTime}
)
IChannelService
/**
* 批量新增售货机货道
* @param channelList
* @return 结果
*/
public int batchInsertChannel(List channelList);
IChannelServiceImpl实现类
/**
* 批量新增售货机货道
* @param channelList
* @return 结果
*/
@Override
public int batchInsertChannel(List channelList) {
return channelMapper.batchInsertChannel(channelList);
}
4.3 修改设备改造
4.3.1 需求
修改设备时,根据点位同步更新冗余字段信息
根据前端提交的点位ID,后端需要查询点位表,来获取点位的详细信息,包括详细地址、商圈类型、区域ID和合作商ID,获取到点位信息后,我们需要更新设备表中的相关冗余字段。
4.3.2 实现
-
VendingMachineServiceImpl实现类
/**
* 修改设备管理
*
* @param vendingMachine 设备管理
* @return 结果
*/
@Override
public int updateVendingMachine(VendingMachine vendingMachine)
{
// 查询点位表,补充:区域、点位、合作商等信息
Node node = nodeService.selectNodeById(vendingMachine.getNodeId());
BeanUtil.copyProperties(node,vendingMachine,"id"); // 商圈类型、区域、合作商
vendingMachine.setAddr(node.getAddress()); // 设备地址
vendingMachine.setUpdateTime(DateUtils.getNowDate()); // 更新时间
return vendingMachineMapper.updateVendingMachine(vendingMachine);
}
五. 设备状态改造
5.1 需求
-
为设备状态管理功能创建前端页面,并在若依框架中定义相应的路由和菜单项
-
基于原型完成视图组件基础布局展示改造
5.2 实现
-
在前端manage视图新建vmStatus页面
-
添加二级菜单
-
改造视图组件
搜索
重置
{{ item.name }}
{ JSON.parse(scope.row.runningStatus).status==true ? '正常' : '异常' }}
异常 -->
{{ scope.row.runningStatus != null?JSON.parse(scope.row.runningStatus).status==true ? '正常' : '异常': '异常'}}
查看详情
效果如下✌
六. 点位查看详情
6.1 需求
在点位管理点击查看详情时,可以在对话框查看设备的信息
6.2 实现
-
在node/index.vue视图组件中修改
查看详情
{{ parseTime(scope.row.lastSupplyTime, '{y}-{m}-{d} {h}:{i}:{s}') }}
注意:在查看详情定义了v-hasPermi,这里的权限对应的是想要实现功能的权限字符,如下图
效果如下✌