目录

项目概述

一、项目环境搭建

1.1 后端项目初始化

1.2 前端项目初始化

1.3 数据库准备

二、AI辅助开发实践

2.1 Prompt工程应用

2.2 AI大模型应用场景

三、核心功能模块实现

3.1 点位管理系统

3.1.1 业务需求

3.1.2 数据库设计

3.1.3 关键技术实现

3.2 人员管理系统

3.2.1 业务需求

3.2.2 冗余字段设计

3.2.3 同步更新机制

3.3 文件存储方案

3.3.1 云存储集成

3.3.2 统一文件存储框架

3.3.3 文件上传实现

3.4 设备管理系统

3.4.1 设备全生命周期管理

3.4.2 设备新增事务处理

3.4.3 货道管理

3.5 策略管理系统

3.5.1 营销策略设计

3.5.2 策略分配实现

3.6 商品管理系统

3.6.1 商品管理功能

3.6.2 EasyExcel集成

3.6.3 逻辑外键约束

3.7 工单管理系统

3.7.1 工单系统设计

3.7.2 工单创建流程

3.7.3 工单取消逻辑

3.7.4 API文档集成

四、多端协同架构

4.1 运营管理App端

4.2 设备屏幕端

4.3 支付出货流程

五、项目技术亮点总结

5.1 架构设计亮点

5.2 性能优化实践

5.3 数据一致性保障

5.4 开发效率提升

5.5 运维友好性

六、项目部署与运维

6.1 环境要求

6.2 部署步骤

6.3 监控与维护

七、扩展与优化方向

7.1 功能扩展

7.2 技术优化

7.3 安全加固


智能售货机运营管理系统是基于物联网技术的综合性管理平台,通过互联网连接分布各处的智能售货机,实现对设备、商品、人员、点位和订单的集中化、智能化管理。系统采用SpringBoot+Vue.js技术架构,集成MySQL、Redis、阿里云OSS等组件,提供设备全生命周期管理、工单系统、商品管理、营销策略等核心功能模块。项目通过冗余字段设计、批量操作优化和Redis缓存等性能优化手段,同时采用事务管理和外键约束保障数据一致性。系统支持多端协同工作,包含运营管理App端和设备屏幕端,实现从支付到出货的完整业务流程。该项目具有模块化设计、开发效率高、运维友好等特点,未来可扩展智能预警、会员系统等功能,并考虑微服务化和容器部署等优化方向。

项目概述

智能售货机运营管理系统是一个基于物联网概念的综合性管理平台。系统通过互联网连接分布在各处的智能售货机,实现对设备、商品、人员、点位和订单的集中化、智能化管理,为零售行业带来创新和效率提升。

核心价值

  • 智能化管理:通过物联网技术远程监控设备状态、库存情况

  • 流程自动化:工单系统自动化派发和处理运维、运营任务

  • 数据驱动决策:全面的数据统计和分析支持业务决策

  • 线上线下融合:支持移动支付、线上浏览线下取货等OMO模式

技术架构

  • 后端:Spring Boot + MyBatis + Redis

  • 前端:Vue.js + Element Plus

  • 数据库:MySQL

  • 文件存储:阿里云OSS

  • 其他:Redis缓存、EasyExcel、Knife4j接口文档

一、项目环境搭建

1.1 后端项目初始化

  1. 从Git仓库克隆项目源码

  2. 使用Maven下载项目依赖

  3. 配置MySQL数据库连接信息

  4. 配置Redis连接及密码设置

  5. 启动Spring Boot应用

1.2 前端项目初始化

  1. 克隆前端Vue项目源码

  2. 使用npm安装项目依赖

  3. 运行开发服务器

  4. 访问系统登录页面(默认账号/密码)

1.3 数据库准备

  1. 创建业务数据库

  2. 执行SQL脚本初始化表结构

  3. 配置数据库连接池参数

二、AI辅助开发实践

2.1 Prompt工程应用

在项目开发中,我们充分利用AI辅助编程提高开发效率:

表结构生成示例

角色:软件工程师
指示:生成MySQL表结构
需求:区域表、合作商表、点位表
要求:包含标准字段、外键约束、注释说明

代码流程图生成

// 将复杂业务方法转换为Mermaid流程图
graph TD;
    A[查询售货机] --> B{售货机是否存在?};
    B -- 是 --> C[校验状态];
    B -- 否 --> D[抛出异常];

2.2 AI大模型应用场景

  1. 代码补全:实体类getter/setter、构造方法

  2. 接口文档:根据表结构生成API文档

  3. SQL优化:复杂查询语句优化建议

  4. 业务流程:代码执行流程图生成

三、核心功能模块实现

3.1 点位管理系统

3.1.1 业务需求
  • 区域划分管理(逻辑区域非行政区域)

  • 合作商管理(分成比例、联系人信息)

  • 点位管理(具体设备放置位置)

3.1.2 数据库设计

表关系设计

  • 区域表(tb_region):区域基本信息

  • 合作商表(tb_partner):合作商信息及分成比例

  • 点位表(tb_node):具体点位信息,关联区域和合作商

外键约束

-- 点位表外键约束
FOREIGN KEY (region_id) REFERENCES tb_region(id) ON DELETE RESTRICT,
FOREIGN KEY (partner_id) REFERENCES tb_partner(id) ON DELETE RESTRICT
3.1.3 关键技术实现

关联查询优化

<!-- 区域列表显示点位数 -->
<select id="selectRegionVoList" resultType="RegionVo">
SELECT r.*, COUNT(n.id) AS node_count 
FROM tb_region r 
LEFT JOIN tb_node n ON r.id = n.region_id 
GROUP BY r.id
</select>

数据完整性保护

// 全局异常处理器处理外键约束异常
@ExceptionHandler(DataIntegrityViolationException.class)
public AjaxResult handleDataIntegrityViolationException(DataIntegrityViolationException e) {
    if (e.getMessage().contains("foreign")) {
        return AjaxResult.error("无法删除,有其他数据引用");
    }
    return AjaxResult.error("操作违反了数据库完整性约束");
}

3.2 人员管理系统

3.2.1 业务需求
  • 员工信息管理(运维、运营人员)

  • 角色权限分配

  • 区域责任划分

3.2.2 冗余字段设计

在员工表中添加冗余字段提高查询效率:

  • region_name:区域名称

  • role_name:角色名称

  • role_code:角色编码

3.2.3 同步更新机制

当区域名称修改时,同步更新员工表中的区域名称:

@Transactional(rollbackFor = Exception.class)
public int updateRegion(Region region) {
    // 更新区域信息
    int result = regionMapper.updateRegion(region);
    // 同步更新员工表区域名称
    empMapper.updateByRegionId(region.getRegionName(), region.getId());
    return result;
}

3.3 文件存储方案

3.3.1 云存储集成

问题分析:本地文件存储的局限性

  • 硬件和网络要求高

  • 管理维护复杂

  • 存在单点故障风险

解决方案:阿里云OSS对象存储

  1. 开通OSS服务并创建Bucket

  2. 配置AccessKey和SecretKey

  3. 集成OSS SDK实现文件上传

3.3.2 统一文件存储框架

使用x-file-storage统一文件存储接口:

# yaml文件配置

dromara:
  x-file-storage:
    default-platform: aliyun-oss-1
    aliyun-oss:
      - platform: aliyun-oss-1
        access-key: ${OSS_ACCESS_KEY_ID}
        secret-key: ${OSS_ACCESS_KEY_SECRET}
        end-point: oss-cn-beijing.aliyuncs.com
        bucket-name: your-bucket
        base-path: project-images/
3.3.3 文件上传实现
public AjaxResult uploadFile(MultipartFile file) {
    // 指定OSS保存路径
    String objectName = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd")) + "/";
    // 上传文件到OSS
    FileInfo fileInfo = fileStorageService.of(file).setPath(objectName).upload();
    // 返回文件访问URL
    return AjaxResult.success().put("url", fileInfo.getUrl());
}

3.4 设备管理系统

3.4.1 设备全生命周期管理

设备状态流转

  • 0:未投放 → 创建投放工单

  • 1:运营 → 可创建补货、维修工单

  • 3:撤机 → 设备下线

3.4.2 设备新增事务处理
@Transactional
public int insertVendingMachine(VendingMachine vendingMachine) {
    // 1. 生成设备编号
    String innerCode = UUIDUtils.getUUID();
    vendingMachine.setInnerCode(innerCode);
    
    // 2. 补充设备信息
    VmType vmType = vmTypeService.selectVmTypeById(vendingMachine.getVmTypeId());
    vendingMachine.setChannelMaxCapacity(vmType.getChannelMaxCapacity());
    
    // 3. 查询点位信息
    Node node = nodeService.selectNodeById(vendingMachine.getNodeId());
    BeanUtil.copyProperties(node, vendingMachine, "id");
    vendingMachine.setAddr(node.getAddress());
    
    // 4. 保存设备信息
    int result = vendingMachineMapper.insertVendingMachine(vendingMachine);
    
    // 5. 批量创建货道(根据设备类型规格)
    List<Channel> channelList = createChannels(vendingMachine, vmType);
    channelService.batchInsertChannel(channelList);
    
    return result;
}
3.4.3 货道管理
public int setChannel(ChannelConfigDto channelConfigDto) {
    // 批量更新货道商品关联
    List<Channel> list = channelConfigDto.getChannelList().stream()
        .map(dto -> {
            Channel channel = channelMapper.getChannelInfo(dto.getInnerCode(), dto.getChannelCode());
            if (channel != null) {
                channel.setSkuId(dto.getSkuId());
                channel.setUpdateTime(DateUtils.getNowDate());
            }
            return channel;
        }).collect(Collectors.toList());
    
    return channelMapper.batchUpdateChannel(list);
}

货道设计原则

  • 货道编号格式:行号-列号(如"1-1", "1-2")

  • 最大容量:由设备类型决定

  • 当前容量:动态变化,补货时更新

货道关联商品


3.5 策略管理系统

3.5.1 营销策略设计
  • 折扣策略:固定折扣比例

  • 策略分配:可分配给单个或多个设备

  • 策略生效:实时计算商品折扣价

3.5.2 策略分配实现
public int updateVendingMachine(VendingMachine vendingMachine) {
    if (vendingMachine.getNodeId() != null) {
        // 更新点位相关冗余信息
        Node node = nodeService.selectNodeById(vendingMachine.getNodeId());
        BeanUtil.copyProperties(node, vendingMachine, "id");
        vendingMachine.setAddr(node.getAddress());
    }
    vendingMachine.setUpdateTime(DateUtils.getNowDate());
    return vendingMachineMapper.updateVendingMachine(vendingMachine);
}

3.6 商品管理系统

3.6.1 商品管理功能
  • 商品分类管理

  • 商品信息维护(名称、图片、价格、规格)

  • 批量导入导出

3.6.2 EasyExcel集成

优势对比传统POI

  • 内存消耗大幅降低(3M Excel只需几M内存)

  • API设计更简洁易用

  • 支持大文件处理

集成步骤

  1. 添加EasyExcel依赖

  2. 实体类添加@ExcelProperty注解

  3. 实现导入导出逻辑

批量导入实现

@PostMapping("/import")
public AjaxResult excelImport(MultipartFile file) throws Exception {
    ExcelUtil<Sku> util = new ExcelUtil<Sku>(Sku.class);
    // 使用EasyExcel解析
    List<Sku> skuList = util.importEasyExcel(file.getInputStream());
    return toAjax(skuService.insertSkus(skuList));
}
3.6.3 逻辑外键约束

问题场景:货道表默认SKU_ID为0,物理外键约束会导致插入失败

解决方案:应用层逻辑约束

public int deleteSkuBySkuIds(Long[] skuIds) {
    // 检查商品是否被货道引用
    int count = channelService.countChannelBySkuIds(skuIds);
    if (count > 0) {
        throw new ServiceException("此商品被货道关联,无法删除");
    }
    return skuMapper.deleteSkuBySkuIds(skuIds);
}

3.7 工单管理系统

3.7.1 工单系统设计

工单类型

  • 运营工单:补货操作

  • 运维工单:投放、撤机、维修操作

工单状态

  • 1:待处理

  • 2:进行中

  • 3:已取消

  • 4:已完成

3.7.2 工单创建流程

关键校验逻辑

  1. 设备状态与工单类型匹配性校验

  2. 同类型未完成工单检查

  3. 员工区域匹配性校验

  4. 补货工单详情完整性校验

工单编号生成

public String generateTaskCode() {
    String dateStr = DateUtils.getDate().replaceAll("-", "");
    String key = "project.task.code." + dateStr;
    
    if (!redisTemplate.hasKey(key)) {
        redisTemplate.opsForValue().set(key, 1, Duration.ofDays(1));
        return dateStr + "0001";
    }
    
    Long increment = redisTemplate.opsForValue().increment(key);
    return dateStr + String.format("%04d", increment);
}
3.7.3 工单取消逻辑
public int cancelTask(Task task) {
    // 检查工单状态是否可取消
    Task taskDb = taskMapper.selectTaskByTaskId(task.getTaskId());
    if (taskDb.getTaskStatus().equals(TASK_STATUS_CANCEL)) {
        throw new ServiceException("该工单已取消了,不能再次取消");
    }
    if (taskDb.getTaskStatus().equals(TASK_STATUS_FINISH)) {
        throw new ServiceException("该工单已完成了,不能取消");
    }
    
    // 更新为取消状态
    task.setTaskStatus(TASK_STATUS_CANCEL);
    task.setUpdateTime(DateUtils.getNowDate());
    return taskMapper.updateTask(task);
}
3.7.4 API文档集成

使用Knife4j替代Swagger:

  1. 添加Knife4j依赖

  2. 配置接口访问路径

  3. 添加API注解

  4. 统一返回类型处理

注解示例

@Api(tags = "工单管理")
@RestController
@RequestMapping("/manage/task")
public class TaskController {
    
    @ApiOperation("创建工单")
    @PostMapping
    public R<String> createTask(@RequestBody TaskDto taskDto) {
        // 业务逻辑
        return R.ok("创建成功");
    }
}

四、多端协同架构

4.1 运营管理App端

技术栈:Spring Boot + MyBatis-Plus + 阿里云短信
核心功能

  • 工单接收与处理

  • 设备维修操作

  • 商品补货执行

4.2 设备屏幕端

技术栈:Spring Boot + MyBatis-Plus
核心功能

  • 商品展示与选择

  • 支付二维码生成

  • 订单状态同步

4.3 支付出货流程

  1. 屏幕端发起支付请求

  2. 订单服务创建订单并调用支付平台

  3. 返回支付二维码链接

  4. 用户扫码支付成功

  5. 支付平台回调通知

  6. 订单服务更新状态并触发出货

五、项目技术亮点总结

5.1 架构设计亮点

  1. 分层清晰:Controller-Service-Mapper标准分层

  2. 模块化:按功能划分模块,高内聚低耦合

  3. 扩展性:易于新增功能模块

5.2 性能优化实践

  1. 冗余字段:减少关联查询,提升列表查询性能

  2. Redis应用:工单编号生成、缓存热点数据

  3. 批量操作:批量插入、更新减少数据库交互

5.3 数据一致性保障

  1. 事务管理:关键业务操作添加事务注解

  2. 外键约束:数据库层与应用层双重保障

  3. 状态机设计:明确的状态流转规则

5.4 开发效率提升

  1. 代码生成器:快速生成基础CRUD代码

  2. AI辅助:Prompt工程加速开发过程

  3. 统一异常处理:全局异常处理器简化错误处理

5.5 运维友好性

  1. 完整日志:关键操作记录操作日志

  2. 接口文档:Knife4j提供清晰API文档

  3. 配置外化:关键配置统一管理

六、项目部署与运维

6.1 环境要求

  • JDK 8+

  • MySQL 5.7+

  • Redis 3.2+

  • Node.js 14+

6.2 部署步骤

  1. 数据库初始化

  2. 后端应用打包部署

  3. 前端构建部署

  4. 反向代理配置

  5. 域名绑定与SSL证书

6.3 监控与维护

  1. 应用健康检查接口

  2. 日志集中管理

  3. 数据库备份策略

  4. 性能监控告警

七、扩展与优化方向

7.1 功能扩展

  1. 智能预警:基于销售数据预测补货时间

  2. 会员系统:用户积分、优惠券体系

  3. 数据分析:销售热力图、用户偏好分析

7.2 技术优化

  1. 微服务化:按业务域拆分微服务

  2. 容器化部署:Docker + Kubernetes

  3. 消息队列:异步处理订单、工单等业务

  4. 分布式事务:跨服务数据一致性保障

7.3 安全加固

  1. API安全:请求签名、防重放攻击

  2. 数据加密:敏感数据加密存储

  3. 权限细化:更细粒度的RBAC权限控制

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐