尧图精选

Spring Boot开发同城回收小程序全流程指南

🕒 发布时间:2026/9/16 17:00:15 📁 来源:尧图网络
1. 同城好物回收小程序开发概述同城好物回收小程序是一种基于地理位置服务的O2O应用连接用户与回收服务提供者。这类应用通常包含用户端、回收员端和后台管理系统三部分。我们这次开发的版本聚焦于核心功能实现采用Spring Boot MyBatis MySQL的技术栈前端使用微信小程序原生开发框架。对于零基础开发者来说理解这个项目的架构设计很重要。整个系统采用典型的三层架构表现层处理HTTP请求和响应业务逻辑层实现核心业务规则数据访问层与数据库交互这种分层设计使得代码结构清晰便于维护和扩展。在实际开发中我们会先搭建基础框架然后逐步实现各个功能模块。2. 开发环境准备2.1 工具安装与配置开发Java Web项目需要准备以下工具我会详细说明每个工具的安装要点JDK 11建议从Oracle官网下载LTS版本。安装后需要配置环境变量JAVA_HOME指向JDK安装目录Path添加%JAVA_HOME%\bin 验证安装命令行执行java -versionIntelliJ IDEA社区版完全够用。安装后建议配置设置合适的字体和主题File → Settings → Editor → Font安装Lombok插件File → Settings → Plugins配置Maven仓库路径File → Settings → Build → MavenMySQL 8.0安装时注意设置强密码至少8位含大小写字母和特殊字符配置字符集为utf8mb4支持完整Unicode安装Workbench作为图形化管理工具Postman用于API测试建议创建项目专属的Collection保存常用请求为Example配置环境变量如baseUrl提示所有工具建议安装在非系统盘路径不要包含中文和空格避免后续开发中出现奇怪的问题。2.2 项目初始化使用Spring Initializr创建项目是最佳实践比手动配置更可靠。访问https://start.spring.io/ 按以下配置Project: Maven ProjectLanguage: JavaSpring Boot: 2.7.x稳定版本Group: com.yourdomainArtifact: recycle-appDependencies:Spring WebMyBatis FrameworkMySQL DriverLombok下载生成的zip包解压后用IDEA打开。首次加载可能需要几分钟下载依赖。3. 数据库设计与实现3.1 数据表结构我们需要设计三张核心表-- 用户表 CREATE TABLE user ( id bigint NOT NULL AUTO_INCREMENT, phone varchar(11) NOT NULL COMMENT 手机号, password varchar(64) NOT NULL COMMENT 加密密码, nickname varchar(20) DEFAULT NULL COMMENT 昵称, avatar varchar(255) DEFAULT NULL COMMENT 头像URL, create_time datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY idx_phone (phone) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- 回收品类表 CREATE TABLE category ( id bigint NOT NULL AUTO_INCREMENT, name varchar(20) NOT NULL COMMENT 品类名称, base_price decimal(10,2) NOT NULL COMMENT 基础单价, icon varchar(255) DEFAULT NULL COMMENT 图标URL, sort int DEFAULT 0 COMMENT 排序权重, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- 订单表 CREATE TABLE order ( id bigint NOT NULL AUTO_INCREMENT, user_id bigint NOT NULL COMMENT 用户ID, category_id bigint NOT NULL COMMENT 品类ID, weight decimal(10,2) NOT NULL COMMENT 重量(kg), total_price decimal(10,2) NOT NULL COMMENT 总价, address varchar(255) NOT NULL COMMENT 回收地址, contact_phone varchar(11) NOT NULL COMMENT 联系电话, status tinyint NOT NULL DEFAULT 0 COMMENT 0-待接单 1-回收中 2-已完成, create_time datetime DEFAULT CURRENT_TIMESTAMP, update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_user (user_id), KEY idx_status (status) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;3.2 初始化数据在resources目录下创建data.sql添加初始化数据-- 回收品类初始化 INSERT INTO category VALUES (1, 废纸, 1.20, /icons/paper.png, 1); INSERT INTO category VALUES (2, 塑料, 0.80, /icons/plastic.png, 2); INSERT INTO category VALUES (3, 金属, 2.50, /icons/metal.png, 3); INSERT INTO category VALUES (4, 玻璃, 0.50, /icons/glass.png, 4); INSERT INTO category VALUES (5, 电子产品, 5.00, /icons/electronic.png, 5); -- 测试用户 INSERT INTO user VALUES (1, 13800138000, e10adc3949ba59abbe56e057f20f883e, 测试用户, https://avatar.png, NOW());注意实际项目中密码应该使用BCrypt等加密算法这里MD5仅用于演示。4. 后端核心模块开发4.1 用户模块实现用户模块需要实现注册、登录、个人信息等基础功能。我们先创建实体类和Mapper接口// User.java Data TableName(user) public class User { TableId(type IdType.AUTO) private Long id; private String phone; private String password; private String nickname; private String avatar; private LocalDateTime createTime; } // UserMapper.java Mapper public interface UserMapper extends BaseMapperUser { // 自定义查询方法 Select(SELECT * FROM user WHERE phone #{phone}) User selectByPhone(Param(phone) String phone); }Controller层实现关键接口RestController RequestMapping(/api/user) public class UserController { Autowired private UserMapper userMapper; PostMapping(/register) public Result register(RequestBody Valid UserRegisterDTO dto) { // 检查手机号是否已注册 if(userMapper.selectByPhone(dto.getPhone()) ! null) { return Result.fail(该手机号已注册); } // 密码加密 String encryptedPwd DigestUtils.md5DigestAsHex(dto.getPassword().getBytes()); // 创建用户 User user new User(); user.setPhone(dto.getPhone()); user.setPassword(encryptedPwd); user.setNickname(dto.getNickname()); userMapper.insert(user); return Result.success(); } PostMapping(/login) public Result login(RequestBody UserLoginDTO dto) { User user userMapper.selectByPhone(dto.getPhone()); if(user null) { return Result.fail(用户不存在); } String encryptedPwd DigestUtils.md5DigestAsHex(dto.getPassword().getBytes()); if(!encryptedPwd.equals(user.getPassword())) { return Result.fail(密码错误); } // 生成token简化版实际应该用JWT String token UUID.randomUUID().toString(); // 返回用户基本信息不包含密码 UserVO vo new UserVO(); vo.setId(user.getId()); vo.setPhone(user.getPhone()); vo.setNickname(user.getNickname()); vo.setAvatar(user.getAvatar()); vo.setToken(token); return Result.success(vo); } }4.2 回收品类模块品类模块相对简单主要是提供品类列表查询// Category.java Data TableName(category) public class Category { TableId(type IdType.AUTO) private Long id; private String name; private Double basePrice; private String icon; private Integer sort; } // CategoryController.java RestController RequestMapping(/api/category) public class CategoryController { Autowired private CategoryMapper categoryMapper; GetMapping(/list) public Result list() { QueryWrapperCategory query new QueryWrapper(); query.orderByAsc(sort); return Result.success(categoryMapper.selectList(query)); } }4.3 订单模块开发订单模块是核心业务包含创建订单、订单列表、订单状态变更等功能// Order.java Data TableName(order) public class Order { TableId(type IdType.AUTO) private Long id; private Long userId; private Long categoryId; private Double weight; private Double totalPrice; private String address; private String contactPhone; private Integer status; private LocalDateTime createTime; private LocalDateTime updateTime; } // OrderController.java RestController RequestMapping(/api/order) public class OrderController { Autowired private OrderMapper orderMapper; Autowired private CategoryMapper categoryMapper; PostMapping(/create) public Result create(RequestBody Valid OrderCreateDTO dto, RequestHeader(Authorization) String token) { // 1. 验证用户简化版实际应该解析token Long userId validateToken(token); if(userId null) { return Result.fail(401, 未登录); } // 2. 验证品类 Category category categoryMapper.selectById(dto.getCategoryId()); if(category null) { return Result.fail(无效的回收品类); } // 3. 计算价格 if(dto.getWeight() 0) { return Result.fail(重量必须大于0); } double totalPrice dto.getWeight() * category.getBasePrice(); // 4. 创建订单 Order order new Order(); order.setUserId(userId); order.setCategoryId(dto.getCategoryId()); order.setWeight(dto.getWeight()); order.setTotalPrice(totalPrice); order.setAddress(dto.getAddress()); order.setContactPhone(dto.getContactPhone()); order.setStatus(0); // 待接单 orderMapper.insert(order); return Result.success(order); } GetMapping(/list) public Result list(RequestParam(defaultValue 0) Integer status, RequestHeader(Authorization) String token) { Long userId validateToken(token); if(userId null) { return Result.fail(401, 未登录); } QueryWrapperOrder query new QueryWrapper(); query.eq(user_id, userId); if(status ! null) { query.eq(status, status); } query.orderByDesc(create_time); return Result.success(orderMapper.selectList(query)); } }5. 前端小程序开发5.1 项目初始化使用微信开发者工具创建小程序项目选择小程序项目填写AppID没有可以选测试号项目目录选择空文件夹勾选不使用云服务基础目录结构/pages /index - 首页 /user - 用户中心 /order - 订单相关 /utils - 工具类 /app.js - 小程序入口 /app.json - 全局配置 /app.wxss - 全局样式5.2 集成Vant Weapp组件库通过npm安装npm init -y npm i vant/weapp -S --production在app.json中配置{ usingComponents: { van-button: vant/weapp/button/index, van-field: vant/weapp/field/index, van-cell: vant/weapp/cell/index, van-cell-group: vant/weapp/cell-group/index } }在project.config.json中开启npm构建{ setting: { packNpmManually: true, packNpmRelationList: [ { packageJsonPath: ./package.json, miniprogramNpmDistDir: ./ } ] } }5.3 首页开发首页主要展示回收品类和快速下单入口!-- pages/index/index.wxml -- view classcontainer van-cell-group title选择回收品类 van-cell wx:for{{categories}} wx:keyid title{{item.name}} label参考价: ¥{{item.basePrice}}/kg is-link bind:clickonSelectCategory >// pages/index/index.js Page({ data: { categories: [] }, onLoad() { this.loadCategories(); }, loadCategories() { wx.request({ url: https://your-domain/api/category/list, success: (res) { if(res.data.code 0) { this.setData({ categories: res.data.data }); } } }); }, onSelectCategory(e) { const id e.currentTarget.dataset.id; wx.navigateTo({ url: /pages/order/create?id${id} }); }, onCreateOrder() { wx.navigateTo({ url: /pages/order/create }); } });6. 系统部署上线6.1 服务器环境准备推荐使用阿里云ECS或腾讯云CVM最低配置CPU2核内存4GB系统CentOS 7.9基础环境安装# 安装Docker curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun systemctl start docker systemctl enable docker # 安装MySQL docker run -d --name mysql \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORDyourpassword \ -v /data/mysql:/var/lib/mysql \ mysql:8.0 \ --character-set-serverutf8mb4 \ --collation-serverutf8mb4_unicode_ci # 安装Redis可选 docker run -d --name redis \ -p 6379:6379 \ -v /data/redis:/data \ redis:alpine \ --requirepass yourpassword6.2 应用打包与部署修改application-prod.yml配置server: port: 8080 servlet: context-path: /api spring: datasource: url: jdbc:mysql://服务器IP:3306/recycle_db?useSSLfalseserverTimezoneAsia/Shanghai username: root password: yourpassword driver-class-name: com.mysql.cj.jdbc.Driver redis: host: 服务器IP port: 6379 password: yourpassword使用Maven打包mvn clean package -DskipTests上传并运行scp target/recycle-app.jar root服务器IP:/opt/app/ ssh root服务器IP # 在服务器上 nohup java -jar /opt/app/recycle-app.jar --spring.profiles.activeprod /opt/app/app.log 21 6.3 微信小程序配置在微信公众平台配置服务器域名request合法域名https://your-domain.comuploadFile合法域名https://your-domain.comdownloadFile合法域名https://your-domain.com配置业务域名如果需要web-view提交审核前检查所有页面都有明确的用户引导隐私政策合规功能完整可用7. 常见问题与解决方案7.1 数据库连接问题问题现象应用启动时报数据库连接失败排查步骤检查MySQL服务是否运行docker ps | grep mysql检查防火墙是否开放3306端口firewall-cmd --list-ports尝试手动连接mysql -h 127.0.0.1 -u root -p检查application.yml中的连接配置解决方案如果使用云服务器需要在安全组中开放3306端口连接字符串添加时区参数serverTimezoneAsia/Shanghai检查MySQL用户权限GRANT ALL PRIVILEGES ON *.* TO root% WITH GRANT OPTION;7.2 跨域问题问题现象前端请求接口时报CORS错误解决方案后端添加CORS配置Configuration public class CorsConfig implements WebMvcConfigurer { Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(/**) .allowedOrigins(*) .allowedMethods(GET, POST, PUT, DELETE) .allowedHeaders(*) .maxAge(3600); } }或者使用注解方式RestController RequestMapping(/api) CrossOrigin(origins *) public class MyController { // ... }7.3 微信小程序请求失败问题现象小程序端请求接口返回不在合法域名列表中解决方案确认已在小程序后台配置合法域名检查请求的URL是否完全匹配包括https://开发阶段可以勾选不校验合法域名仅限开发版确保服务器已配置SSL证书小程序要求HTTPS8. 项目优化与扩展8.1 性能优化建议数据库优化为常用查询字段添加索引使用MyBatis-Plus的分页插件复杂查询使用Select注解优化SQL缓存策略使用Redis缓存热门数据如品类列表实现二级缓存MyBatis Redis为缓存设置合理的过期时间接口优化使用DTO替代直接暴露实体类实现接口限流如Guava RateLimiter耗时操作异步处理如Async8.2 安全增强方案认证授权实现JWT认证替代简单token使用Spring Security进行权限控制敏感操作要求二次验证数据安全密码使用BCrypt加密敏感信息脱敏处理实现接口签名验证防护措施添加XSS防护过滤器实现CSRF防护SQL注入防护使用预编译语句8.3 功能扩展方向地图集成接入高德地图API实现LBS服务实现附近回收员查询订单分配最优回收员算法支付集成接入微信支付实现余额系统交易记录查询智能定价基于市场行情动态调整价格实现价格预测模型特殊时段溢价策略用户成长体系积分奖励机制会员等级系统环保成就系统9. 学习资源与进阶建议9.1 推荐学习路径Java基础巩固《Java核心技术 卷I》慕课网Java零基础入门牛客网Java专项练习Spring Boot进阶官方文档spring.io/guides《Spring Boot实战》B站Spring Boot企业级开发小程序开发微信官方文档掘金小册小程序从入门到精通腾讯云开发训练营9.2 项目实践建议从简单功能开始逐步迭代每个功能模块都编写单元测试使用Git进行版本控制养成写开发文档的习惯参与开源项目学习优秀代码9.3 社区与交流遇到问题优先查Stack Overflow掘金社区V2EX技术板块加入技术交流群Spring Boot技术交流群微信小程序开发群本地技术社区参加线下技术沙龙腾讯云开发者大会阿里云栖大会本地技术Meetup我在实际开发这个项目时最大的体会是模块化设计和清晰的代码结构比追求高级技术更重要。对于初学者建议先把基础功能做稳定再考虑引入复杂技术。数据库设计阶段多花些时间能避免后期很多麻烦。小程序开发要注意性能优化特别是列表页面的渲染效率。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →