本指南将带你从零开始,一步步搭建完整的奶茶点餐微信小程序后端系统
📚 目录
一、环境准备
1.1 必需软件安装
1.1.1 安装JDK 1.8
Windows:
- 下载JDK 1.8: https://www.oracle.com/java/technologies/javase/javase8-archive-downloads.html
- 安装JDK(记住安装路径)
- 配置环境变量:
JAVA_HOME: JDK安装路径(如C:\Program Files\Java\jdk1.8.0_291)PATH: 添加%JAVA_HOME%\bin
macOS:
# 使用Homebrew安装
brew install openjdk@8
# 或下载Oracle JDK安装包
Linux:
sudo apt-get update
sudo apt-get install openjdk-8-jdk -y
验证安装:
java -version
# 应显示: java version "1.8.0_xxx"
1.1.2 安装Maven
Windows:
- 下载Maven: https://maven.apache.org/download.cgi
- 解压到目录(如
C:\Program Files\Apache\maven) - 配置环境变量:
MAVEN_HOME: Maven安装路径PATH: 添加%MAVEN_HOME%\bin
macOS:
brew install maven
Linux:
sudo apt-get install maven -y
验证安装:
mvn -version
# 应显示Maven版本信息
配置Maven镜像(加速下载):
编辑 ~/.m2/settings.xml(如不存在则创建):
<?xml version="1.0" encoding="UTF-8"?>
<settings>
<mirrors>
<mirror>
<id>aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Aliyun Maven</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
</mirrors>
</settings>
1.1.3 安装MySQL
Windows:
- 下载MySQL: https://dev.mysql.com/downloads/mysql/
- 安装MySQL Server
- 记住root密码
macOS:
brew install mysql
brew services start mysql
Linux:
sudo apt-get install mysql-server -y
sudo systemctl start mysql
sudo systemctl enable mysql
创建数据库:
mysql -uroot -p
CREATE DATABASE naicha DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
EXIT;
1.1.4 安装Redis(可选)
Windows:
- 下载Redis for Windows: https://github.com/microsoftarchive/redis/releases
- 或使用WSL安装
macOS:
brew install redis
brew services start redis
Linux:
sudo apt-get install redis-server -y
sudo systemctl start redis-server
验证Redis:
redis-cli ping
# 应返回: PONG
1.1.5 安装IDE(推荐IntelliJ IDEA)
下载地址: https://www.jetbrains.com/idea/
社区版(免费): 足够使用
旗舰版(付费): 功能更强大
二、创建项目结构
2.1 创建项目根目录
mkdir naicha
cd naicha
2.2 创建多模块结构
naicha/
├── pom.xml # 父级POM
├── common/ # 公共模块
│ ├── pom.xml
│ └── src/main/
│ ├── java/com/yu/common/
│ └── resources/
├── naicha_app/ # 小程序API模块
│ ├── pom.xml
│ └── src/main/
│ ├── java/com/yu/app/
│ └── resources/
└── naicha_system/ # 后台管理API模块
├── pom.xml
└── src/main/
├── java/com/yu/system/
└── resources/
创建目录结构:
# Windows (PowerShell)
mkdir common, naicha_app, naicha_system
mkdir common\src\main\java\com\yu\common
mkdir common\src\main\resources
mkdir naicha_app\src\main\java\com\yu\app
mkdir naicha_app\src\main\resources
mkdir naicha_system\src\main\java\com\yu\system
mkdir naicha_system\src\main\resources
# macOS/Linux
mkdir -p common/src/main/java/com/yu/common
mkdir -p common/src/main/resources
mkdir -p naicha_app/src/main/java/com/yu/app
mkdir -p naicha_app/src/main/resources
mkdir -p naicha_system/src/main/java/com/yu/system
mkdir -p naicha_system/src/main/resources
三、配置Maven多模块
3.1 创建父级POM(pom.xml)
在 naicha/pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.yu</groupId>
<artifactId>naicha</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging> <!-- 父级必须是pom -->
<!-- 子模块 -->
<modules>
<module>common</module>
<module>naicha_app</module>
<module>naicha_system</module>
</modules>
<!-- Spring Boot父级依赖 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<!-- 公共依赖 -->
<dependencies>
<!-- Spring Boot开发工具(热部署) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<!-- Hutool工具类 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>4.3.1</version>
</dependency>
<!-- 测试依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Maven编译插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<!-- 跳过测试 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
</project>
3.2 创建common模块POM
在 naicha/common/pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>naicha</artifactId>
<groupId>com.yu</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>common</artifactId>
<packaging>jar</packaging>
<dependencies>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
</dependency>
<!-- FastJSON -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.7</version>
</dependency>
<!-- MySQL驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.15</version>
</dependency>
<!-- Druid连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.22</version>
</dependency>
<!-- Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- MyBatis-Plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.1</version>
</dependency>
<!-- Swagger文档 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<!-- JWT -->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.1</version>
</dependency>
</dependencies>
</project>
3.3 创建naicha_app模块POM
在 naicha/naicha_app/pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>naicha</artifactId>
<groupId>com.yu</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>naicha_app</artifactId>
<packaging>jar</packaging>
<dependencies>
<!-- 依赖common模块 -->
<dependency>
<groupId>com.yu</groupId>
<artifactId>common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot AOP -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Spring Boot Maven插件(打包成可执行JAR) -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
3.4 验证Maven配置
cd naicha
mvn clean install -DskipTests
如果成功,会看到 BUILD SUCCESS。
四、配置数据库
4.1 创建数据库表
创建用户表:
USE naicha;
CREATE TABLE `user` (
`wx_openid` varchar(28) NOT NULL COMMENT '微信openid(主键)',
`wx_avatar` varchar(255) DEFAULT NULL COMMENT '微信头像',
`name` varchar(50) DEFAULT NULL COMMENT '姓名',
`phone` varchar(20) DEFAULT NULL COMMENT '手机号',
`address` varchar(255) DEFAULT NULL COMMENT '地址',
`sex` tinyint(1) DEFAULT NULL COMMENT '性别:0-女,1-男',
`status` tinyint(1) DEFAULT '1' COMMENT '状态:0-冻结,1-正常',
PRIMARY KEY (`wx_openid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
创建商品表:
CREATE TABLE `goods` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '商品ID',
`name` varchar(100) NOT NULL COMMENT '商品名称',
`description` text COMMENT '商品描述',
`price` int(11) NOT NULL COMMENT '价格(分)',
`image` varchar(255) DEFAULT NULL COMMENT '商品图片',
`category_id` int(11) DEFAULT NULL COMMENT '分类ID',
`status` tinyint(1) DEFAULT '1' COMMENT '状态:0-下架,1-上架',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品表';
4.2 创建配置文件
创建application.yml (naicha_app/src/main/resources/application.yml):
server:
port: 8101
servlet:
context-path: /naicha-api
# MyBatis-Plus配置
mybatis-plus:
configuration:
map-underscore-to-camel-case: true
type-aliases-package: com.yu.**.entity.**
global-config:
db-config:
id-type: auto
spring:
profiles:
active: dev
jackson:
time-zone: GMT+8
dateFormat: yyyy-MM-dd HH:mm:ss
# Redis配置
redis:
database: 0
host: 127.0.0.1
port: 6379
password:
timeout: 5000
# 数据源配置
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
druid:
url: jdbc:mysql://127.0.0.1:3306/naicha?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2b8&allowPublicKeyRetrieval=true
username: root
password: root
五、编写核心代码
5.1 创建实体类(Entity)
创建User实体 (common/src/main/java/com/yu/common/entity/app/User.java):
package com.yu.common.entity.app;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("user")
public class User {
@TableId(type = IdType.INPUT)
private String wxOpenid;
private String wxAvatar;
private String name;
private String phone;
private String address;
private Integer sex;
private Boolean status;
@TableField(exist = false)
private String token;
}
5.2 创建Mapper接口
创建UserMapper (naicha_app/src/main/java/com/yu/app/moudles/mapper/UserMapper.java):
package com.yu.app.moudles.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yu.common.entity.app.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;
@Mapper
public interface UserMapper extends BaseMapper<User> {
@Update("UPDATE user SET wx_avatar = #{avatar} WHERE wx_openid = #{openid}")
int updateWxAvatar(@Param("avatar") String avatar, @Param("openid") String openid);
}
5.3 创建Service
创建UserService接口 (naicha_app/src/main/java/com/yu/app/moudles/service/UserService.java):
package com.yu.app.moudles.service;
import com.yu.common.entity.app.User;
import com.yu.common.entity.app.form.LoginByWeixinForm;
public interface UserService {
User loginByWeixin(LoginByWeixinForm form) throws Exception;
User getUser(String userId);
}
创建UserServiceImpl (naicha_app/src/main/java/com/yu/app/moudles/service/UserServiceImpl.java):
package com.yu.app.moudles.service;
import com.yu.app.moudles.mapper.UserMapper;
import com.yu.common.common.exception.ServiceException;
import com.yu.common.common.util.weixin.WeixinUtil;
import com.yu.common.entity.app.User;
import com.yu.common.entity.app.form.LoginByWeixinForm;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
@Slf4j
@Service
public class UserServiceImpl implements UserService {
@Resource
private UserMapper userMapper;
@Override
@Transactional
public User loginByWeixin(LoginByWeixinForm form) throws ServiceException {
log.info("微信登录,code: {}", form.getCode());
String wxOpenid = WeixinUtil.getWeiXinOpenid(form.getCode());
if (wxOpenid == null) {
throw ServiceException.CONST_wx_login_failed;
}
User user = userMapper.selectById(wxOpenid);
if (user == null) {
// 新用户注册
user = new User();
user.setWxOpenid(wxOpenid);
user.setWxAvatar(form.getWxAvatar());
user.setStatus(true);
userMapper.insert(user);
} else {
// 更新头像
user.setWxAvatar(form.getWxAvatar());
userMapper.updateWxAvatar(user.getWxAvatar(), wxOpenid);
}
return user;
}
@Override
public User getUser(String userId) {
return userMapper.selectById(userId);
}
}
5.4 创建Controller
创建UserController (naicha_app/src/main/java/com/yu/app/moudles/controller/UserController.java):
package com.yu.app.moudles.controller;
import com.yu.app.moudles.service.UserService;
import com.yu.common.common.util.result.Result;
import com.yu.common.entity.app.User;
import com.yu.common.entity.app.form.LoginByWeixinForm;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@Api(tags = "用户服务")
@RestController
@Slf4j
@RequestMapping("/user")
public class UserController {
@Resource
private UserService userService;
@ApiOperation("通过微信登录")
@PostMapping("/login/weixin")
public Result<User> loginByWx(@RequestBody LoginByWeixinForm form) throws Exception {
User user = userService.loginByWeixin(form);
return Result.ok(user);
}
@ApiOperation("获取用户信息")
@GetMapping("/{id}")
public Result<User> getUser(@PathVariable String id) {
User user = userService.getUser(id);
return Result.ok(user);
}
}
5.5 创建启动类
创建NaichaAppRun (naicha_app/src/main/java/com/yu/app/NaichaAppRun.java):
package com.yu.app;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication(scanBasePackages = {"com.yu.app", "com.yu.common"})
@MapperScan("com.yu.**.mapper")
@RestController
public class NaichaAppRun {
public static void main(String[] args) {
SpringApplication.run(NaichaAppRun.class, args);
}
@GetMapping({"/ping", "/"})
public String ping() {
return "服务器正常运行 [app]";
}
}
5.6 创建必要的工具类
创建Result类 (common/src/main/java/com/yu/common/common/util/result/Result.java):
package com.yu.common.common.util.result;
import lombok.Data;
@Data
public class Result<T> {
private Integer code;
private String message;
private T data;
public static <T> Result<T> ok(T data) {
Result<T> result = new Result<>();
result.setCode(200);
result.setMessage("success");
result.setData(data);
return result;
}
public static <T> Result<T> fail(String message) {
Result<T> result = new Result<>();
result.setCode(400);
result.setMessage(message);
return result;
}
}
创建LoginByWeixinForm (common/src/main/java/com/yu/common/entity/app/form/LoginByWeixinForm.java):
package com.yu.common.entity.app.form;
import lombok.Data;
@Data
public class LoginByWeixinForm {
private String code;
private String wxAvatar;
}
创建ServiceException (common/src/main/java/com/yu/common/common/exception/ServiceException.java):
package com.yu.common.common.exception;
public class ServiceException extends RuntimeException {
private Integer code;
public ServiceException(Integer code, String message) {
super(message);
this.code = code;
}
public static final ServiceException CONST_wx_login_failed =
new ServiceException(400, "通过微信登录失败");
}
创建WeixinUtil (common/src/main/java/com/yu/common/common/util/weixin/WeixinUtil.java):
package com.yu.common.common.util.weixin;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yu.common.common.constant.Const;
import com.yu.common.common.util.http.HttpUtil;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class WeixinUtil {
public static String getWeiXinOpenid(String code) {
String urlStr = "https://api.weixin.qq.com/sns/jscode2session?appid=" + Const.Wx.appId
+ "&secret=" + Const.Wx.appSecret
+ "&grant_type=authorization_code&js_code=" + code;
String body = HttpUtil.get(urlStr);
JSONObject result = JSON.parseObject(body);
Integer errcode = result.getInteger("errcode");
if (errcode == null || errcode.equals(0)) {
return result.getString("openid");
} else {
log.error("[获取openid失败] 回复报文:{}", body);
return null;
}
}
}
创建Const类 (common/src/main/java/com/yu/common/common/constant/Const.java):
package com.yu.common.common.constant;
public final class Const {
public static class Wx {
public static final String appId = "wxe1fb0176d712ed54";
public static final String appSecret = "e251db3726757825d194ee6f147a4a73";
}
}
创建HttpUtil (common/src/main/java/com/yu/common/common/util/http/HttpUtil.java):
package com.yu.common.common.util.http;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class HttpUtil {
public static String get(String urlStr) {
try {
URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
BufferedReader reader = new BufferedReader(
new InputStreamReader(conn.getInputStream(), "UTF-8"));
StringBuilder result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
reader.close();
return result.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
六、配置Redis
6.1 创建Redis配置类(可选)
如果不需要特殊配置,Spring Boot会自动配置Redis。
创建RedisConfig (common/src/main/java/com/yu/common/common/config/redis/RedisConfig.java):
package com.yu.common.common.config.redis;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new StringRedisSerializer());
return template;
}
}
七、编写业务代码
7.1 添加全局异常处理
创建GlobalExceptionHandler (common/src/main/java/com/yu/common/common/exception/GlobalExceptionHandler.java):
package com.yu.common.common.exception;
import com.yu.common.common.util.result.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ServiceException.class)
public Result handleServiceException(ServiceException e) {
log.error("[异常{}] {}", e.getCode(), e.getMessage());
return Result.fail(e.getMessage());
}
@ExceptionHandler(Exception.class)
public Result handleException(Exception e) {
log.error("[系统异常]", e);
return Result.fail("系统异常,请稍后重试");
}
}
7.2 添加跨域配置(如果需要)
创建WebMVCConfig (naicha_app/src/main/java/com/yu/app/common/mvc/WebMVCConfig.java):
package com.yu.app.common.mvc;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebMVCConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.maxAge(3600);
}
}
八、测试和运行
8.1 编译项目
cd naicha
mvn clean install -DskipTests
8.2 运行项目
方式一:使用Maven命令
cd naicha_app
mvn spring-boot:run
方式二:使用IDE
- 在IntelliJ IDEA中打开项目
- 找到
NaichaAppRun.java - 右键 → Run ‘NaichaAppRun.main()’
方式三:使用JAR包
# 打包
mvn clean package -DskipTests
# 运行
java -jar naicha_app/target/naicha_app-1.0-SNAPSHOT.jar
8.3 测试API
测试ping接口:
curl http://localhost:8101/naicha-api/ping
# 应返回: 服务器正常运行 [app]
测试用户登录接口:
curl -X POST http://localhost:8101/naicha-api/user/login/weixin \
-H "Content-Type: application/json" \
-d '{"code":"test_code","wxAvatar":"http://example.com/avatar.jpg"}'
8.4 查看Swagger文档(如果配置了)
访问: http://localhost:8101/naicha-api/swagger-ui.html
九、常见问题
Q1: Maven依赖下载失败
解决方案:
- 检查网络连接
- 配置Maven镜像(见1.1.2节)
- 清理Maven缓存:
mvn clean
Q2: 数据库连接失败
检查:
- MySQL服务是否启动
- 数据库用户名密码是否正确
- 数据库
naicha是否已创建 - 端口3306是否被占用
Q3: 端口被占用
解决方案:
# Windows
netstat -ano | findstr :8101
taskkill /PID <PID> /F
# macOS/Linux
lsof -i :8101
kill -9 <PID>
或修改配置文件中的端口号。
Q4: 找不到类或包
解决方案:
- 检查包名是否正确
- 检查类路径是否正确
- 重新编译:
mvn clean install - 在IDE中刷新Maven项目
Q5: Redis连接失败
解决方案:
- 检查Redis服务是否启动
- 检查配置文件中的Redis地址和端口
- 如果不需要Redis,可以暂时注释掉相关配置
十、下一步扩展
10.1 添加更多功能
-
商品管理
- 创建Goods实体、Mapper、Service、Controller
- 实现商品的增删改查
-
订单管理
- 创建Order实体、Mapper、Service、Controller
- 实现下单、支付、查询订单等功能
-
用户认证
- 实现JWT token生成和验证
- 添加登录拦截器
10.2 优化项目
-
添加日志
- 配置logback或log4j2
- 添加日志文件输出
-
添加单元测试
- 使用JUnit编写测试用例
- 使用Mockito模拟依赖
-
代码规范
- 使用Checkstyle检查代码规范
- 使用SpotBugs检查代码缺陷
十一、项目结构总结
完成后的项目结构:
naicha/
├── pom.xml # 父级POM
├── common/ # 公共模块
│ ├── pom.xml
│ └── src/main/java/com/yu/common/
│ ├── common/
│ │ ├── constant/Const.java
│ │ ├── exception/
│ │ │ ├── ServiceException.java
│ │ │ └── GlobalExceptionHandler.java
│ │ └── util/
│ │ ├── result/Result.java
│ │ ├── weixin/WeixinUtil.java
│ │ └── http/HttpUtil.java
│ └── entity/app/
│ ├── User.java
│ └── form/LoginByWeixinForm.java
├── naicha_app/ # 小程序API模块
│ ├── pom.xml
│ └── src/main/
│ ├── java/com/yu/app/
│ │ ├── NaichaAppRun.java # 启动类
│ │ ├── moudles/
│ │ │ ├── controller/UserController.java
│ │ │ ├── service/
│ │ │ │ ├── UserService.java
│ │ │ │ └── UserServiceImpl.java
│ │ │ └── mapper/UserMapper.java
│ │ └── common/mvc/WebMVCConfig.java
│ └── resources/
│ └── application.yml
└── naicha_system/ # 后台管理模块(类似结构)
十二、学习建议
12.1 循序渐进
- 第一步: 完成基础框架搭建(1-3天)
- 第二步: 实现一个完整的CRUD功能(2-3天)
- 第三步: 添加更多业务功能(持续)
12.2 参考资源
- Spring Boot官方文档: https://spring.io/projects/spring-boot
- MyBatis-Plus文档: https://baomidou.com/
- 项目源码: 参考现有代码学习
12.3 实践建议
- 多动手: 不要只看文档,要实际编写代码
- 多调试: 使用断点调试理解代码执行流程
- 多思考: 理解为什么这样设计,而不是死记硬背
最后更新: 2025-12-18
版本: 1.0

被折叠的 条评论
为什么被折叠?



