帝可得 - 设备管理
一. 需求说明
设备管理主要涉及到三个功能模块,业务流程如下:
-
新增设备类型: 允许管理员定义新的售货机型号,包括其规格和容量。
-
新增设备: 在新的设备类型定义后,系统应允许添加新的售货机实例,并将它们分配到特定的点位。
-
新增货道: 对于每个新添加的设备,系统应支持定义新的货道,后期用于关联相应的商品SKU。
graph TDA[登录系统] 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视图组件中修改
<!-- 查询条件 -->
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px"><el-form-item label="型号名称" prop="name"><el-input v-model="queryParams.name" placeholder="请输入型号名称" clearable @keyup.enter="handleQuery"/></el-form-item><el-form-item><el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button><el-button icon="Refresh" @click="resetQuery">重置</el-button></el-form-item>
</el-form>
<!-- 列表展示 -->
<el-table v-loading="loading" :data="vmTypeList" @selection-change="handleSelectionChange"><el-table-column type="selection" width="55" align="center" /><el-table-column label="型号名称" align="center" prop="name" /><el-table-column label="型号编码" align="center" prop="model" /><el-table-column label="设备图片" align="center" prop="image" width="100"><template #default="scope">
<image-preview :src="scope.row.image" :width="50" :height="50"/></template></el-table-column><el-table-column label="货道行" align="center" prop="vmRow" /><el-table-column label="货道列" align="center" prop="vmCol" /><el-table-column label="设备容量" align="center" prop="channelMaxCapacity" /><el-table-column label="操作" align="center" class-name="small-padding fixed-width"><template #default="scope"><el-button link type="primary" @click="handleUpdate(scope.row)" v-hasPermi="['manage:vmType:edit']">修改</el-button><el-button link type="primary" @click="handleDelete(scope.row)" v-hasPermi="['manage:vmType:remove']">删除</el-button></template></el-table-column>
</el-table>
<!-- 添加或修改设备类型管理对话框 -->
<el-dialog :title="title" v-model="open" width="500px" append-to-body><el-form ref="vmTypeRef" :model="form" :rules="rules" label-width="80px"><el-form-item label="型号名称" prop="name"><el-input v-model="form.name" placeholder="请输入型号名称" /></el-form-item><el-form-item label="型号编码" prop="model"><el-input v-model="form.model" placeholder="请输入型号编码" /></el-form-item><el-form-item label="货道数" prop="vmRow"><el-input-number v-model="form.vmRow" placeholder="请输入" :min="1" :max="10"/>行 <el-input-number v-model="form.vmCol" placeholder="请输入" :min="1" :max="10"/>列</el-form-item><el-form-item label="货道容量" prop="channelMaxCapacity"><el-input-number v-model="form.channelMaxCapacity" placeholder="请输入" :min="1" :max="10"/>个</el-form-item><el-form-item label="设备图片" prop="image"><image-upload v-model="form.image"/></el-form-item></el-form><template #footer><div class="dialog-footer"><el-button type="primary" @click="submitForm">确 定</el-button><el-button @click="cancel">取 消</el-button></div></template>
</el-dialog>
测试新增成功
四. 设备管理改造
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}') 可以修改日期展示格式
<!-- 查询条件 -->
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px"><el-form-item label="设备编号" prop="innerCode"><el-input v-model="queryParams.innerCode" placeholder="请输入设备编号" clearable @keyup.enter="handleQuery" /></el-form-item><el-form-item><el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button><el-button icon="Refresh" @click="resetQuery">重置</el-button></el-form-item>
</el-form>
<!-- 列表展示 -->
<el-table v-loading="loading" :data="vmList" @selection-change="handleSelectionChange"><el-table-column type="selection" width="55" align="center" /><el-table-column label="设备编号" align="center" prop="innerCode" /><el-table-column label="设备型号" align="center" prop="vmTypeId" ><template #default="scope"><div v-for="item in vmTypeList" :key="item.id"><span v-if="item.id==scope.row.vmTypeId">{{ item.name }}</span></div></template></el-table-column><el-table-column label="详细地址" align="center" prop="addr" /><el-table-column label="合作商" align="center" prop="partnerId" ><template #default="scope"><div v-for="item in partnerList" :key="item.id"><span v-if="item.id==scope.row.partnerId">{{ item.partnerName }}</span></div></template></el-table-column><el-table-column label="设备状态" align="center" prop="vmStatus"><template #default="scope"><dict-tag :options="vm_status" :value="scope.row.vmStatus" /></template></el-table-column><el-table-column label="操作" align="center" class-name="small-padding fixed-width"><template #default="scope"><el-button link type="primary" @click="handleUpdate(scope.row)" v-hasPermi="['manage:vm:edit']">修改</el-button></template></el-table-column>
</el-table>
<!-- 添加或修改设备管理对话框 -->
<el-dialog :title="title" v-model="open" width="500px" append-to-body><el-form ref="vmRef" :model="form" :rules="rules" label-width="80px"><el-form-item label="设备编号"><span>{{ form.innerCode == null ? '系统自动生成' : form.innerCode }}</span></el-form-item><el-form-item label="供货时间" v-if="form.innerCode != null"><span>{{ parseTime(form.lastSupplyTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span></el-form-item><el-form-item label="设备类型" v-if="form.innerCode != null"><div v-for="item in vmTypeList" :key="item.id"><span v-if="form.vmTypeId == item.id">{{ item.name }}</span></div></el-form-item><el-form-item label="设备容量" v-if="form.innerCode != null"><span>{{ form.channelMaxCapacity }}</span></el-form-item><el-form-item label="选择型号" prop="vmTypeId" v-if="form.innerCode == null"><!-- <el-input v-model="form.vmTypeId" placeholder="请输入设备型号" /> --><el-select v-model="form.vmTypeId" placeholder="请选择设备型号" style="width: 100%"><el-option v-for="item in vmTypeList" :key="item.id" :label="item.name" :value="item.id" /></el-select></el-form-item><el-form-item label="选择点位" prop="nodeId"><!-- <el-input v-model="form.nodeId" placeholder="请输入点位Id" /> --><el-select v-model="form.nodeId" placeholder="请选择点位" style="width: 100%"><el-option v-for="item in nodeList" :key="item.id" :label="item.nodeName" :value="item.id" /></el-select></el-form-item><el-form-item label="合作商" v-if="form.innerCode != null"><div v-for="item in partnerList" :key="item.id"><span v-if="form.partnerId == item.id">{{ item.partnerName }}</span></div></el-form-item><el-form-item label="所属区域" v-if="form.innerCode != null"><div v-for="item in regionList" :key="item.id"><span v-if="form.regionId == item.id">{{ item.regionName }}</span></div></el-form-item><el-form-item label="设备地址" v-if="form.innerCode != null"><span>{{ form.addr }}</span></el-form-item></el-form><template #footer><div class="dialog-footer"><el-button type="primary" @click="submitForm">确 定</el-button><el-button @click="cancel">取 消</el-button></div></template>
</el-dialog>
<script setup name="Vm">
import { listVmType } from "@/api/manage/vmType";
import { listPartner } from "@/api/manage/partner";
import { loadAllParams } from '@/api/page';
import { listNode } from '@/api/manage/node';
import { listRegion } from "@/api/manage/region";/* 查询设备类型列表 */
const vmTypeList = ref([]);
function getVmTypeList() {listVmType(loadAllParams).then((response) => {vmTypeList.value = response.rows;});
}
/* 查询合作商列表 */
const partnerList = ref([]);
function getPartnerList() {listPartner(loadAllParams).then((response) => {partnerList.value = response.rows;});
}
/* 查询点位列表 */
const nodeList = ref([]);
function getNodeList() {listNode(loadAllParams).then((response) => {nodeList.value = response.rows;});
}
/* 查询区域列表 */
const regionList = ref([]);
function getRegionList() {listRegion(loadAllParams).then((response) => {regionList.value = response.rows;});
}
getRegionList();
getPartnerList();
getNodeList();
getVmTypeList();</script>
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<Channel> channelList = new ArrayList<>();//2-2 双层for循环for (int i = 1; i <= vmType.getVmRow(); i++) { // 外层行for (int j = 1; j <= vmType.getVmCol(); j++) {// 内层列//2-3 封装channelChannel channel = new Channel();channel.setChannelCode(i + "-" + j);// 货道编号channel.setVmId(vendingMachine.getId());// 售货机idchannel.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<Channel> channelList);
ChannelMapper.xml<insert id="batchInsertChannel" parameterType="java.util.List">INSERT INTO tb_channel (channel_code, vm_id, inner_code, max_capacity, current_capacity, last_supply_time, create_time, update_time) VALUES<foreach collection="list" item="channel" separator=",">(#{channel.channelCode},#{channel.vmId},#{channel.innerCode},#{channel.maxCapacity},#{channel.currentCapacity},#{channel.lastSupplyTime},#{channel.createTime},#{channel.updateTime})</foreach>
</insert>
IChannelService/*** 批量新增售货机货道* @param channelList* @return 结果*/
public int batchInsertChannel(List<Channel> channelList);
IChannelServiceImpl实现类/*** 批量新增售货机货道* @param channelList* @return 结果*/
@Override
public int batchInsertChannel(List<Channel> channelList) {return channelMapper.batchInsertChannel(channelList);
}
4.3 修改设备改造
4.3.1 需求
修改设备时,根据点位同步更新冗余字段信息
根据前端提交的点位ID,后端需要查询点位表,来获取点位的详细信息,包括详细地址、商圈类型、区域ID和合作商ID,获取到点位信息后,我们需要更新设备表中的相关冗余字段。
4.3.2 实现
-
VendingMachineServiceImpl实现类
/*** 修改设备管理** @param vendingMachine 设备管理* @return 结果*/@Overridepublic 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页面
-
添加二级菜单
-
改造视图组件
<template><div class="app-container"><el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px"><el-form-item label="设备编号" prop="innerCode"><el-inputv-model="queryParams.innerCode"placeholder="请输入设备编号"clearable@keyup.enter="handleQuery"/></el-form-item><el-form-item><el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button><el-button icon="Refresh" @click="resetQuery">重置</el-button></el-form-item></el-form><el-table v-loading="loading" :data="vmList" @selection-change="handleSelectionChange"><el-table-column label="序号" type="index" width="55" align="center" /><el-table-column label="设备编号" align="center" prop="innerCode" /><el-table-column label="设备型号" align="center" prop="vmTypeId" ><template #default="scope"><div v-for="item in vmTypeList" :key="item.id"><span v-if="item.id==scope.row.vmTypeId">{{ item.name }}</span></div></template></el-table-column><el-table-column label="详细地址" align="left" prop="addr" show-overflow-tooltip="true" /><el-table-column label="运营状态" align="center" prop="vmStatus"><template #default="scope"><dict-tag :options="vm_status" :value="scope.row.vmStatus"/></template></el-table-column><el-table-column label="设备状态" align="center" prop="vmStatus"><template #default="scope"><!-- <span v-if="scope.row.runningStatus != null">{{ JSON.parse(scope.row.runningStatus).status==true ? '正常' : '异常' }}</span><span v-else>异常</span> -->{{ scope.row.runningStatus != null?JSON.parse(scope.row.runningStatus).status==true ? '正常' : '异常': '异常'}}</template></el-table-column><el-table-column label="操作" align="center" class-name="small-padding fixed-width"><template #default="scope"><el-button link type="primary" @click="getVmInfo(scope.row)" v-hasPermi="['manage:vm:query']">查看详情</el-button></template></el-table-column></el-table><paginationv-show="total>0":total="total"v-model:page="queryParams.pageNum"v-model:limit="queryParams.pageSize"@pagination="getList"/><!-- 添加或修改设备管理对话框 -->
<el-dialog :title="title" v-model="open" width="500px" append-to-body></el-dialog></div>
</template><script setup name="Vm">
import { listVm, getVm, delVm, addVm, updateVm } from "@/api/manage/vm";
import { listVmType } from "@/api/manage/vmType";
import { listPartner } from "@/api/manage/partner";
import { loadAllParams } from '@/api/page';
import { listNode } from '@/api/manage/node';
import { listRegion } from "@/api/manage/region";const { proxy } = getCurrentInstance();
const { vm_status } = proxy.useDict('vm_status');const vmList = ref([]);
const open = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const title = ref("");const data = reactive({form: {},queryParams: {pageNum: 1,pageSize: 10,innerCode: null,channelMaxCapacity: null,nodeId: null,businessType: null,regionId: null,partnerId: null,vmTypeId: null,vmStatus: null,runningStatus: null,policyId: null,},rules: {nodeId: [{ required: true, message: "点位Id不能为空", trigger: "blur" }],vmTypeId: [{ required: true, message: "设备型号不能为空", trigger: "blur" }],}
});const { queryParams, form, rules } = toRefs(data);/** 查询设备管理列表 */
function getList() {loading.value = true;listVm(queryParams.value).then(response => {vmList.value = response.rows;total.value = response.total;loading.value = false;});
}// ------------------------------------
/* 查询设备类型列表 */
const vmTypeList = ref([]);
function getVmTypeList() {listVmType(loadAllParams).then((response) => {vmTypeList.value = response.rows;});
}
/* 查询合作商列表 */
const partnerList = ref([]);
function getPartnerList() {listPartner(loadAllParams).then((response) => {partnerList.value = response.rows;});
}
/* 查询点位列表 */
const nodeList = ref([]);
function getNodeList() {listNode(loadAllParams).then((response) => {nodeList.value = response.rows;});
}
/* 查询区域列表 */
const regionList = ref([]);
function getRegionList() {listRegion(loadAllParams).then((response) => {regionList.value = response.rows;});
}
getRegionList();
getPartnerList();
getNodeList();
getVmTypeList();
//-----------------------------------------// 取消按钮
function cancel() {open.value = false;reset();
}// 表单重置
function reset() {form.value = {id: null,innerCode: null,channelMaxCapacity: null,nodeId: null,addr: null,lastSupplyTime: null,businessType: null,regionId: null,partnerId: null,vmTypeId: null,vmStatus: null,runningStatus: null,longitudes: null,latitude: null,clientId: null,policyId: null,createTime: null,updateTime: null};proxy.resetForm("vmRef");
}/** 搜索按钮操作 */
function handleQuery() {queryParams.value.pageNum = 1;getList();
}/** 重置按钮操作 */
function resetQuery() {proxy.resetForm("queryRef");handleQuery();
}// 多选框选中数据
function handleSelectionChange(selection) {ids.value = selection.map(item => item.id);single.value = selection.length != 1;multiple.value = !selection.length;
}/** 新增按钮操作 */
function handleAdd() {reset();open.value = true;title.value = "添加设备管理";
}/** 修改按钮操作 */
function getVmInfo(row) {reset();const _id = row.id || ids.valuegetVm(_id).then(response => {form.value = response.data;open.value = true;title.value = "设备详情";});
}/** 提交按钮 */
function submitForm() {proxy.$refs["vmRef"].validate(valid => {if (valid) {if (form.value.id != null) {updateVm(form.value).then(response => {proxy.$modal.msgSuccess("修改成功");open.value = false;getList();});} else {addVm(form.value).then(response => {proxy.$modal.msgSuccess("新增成功");open.value = false;getList();});}}});
}/** 删除按钮操作 */
function handleDelete(row) {const _ids = row.id || ids.value;proxy.$modal.confirm('是否确认删除设备管理编号为"' + _ids + '"的数据项?').then(function() {return delVm(_ids);}).then(() => {getList();proxy.$modal.msgSuccess("删除成功");}).catch(() => {});
}/** 导出按钮操作 */
function handleExport() {proxy.download('manage/vm/export', {...queryParams.value}, `vm_${new Date().getTime()}.xlsx`)
}getList();
</script>
效果如下✌
六. 点位查看详情
6.1 需求
在点位管理点击查看详情时,可以在对话框查看设备的信息
6.2 实现
-
在node/index.vue视图组件中修改
<el-button link type="primary" @click="getNodeInfo(scope.row)" v-hasPermi="['manage:vm:list']">查看详情</el-button><!-- 点位详情对话框 -->
<el-dialog title="点位详情" v-model="nodeOpen" width="600px" append-to-body><el-table :data="vmList"><el-table-column label="序号" type="index" width="80" align="center" prop="id" /><el-table-column label="设备编号" align="center" prop="innerCode" /><el-table-column label="设备状态" align="center" prop="vmStatus"><template #default="scope"><dict-tag :options="vm_status" :value="scope.row.vmStatus" /></template></el-table-column><el-table-column label="最后一次供货时间" align="center" prop="lastSupplyTime" width="180"><template #default="scope">
<!-- parseTime 是一个函数,用于格式化时间戳 --><span>{{ parseTime(scope.row.lastSupplyTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span></template></el-table-column></el-table>
</el-dialog><script setup name="Node">
import { listVm } from "@/api/manage/vm";
const { proxy } = getCurrentInstance();
/* 引入设备状态数据字典 */
const { vm_status } = proxy.useDict('vm_status');/* 查看详情 */
const nodeOpen = ref(false);
const vmList = ref([]);
function getNodeInfo(row) {// 根据点位id,查询设备列表loadAllParams.nodeId = row.id;listVm(loadAllParams).then(response => {vmList.value = response.rows;nodeOpen.value = true;});
}
</script>
注意:在查看详情定义了v-hasPermi,这里的权限对应的是想要实现功能的权限字符,如下图
效果如下✌
相关文章:

帝可得 - 设备管理
一. 需求说明 设备管理主要涉及到三个功能模块,业务流程如下: 新增设备类型: 允许管理员定义新的售货机型号,包括其规格和容量。 新增设备: 在新的设备类型定义后,系统应允许添加新的售货机实例,并将它们分配到特定的…...
FTXUI配置
对于 FTXUI 的安装与配置, 官方已经给出了三种方案. 第一种: 使用 FetchContent 远程拉取第二种: 在你本地安装 FTXUI 库, 然后通过 find_package 使用第三种: 使用 Git 子模块 FetchContent 无需手动下载安装 FTXUI, 通过 CMake 自动从 GitHub 拉取并编译依赖 include(Fet…...
Caliper压力测试
目前FISCO BCOS适配的Caliper版本为0.2.0,请在部署Caliper运行环境时确保Caliper的版本为0.2.0,如在部署或使用过程中遇到任何问题,请优先参考 https://github.com/FISCO-BCOS/FISCO-BCOS/issues/1248 中的解决方案进行排查。 1. 环境要求 …...

【iOS安全】使用LLDB调试iOS App | LLDB基本架构 | LLDB安装和配置
LLDB基本架构 参考: https://crifan.github.io/ios_re_dynamic_debug/website/debug_code/lldb_debugserver.html https://book.crifan.org/books/ios_re_debug_debugserver_lldb/website/ LLDB安装和配置 1. 让iPhone中出现/Developer/usr/bin/debugserver 最初…...
一、核心概念深入解析
一、核心概念深入解析 1. shared_ptr 的线程安全性澄清 引用计数是原子操作:shared_ptr 的引用计数(use_count)在多线程中递增 / 递减是安全的(原子操作),但对象本身的读写需额外同步(如 std:…...
python直方图
在Python中,绘制直方图(Histogram)是一项非常常见的任务,通常用于数据可视化,以展示数据的分布情况。Python中有多种库可以绘制直方图,其中最常用的两个库是Matplotlib和Seaborn。此外,Pandas库…...
[特殊字符] Unity 性能优化终极指南 — Text / TextMeshPro 组件篇
UGUI Text组件的不当使用及其性能瓶颈与优化 在Unity UGUI系统中,Text 组件(或其升级版 TextMeshPro)是显示文本信息的核心元素。然而,如果不当使用,它极易成为UI性能瓶颈的罪魁祸首,尤其是在预制体、属性…...

Idea 配置 Maven 环境
下载 Maven 官网:https://maven.apache.org/index.html 点击左侧 Downloads,然后选择 Files 中的 zip 包下载(下载慢可以使用迅雷) 配置 Maven 将压缩包解压,比如我解压后放到了 D:\developer\environment\apache-…...
git clone报错:SSL certificate problem: unable to get local issuer certificate
上述报错的完整信息是: Cloning into test... fatal: unable to access https://github.com/xxxx/xxxx.git/: SSL certificate problem: unable to get local issuer certificate 该报错表示 Git 在使用 HTTPS 协议克隆仓库时,无法验证 GitHub 的 SSL …...

Kafka 如何保证不重复消费
在消息队列的使用场景中,避免消息重复消费是保障数据准确性和业务逻辑正确性的关键。对于 Kafka 而言,保证不重复消费并非单一机制就能实现,而是需要从生产者、消费者以及业务层等多个维度协同配合。接下来,我们将结合图文详细解析…...
SpringBoot整合MyBatis完整实践指南
在Java企业级应用开发中,SpringBoot和MyBatis的组合已经成为主流的技术选型方案之一。本文将详细介绍如何从零开始搭建一个基于SpringBoot和MyBatis的项目,包括环境配置、数据库设计、实体类创建、Mapper接口编写以及实际应用等完整流程。 一、环境准备…...

RNN结构扩展与改进:从简单循环网络到时间间隔网络的技术演进
本文系统介绍 RNN 结构的常见扩展与改进方案。涵盖 简单循环神经网络(SRN)、双向循环神经网络(BRNN)、深度循环神经网络(Deep RNN) 等多种变体,解析其核心架构、技术特点及应用场景,…...
docker中,容器时间和宿机主机时间不一致问题
win11下的docker中有个mysql。今天发现插入数据的时间不正确。后来发现原来是docker容器中的时间不正确。于是尝试了各种修改,什么run -e TZ"${tzutil /g}",TZ"Asia/Shanghai",还有初始化时带--mysqld一类的,…...
Unity Shader编程】之高级纹理
一,立方体纹理 Cubemap 用途 用途说明反射贴图表面镜面高光或金属反射环境光采样模拟环境对物体的影响天空盒背景使用六张图拼接场景背景全景投影做360度相机渲染、投影等 二,创建立方体纹理 在 Unity 中创建和保存一个 立方体纹理(Cubema…...

类 Excel 数据填报
类 Excel 填报模式,满足用户 Excel 使用习惯 数据填报,可作为独立的功能模块,用于管理业务流程、汇总采集数据,以及开发各类数据报送系统,因此,对于报表工具而言,其典型场景之一就是利用报表模…...
vscode调试stm32,Cortex Debug的配置文件lanuch.json如何写,日志
https://blog.csdn.net/jiladahe1997/article/details/122046665 https://discuss.em-ide.com/blog/67-cortex-debug 第一版 {// 使用 IntelliSense 了解相关属性。 // 悬停以查看现有属性的描述。// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?li…...

Office文档图片批量导出工具
软件介绍 本文介绍一款专业的Office文档图片批量导出工具。 软件特点 这款软件能够批量导出Word、Excel和PPT中的图片,采用绿色单文件设计,体积小巧仅344KB。 基本操作流程 使用方法十分简单:直接将Word、Excel或PPT文件拖入软件…...

【iOS】ARC 与 Autorelease
ARC 与 Autorelease 文章目录 ARC 与 Autorelease前言何为ARC内存管理考虑方式自己生成的对象,自己持有非自己生成的对象,自己也可以持有不再需要自己持有的对象时释放非自己持有的对象无法释放 ARC的具体实现编译期和运行期ARC做的事情ARC实现: __autoreleasing 与 Autoreleas…...
人工智能在智能零售中的创新应用与未来趋势
随着电子商务的蓬勃发展和消费者需求的不断变化,零售行业正面临着前所未有的挑战和机遇。智能零售作为零售行业的重要发展方向,通过引入人工智能(AI)、物联网(IoT)、大数据和云计算等前沿技术,正…...
业务材料——半导体行业MES系统核心功能工业协议AI赋能
一、前置概念 半导体行业 半导体行业主要生产基于半导体材料(如硅、锗、化合物半导体等)的电子元器件及相关产品,广泛应用于计算、通信、能源、医疗等领域。 MES系统 MES系统(Manufacturing Execution System,制造…...
docker部署命令行 — 启动一个 MySQL 数据库服务 并且把它的数据存储挂载到卷(volume)里
挂载卷的配置写法: version: "3" services:db:image: mysqlvolumes:- mysql_data:/var/lib/mysqlvolumes:mysql_data:这段 docker-compose.yml 配置非常典型,是用来启动一个 MySQL 数据库服务 并且把它的数据存储挂载到卷(volume&…...

铁电液晶破局 VR/AR:10000PPI 重构元宇宙显示体验
一、VR/AR 沉浸感困境:传统显示技术的天花板在哪? (一)纱窗效应与眩晕感:近眼显示的双重枷锁 当用户戴上 VR 头显,眼前像素网格形成的 “纱窗效应” 瞬间打破沉浸感。传统液晶 500-600PPI 的像素密度&…...
2025年微信小程序开发:AR/VR与电商的最新案例
引言 微信小程序自2017年推出以来,已成为中国移动互联网生态的核心组成部分。根据最新数据,截至2025年,微信小程序的日活跃用户超过4.5亿,总数超过430万,覆盖电商、社交、线下服务等多个领域(WeChat Mini …...
从零开始,学会上传,更新,维护github仓库
以下是一份从头到尾、覆盖安装、配置、创建仓库、上传项目到 GitHub 的完整教程。全程使用通用示例,不包含任何具体的仓库链接,仅供参考。 一、准备工作 1. 注册 GitHub 账号 打开浏览器,访问 GitHub 官网(输入 “GitHub” 即可找…...
#STM32 HAL库实现的STM32F407时钟配置程序以及和STM32F103配置对比
以下是使用STM32 HAL库实现的STM32F407时钟配置完整代码(基于8MHz外部晶振,配置为168MHz系统时钟),包含详细注释和关键点说明: 完整HAL库实现(system_stm32f4xx.c main.c) 1. 首先在stm32f4xx…...

竞争加剧,美团的战略升维:反内卷、科技与全球化
5月26日,美团发布2025年第一季度业绩报告,交出了一份兼具韧性与创新性的成绩单。 报告显示,公司一季度总营收866亿元,同比增长18%;核心本地商业收入643亿元,同比增长18%;季度研发投入58亿元&a…...

(17)课36:窗口函数的例题:例三登录时间与连续三天登录,例四球员的进球时刻连续进球。
(89)例三登录时间 : 保留代码版本 : CREATE TABLE sql_8( user_id varchar(2), login_date date ); insert into sql_8(user_id,login_date) values(A,2024-09-02),(A,2024-09-03),(A,2024-09-04),(B,2023-11-25),(B,2023-12- 3…...

高性能分布式消息队列系统(二)
上一篇博客将C进行实现消息队列的用到的核心技术以及环境配置进行了详细的说明,这一篇博客进行记录消息队列进行实现的核心模块的设计 五、项目的需求分析 5.1、项目框架的概念性理解 5.1.1、消息队列的设计和生产消费者模型的关系 在现代系统架构中,…...
Spring 官方推荐构造函数注入
1. 依赖关系明确 构造函数注入可以清晰地声明类的依赖关系,所有必需的依赖项都通过构造函数参数传递,使得代码的可读性更高。这种方式让类的使用者能够直观地了解类的依赖,而不需要通过注解或反射来猜测。 2. 增强代码健壮性 构造函数注入…...

华为OD机试真题——天然蓄水库(2025A卷:200分)Java/python/JavaScript/C++/C语言/GO六种最佳实现
2025 A卷 200分 题型 本文涵盖详细的问题分析、解题思路、代码实现、代码详解、测试用例以及综合分析; 并提供Java、python、JavaScript、C++、C语言、GO六种语言的最佳实现方式! 2025华为OD真题目录+全流程解析/备考攻略/经验分享 华为OD机试真题《天然蓄水库》: 目录 题目…...