Browse Source

完成购物车、地址等功能

master
前端-胡立永 1 day ago
parent
commit
e388aa75ef
13 changed files with 88 additions and 1660 deletions
  1. +0
    -357
      jeecg-boot/jeecg-boot-module/jeecgboot-boot-applet/API接口文档.md
  2. +0
    -224
      jeecg-boot/jeecg-boot-module/jeecgboot-boot-applet/AppletShiroRealm触发问题分析.md
  3. +0
    -201
      jeecg-boot/jeecg-boot-module/jeecgboot-boot-applet/README-Applet-API.md
  4. +0
    -272
      jeecg-boot/jeecg-boot-module/jeecgboot-boot-applet/README-Applet-Module.md
  5. +13
    -59
      jeecg-boot/jeecg-boot-module/jeecgboot-boot-applet/src/main/java/org/jeecg/modules/applet/controller/AppletApiAddressController.java
  6. +5
    -18
      jeecg-boot/jeecg-boot-module/jeecgboot-boot-applet/src/main/java/org/jeecg/modules/applet/controller/AppletApiCarController.java
  7. +7
    -0
      jeecg-boot/jeecg-boot-module/jeecgboot-boot-applet/src/main/java/org/jeecg/modules/applet/service/AppletApiAddressService.java
  8. +1
    -9
      jeecg-boot/jeecg-boot-module/jeecgboot-boot-applet/src/main/java/org/jeecg/modules/applet/service/AppletApiCarService.java
  9. +31
    -4
      jeecg-boot/jeecg-boot-module/jeecgboot-boot-applet/src/main/java/org/jeecg/modules/applet/service/impl/AppletApiAddressServiceImpl.java
  10. +25
    -32
      jeecg-boot/jeecg-boot-module/jeecgboot-boot-applet/src/main/java/org/jeecg/modules/applet/service/impl/AppletApiCarServiceImpl.java
  11. +6
    -4
      jeecg-boot/jeecg-boot-module/jeecgboot-boot-applet/src/main/java/org/jeecg/modules/demo/appletCar/entity/AppletCar.java
  12. +0
    -202
      jeecg-boot/jeecg-boot-module/jeecgboot-boot-applet/小程序登录修复说明.md
  13. +0
    -278
      jeecg-boot/jeecg-boot-module/jeecgboot-boot-applet/小程序配置说明.md

+ 0
- 357
jeecg-boot/jeecg-boot-module/jeecgboot-boot-applet/API接口文档.md View File

@ -1,357 +0,0 @@
# 小程序登录API接口文档
## 概述
本文档描述小程序登录模块的API接口,包括登录、用户管理、token管理等功能。
## 基础信息
- **基础URL**: `http://your-domain/applet/login`
- **请求方式**: GET/POST
- **数据格式**: JSON
- **字符编码**: UTF-8
## 通用响应格式
```json
{
"success": true,
"message": "操作成功",
"code": 200,
"result": {}
}
```
## 接口列表
### 1. 微信小程序登录
**接口地址**: `POST /wxLogin`
**请求参数**:
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| code | String | 是 | 微信登录code |
**请求示例**:
```bash
curl -X POST "http://your-domain/applet/login/wxLogin" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "code=wx_login_code_here"
```
**响应示例**:
```json
{
"success": true,
"message": "登录成功",
"code": 200,
"result": {
"token": "eyJhbGciOiJIUzI1NiJ9...",
"userInfo": {
"id": "applet_user_123",
"name": "微信用户12345678",
"openid": "wx_openid_123",
"phone": "13800138000",
"avatar": "https://example.com/avatar.jpg",
"bmi": 22.5,
"fat": 15.2
},
"openid": "wx_openid_123",
"sessionKey": "session_key_123"
}
}
```
### 2. 获取用户手机号
**接口地址**: `POST /getPhoneNumber`
**请求参数**:
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| code | String | 是 | 手机号获取code |
**请求示例**:
```bash
curl -X POST "http://your-domain/applet/login/getPhoneNumber" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "code=phone_code_here"
```
**响应示例**:
```json
{
"success": true,
"message": "获取成功",
"code": 200,
"result": "13800138000"
}
```
### 3. 绑定手机号到用户
**接口地址**: `POST /bindPhoneNumber`
**请求参数**:
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| token | String | 是 | 用户token |
| phoneCode | String | 是 | 手机号获取code |
**请求示例**:
```bash
curl -X POST "http://your-domain/applet/login/bindPhoneNumber" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "token=user_token_here&phoneCode=phone_code_here"
```
**响应示例**:
```json
{
"success": true,
"message": "绑定成功",
"code": 200,
"result": "绑定成功"
}
```
### 4. 刷新token
**接口地址**: `POST /refreshToken`
**请求参数**:
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| token | String | 是 | 原token |
**请求示例**:
```bash
curl -X POST "http://your-domain/applet/login/refreshToken" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "token=old_token_here"
```
**响应示例**:
```json
{
"success": true,
"message": "刷新成功",
"code": 200,
"result": "eyJhbGciOiJIUzI1NiJ9..."
}
```
### 5. 退出登录
**接口地址**: `POST /logout`
**请求参数**:
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| token | String | 是 | 用户token |
**请求示例**:
```bash
curl -X POST "http://your-domain/applet/login/logout" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "token=user_token_here"
```
**响应示例**:
```json
{
"success": true,
"message": "退出成功",
"code": 200,
"result": "退出成功"
}
```
### 6. 检查登录状态
**接口地址**: `GET /checkLogin`
**请求参数**:
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| token | String | 是 | 用户token |
**请求示例**:
```bash
curl -X GET "http://your-domain/applet/login/checkLogin?token=user_token_here"
```
**响应示例**:
```json
{
"success": true,
"message": "登录有效",
"code": 200,
"result": {
"id": "applet_user_123",
"name": "微信用户12345678",
"openid": "wx_openid_123",
"phone": "13800138000",
"avatar": "https://example.com/avatar.jpg",
"bmi": 22.5,
"fat": 15.2
}
}
```
### 7. 获取用户信息
**接口地址**: `GET /getUserInfo`
**请求参数**:
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| token | String | 是 | 用户token |
**请求示例**:
```bash
curl -X GET "http://your-domain/applet/login/getUserInfo?token=user_token_here"
```
**响应示例**:
```json
{
"success": true,
"message": "获取成功",
"code": 200,
"result": {
"id": "applet_user_123",
"name": "微信用户12345678",
"openid": "wx_openid_123",
"phone": "13800138000",
"avatar": "https://example.com/avatar.jpg",
"bmi": 22.5,
"fat": 15.2
}
}
```
### 8. 更新用户信息
**接口地址**: `POST /updateUserInfo`
**请求参数**:
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| token | String | 是 | 用户token |
| userInfo | Object | 是 | 用户信息对象 |
**请求示例**:
```bash
curl -X POST "http://your-domain/applet/login/updateUserInfo" \
-H "Content-Type: application/json" \
-d '{
"token": "user_token_here",
"userInfo": {
"name": "新昵称",
"avatar": "https://example.com/new_avatar.jpg",
"bmi": 23.0,
"fat": 16.0
}
}'
```
**响应示例**:
```json
{
"success": true,
"message": "更新成功",
"code": 200,
"result": "更新成功"
}
```
## 错误码说明
| 错误码 | 说明 |
|--------|------|
| 200 | 成功 |
| 400 | 请求参数错误 |
| 401 | 未授权/token无效 |
| 403 | 禁止访问 |
| 404 | 资源不存在 |
| 500 | 服务器内部错误 |
## 常见错误响应
### 1. token无效
```json
{
"success": false,
"message": "token无效",
"code": 401,
"result": null
}
```
### 2. 用户不存在
```json
{
"success": false,
"message": "用户不存在",
"code": 404,
"result": null
}
```
### 3. 微信登录失败
```json
{
"success": false,
"message": "微信登录失败: code无效",
"code": 400,
"result": null
}
```
### 4. 手机号已被绑定
```json
{
"success": false,
"message": "该手机号已被其他用户绑定",
"code": 400,
"result": null
}
```
## 使用流程
### 1. 小程序登录流程
1. 小程序端调用 `wx.login()` 获取code
2. 调用 `/wxLogin` 接口进行登录
3. 保存返回的token用于后续请求
### 2. 手机号绑定流程
1. 小程序端调用 `wx.getPhoneNumber()` 获取手机号code
2. 调用 `/getPhoneNumber` 接口获取手机号
3. 调用 `/bindPhoneNumber` 接口绑定手机号到用户
### 3. token管理流程
1. 定期调用 `/refreshToken` 刷新token
2. 退出时调用 `/logout` 接口
3. 使用 `/checkLogin` 检查登录状态
## 安全注意事项
1. **token安全**: token应该安全存储,不要暴露给第三方
2. **HTTPS**: 生产环境必须使用HTTPS
3. **参数验证**: 客户端应该验证所有参数
4. **错误处理**: 客户端应该妥善处理各种错误情况
5. **日志记录**: 重要操作应该记录日志
## 性能优化建议
1. **缓存**: 用户信息可以适当缓存
2. **连接池**: 数据库和Redis连接池配置合理
3. **异步处理**: 非关键操作可以使用异步处理
4. **监控**: 添加接口调用监控和性能指标
## 测试建议
1. **单元测试**: 为每个接口编写单元测试
2. **集成测试**: 测试完整的登录流程
3. **压力测试**: 测试高并发场景
4. **安全测试**: 测试各种异常情况

+ 0
- 224
jeecg-boot/jeecg-boot-module/jeecgboot-boot-applet/AppletShiroRealm触发问题分析.md View File

@ -1,224 +0,0 @@
# AppletShiroRealm 触发问题分析
## 问题原因分析
### 1. 主要问题
`AppletShiroRealm` 没有被触发的主要原因是:
1. **Shiro配置问题**: 在 `ShiroConfig.java` 中,`shiroFilter` 方法使用的是 `SecurityManager` 参数,但这个参数绑定的是 `securityManager` Bean,而不是 `appletSecurityManager`
2. **过滤器配置问题**: 虽然配置了 `AppletJwtFilter`,但它没有正确关联到 `AppletShiroRealm`
3. **用户服务接口问题**: `IAppletUserService` 的包路径发生了变化,导致依赖注入失败。
### 2. 具体问题点
#### 2.1 Shiro配置问题
```java
// 原来的配置
@Bean("shiroFilterFactoryBean")
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
// 这里使用的是 securityManager,而不是 appletSecurityManager
}
```
#### 2.2 过滤器链配置问题
```java
// 小程序请求应该使用 appletApi 过滤器
filterChainDefinitionMap.put("/appletApi/**", "appletApi");
```
#### 2.3 用户服务依赖问题
```java
// 原来的包路径
import org.jeecg.modules.appletBackground.appletUser.service.IAppletUserService;
// 修改后的包路径
import org.jeecg.common.api.IAppletUserService;
```
## 解决方案
### 1. 修复Shiro配置
#### 1.1 修改ShiroConfig.java
- 在 `shiroFilter` 方法中添加小程序登录接口的匿名访问配置
- 确保小程序请求使用正确的过滤器
```java
// 小程序登录相关接口不需要认证
filterChainDefinitionMap.put("/appletApi/login/wxLogin", "anon");
filterChainDefinitionMap.put("/appletApi/login/getPhoneNumber", "anon");
// applet专用过滤器,只处理/applet开头的请求
filterChainDefinitionMap.put("/appletApi/**", "appletApi");
```
#### 1.2 修复AppletJwtFilter
- 添加登录接口的匿名访问检查
- 完善token验证逻辑
- 增加详细的错误日志
```java
// 检查是否是登录相关接口,这些接口不需要认证
if (requestPath.startsWith("/appletApi/login/wxLogin") ||
requestPath.startsWith("/appletApi/login/getPhoneNumber")) {
return true;
}
```
### 2. 修复用户服务接口
#### 2.1 创建统一的IAppletUserService接口
```java
package org.jeecg.common.api;
public interface IAppletUserService {
AppletUser getByOpenid(String openid);
AppletUser getByPhone(String phone);
boolean save(AppletUser user);
boolean updateById(AppletUser user);
}
```
#### 2.2 实现服务类
```java
@Service
public class AppletUserServiceImpl extends ServiceImpl<AppletUserMapper, AppletUser>
implements IAppletUserService {
// 实现具体方法
}
```
### 3. 修复AppletShiroRealm
#### 3.1 完善用户获取逻辑
```java
private AppletUser getAppletUser(String openid) {
try {
// 从数据库查询用户信息
AppletUser appletUser = appletUserService.getByOpenid(openid);
if (appletUser != null) {
log.debug("从数据库获取到小程序用户: {}", appletUser.getName());
return appletUser;
}
log.warn("未找到小程序用户,openid: {}", openid);
return null;
} catch (Exception e) {
log.error("获取小程序用户信息异常,openid: {}", openid, e);
return null;
}
}
```
#### 3.2 完善权限配置
```java
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
// 小程序用户默认权限
info.addRole("applet_user");
info.addStringPermission("applet:user:*");
return info;
}
```
### 4. 修复服务层方法
#### 4.1 使用AppletUserUtil获取当前用户
```java
public Result<String> bindPhoneNumber(String phoneCode) {
try {
// 获取当前登录用户
AppletUser currentUser = AppletUserUtil.getCurrentAppletUser();
if (currentUser == null) {
return Result.error("用户未登录");
}
// 其他逻辑...
} catch (Exception e) {
log.error("绑定手机号异常", e);
return Result.error("绑定失败: " + e.getMessage());
}
}
```
#### 4.2 简化控制器方法
```java
@GetMapping("/getUserInfo")
public Result<AppletUser> getUserInfo() {
log.info("收到获取用户信息请求");
return appletApiLoginService.getUserInfo();
}
```
## 测试验证
### 1. 创建测试控制器
```java
@RestController
@RequestMapping("/appletApi/test")
public class AppletTestController {
@GetMapping("/getCurrentUser")
public Result<AppletUser> getCurrentUser() {
AppletUser currentUser = AppletUserUtil.getCurrentAppletUser();
if (currentUser == null) {
return Result.error("用户未登录");
}
return Result.OK("获取成功", currentUser);
}
}
```
### 2. 测试步骤
1. 先调用登录接口获取token
2. 使用token调用测试接口
3. 检查日志中是否有 `AppletShiroRealm` 的调试信息
4. 验证用户信息是否正确返回
## 关键修复点总结
### 1. 配置层面
- ✅ 修复了Shiro配置中的过滤器链
- ✅ 添加了小程序登录接口的匿名访问
- ✅ 确保小程序请求使用正确的过滤器
### 2. 代码层面
- ✅ 修复了用户服务接口的包路径问题
- ✅ 完善了AppletShiroRealm的用户获取逻辑
- ✅ 添加了详细的日志记录
- ✅ 使用AppletUserUtil简化用户获取
### 3. 测试层面
- ✅ 创建了测试控制器验证功能
- ✅ 提供了完整的测试步骤
## 预期效果
修复后,当访问 `/appletApi/**` 路径的请求时:
1. **AppletJwtFilter** 会被触发
2. **AppletShiroRealm** 会进行用户认证
3. **AppletUserUtil** 可以正确获取当前用户
4. 日志中会显示相关的调试信息
## 注意事项
1. **包路径**: 确保所有相关的import语句都使用正确的包路径
2. **Bean注入**: 确保 `IAppletUserService` 的实现类被正确注册为Spring Bean
3. **数据库**: 确保 `applet_user` 表存在且有数据
4. **Redis**: 确保Redis服务正常运行
5. **日志级别**: 建议将 `AppletShiroRealm` 的日志级别设置为DEBUG,便于调试
## 调试建议
1. 在 `AppletShiroRealm` 的关键方法中添加日志
2. 检查Spring Bean是否正确注入
3. 验证数据库连接和查询是否正常
4. 确认Redis缓存是否正常工作
5. 使用测试接口逐步验证功能

+ 0
- 201
jeecg-boot/jeecg-boot-module/jeecgboot-boot-applet/README-Applet-API.md View File

@ -1,201 +0,0 @@
# 小程序基础查询接口文档
## 概述
本文档描述了小程序基础的不需要登录的查询接口,包括产品、Banner、配置信息等模块的查询功能。
## 接口列表
### 1. 产品模块 (Product)
#### 1.1 产品列表查询
- **接口地址**: `GET /applet/product/list`
- **接口描述**: 分页查询产品,支持按分类、关键词筛选
- **请求参数**:
- `type` (必填): 产品类型
- `pageNo` (可选): 页码,默认1
- `pageSize` (可选): 每页大小,默认10
- `classId` (可选): 分类ID
- `keyword` (可选): 关键词,支持产品名称、描述、详情模糊搜索
- **响应示例**:
```json
{
"success": true,
"message": "操作成功!",
"code": 200,
"result": {
"records": [
{
"id": "xxx",
"name": "产品名称",
"info": "产品描述",
"type": "产品类型",
"classId": "分类ID",
"originalPrice": 100.00,
"currentPrice": 80.00,
"unit": "单位",
"detail": "产品详情",
"sold": 100,
"content": "产品内容"
}
],
"total": 100,
"size": 10,
"current": 1
}
}
```
#### 1.2 产品详情查询
- **接口地址**: `GET /applet/product/detail`
- **接口描述**: 获取单个产品详细信息
- **请求参数**:
- `id` (必填): 产品ID
- **响应示例**:
```json
{
"success": true,
"message": "操作成功!",
"code": 200,
"result": {
"id": "xxx",
"name": "产品名称",
"info": "产品描述",
"type": "产品类型",
"classId": "分类ID",
"originalPrice": 100.00,
"currentPrice": 80.00,
"unit": "单位",
"detail": "产品详情",
"sold": 100,
"content": "产品内容"
}
}
```
#### 1.3 产品分类查询
- **接口地址**: `GET /applet/product/category`
- **接口描述**: 根据类型查询产品分类
- **请求参数**:
- `type` (必填): 产品类型
- **响应示例**:
```json
{
"success": true,
"message": "操作成功!",
"code": 200,
"result": [
{
"id": "xxx",
"name": "分类名称",
"description": "分类描述",
"sortOrder": 1,
"type": "产品类型"
}
]
}
```
### 2. Banner模块 (Banner)
#### 2.1 Banner列表查询
- **接口地址**: `GET /applet/banner/list`
- **接口描述**: 获取Banner列表,按类型分组,按排序字段排序
- **请求参数**: 无
- **响应示例**:
```json
{
"success": true,
"message": "操作成功!",
"code": 200,
"result": {
"home": [
{
"id": "xxx",
"imageUrl": "图片地址",
"linkUrl": "跳转链接",
"sortOrder": 1,
"type": "home"
}
],
"product": [
{
"id": "xxx",
"imageUrl": "图片地址",
"linkUrl": "跳转链接",
"sortOrder": 1,
"type": "product"
}
]
}
}
```
### 3. 配置信息模块 (Config)
#### 3.1 配置列表查询
- **接口地址**: `GET /applet/config/list`
- **接口描述**: 查询所有配置信息
- **请求参数**: 无
- **响应示例**:
```json
{
"success": true,
"message": "操作成功!",
"code": 200,
"result": [
{
"id": "xxx",
"code": "配置编码",
"info": "配置描述",
"content": "配置内容",
"type": "配置类型"
}
]
}
```
## 技术特点
1. **Lambda查询**: 所有数据库查询都使用MyBatis-Plus的LambdaQueryWrapper,提供类型安全的查询
2. **模块化设计**: 按业务模块分类,每个模块独立的Controller和Service
3. **复用性高**: 数据库操作复用demo模块的Mapper,避免重复代码
4. **统一响应**: 使用统一的Result响应格式
5. **参数校验**: 必填参数校验,可选参数支持默认值
6. **日志记录**: 所有接口都有详细的日志记录
## 使用示例
### 查询产品列表
```bash
curl -X GET "http://localhost:8080/applet/product/list?type=1&pageNo=1&pageSize=10&keyword=测试"
```
### 查询产品详情
```bash
curl -X GET "http://localhost:8080/applet/product/detail?id=xxx"
```
### 查询产品分类
```bash
curl -X GET "http://localhost:8080/applet/product/category?type=1"
```
### 查询Banner列表
```bash
curl -X GET "http://localhost:8080/applet/banner/list"
```
### 查询配置列表
```bash
curl -X GET "http://localhost:8080/applet/config/list"
```
## 注意事项
1. 所有接口都不需要登录认证
2. 产品列表查询的type参数为必填项
3. 分页参数pageNo从1开始
4. 关键词搜索支持产品名称、描述、详情的模糊匹配
5. Banner按类型分组返回,便于前端按需使用
6. 配置信息按编码排序返回

+ 0
- 272
jeecg-boot/jeecg-boot-module/jeecgboot-boot-applet/README-Applet-Module.md View File

@ -1,272 +0,0 @@
# 小程序模块使用说明
## 概述
本模块为健康管理小程序提供后端服务支持,包含登录、用户管理、微信功能等核心功能。
## 目录结构
```
jeecgboot-boot-applet/
├── src/main/java/org/jeecg/modules/
│ ├── applet/ # 小程序核心模块
│ │ ├── controller/ # 控制器层
│ │ │ ├── AppletLoginController.java # 登录控制器
│ │ │ ├── AppletUserController.java # 用户控制器
│ │ │ └── WxAppletController.java # 微信控制器
│ │ └── service/ # 服务层
│ │ ├── AppletLoginService.java # 登录服务
│ │ ├── AppletUserService.java # 用户服务
│ │ └── WxAppletService.java # 微信服务
│ └── common/
│ └── wxUtils/ # 微信工具类
│ ├── WxHttpUtils.java # 微信HTTP工具
│ └── WxHttpClientUtil.java # 微信HTTP客户端
└── src/main/resources/
└── application-applet.yml # 小程序配置文件
```
## 功能模块
### 1. 登录模块 (AppletLoginController)
#### 接口列表
- `POST /applet/login/wxLogin` - 微信小程序登录
- `POST /applet/login/getPhoneNumber` - 获取用户手机号
- `POST /applet/login/refreshToken` - 刷新token
- `POST /applet/login/logout` - 退出登录
- `GET /applet/login/checkLogin` - 检查登录状态
#### 使用示例
```javascript
// 小程序登录
wx.login({
success: (res) => {
if (res.code) {
// 发送 res.code 到后台换取 openId, sessionKey, unionId
wx.request({
url: 'http://your-domain/applet/login/wxLogin',
method: 'POST',
data: {
code: res.code
},
success: (result) => {
console.log('登录成功', result.data);
// 保存token
wx.setStorageSync('token', result.data.result.token);
}
});
}
}
});
```
### 2. 用户模块 (AppletUserController)
#### 接口列表
- `GET /applet/user/info` - 获取用户信息
- `POST /applet/user/update` - 更新用户信息
- `GET /applet/user/health` - 获取健康信息
- `POST /applet/user/health/update` - 更新健康信息
- `GET /applet/user/member` - 获取会员信息
#### 使用示例
```javascript
// 获取用户信息
wx.request({
url: 'http://your-domain/applet/user/info',
method: 'GET',
data: {
userId: 'applet_user_id'
},
header: {
'Authorization': 'Bearer ' + wx.getStorageSync('token')
},
success: (result) => {
console.log('用户信息', result.data);
}
});
```
### 3. 微信模块 (WxAppletController)
#### 接口列表
- `POST /applet/wx/qrcode` - 获取小程序码
- `POST /applet/wx/subscribe/send` - 发送订阅消息
- `GET /applet/wx/config` - 获取小程序配置
- `GET /applet/wx/check` - 检查微信服务器
- `GET /applet/wx/user/info` - 获取微信用户信息
#### 使用示例
```javascript
// 获取小程序码
wx.request({
url: 'http://your-domain/applet/wx/qrcode',
method: 'POST',
data: {
scene: 'user_id_123',
page: 'pages/index/index'
},
success: (result) => {
console.log('小程序码', result.data);
}
});
```
## 配置说明
### 1. 微信配置
`application-applet.yml` 中配置微信小程序信息:
```yaml
applet:
wechat:
mpAppId: your_applet_appid
mpAppSecret: your_applet_secret
pay:
mchId: your_mch_id
mchKey: your_mch_key
```
### 2. 环境变量
可以通过环境变量覆盖配置:
```bash
export WECHAT_MP_APPID=your_applet_appid
export WECHAT_MP_APPSECRET=your_applet_secret
export WECHAT_MCH_ID=your_mch_id
export WECHAT_MCH_KEY=your_mch_key
```
### 3. 功能开关
可以通过配置文件控制功能模块的启用:
```yaml
applet:
features:
login: true # 登录功能
userInfo: true # 用户信息功能
healthInfo: true # 健康信息功能
member: true # 会员功能
subscribe: true # 订阅消息功能
qrcode: true # 小程序码功能
```
## 安全配置
### 1. Token配置
```yaml
applet:
security:
tokenExpireTime: 7200 # token过期时间(秒)
refreshTokenExpireTime: 604800 # 刷新token过期时间(秒)
enableTokenBlacklist: true # 启用token黑名单
```
### 2. 接口权限
所有小程序接口都使用了 `@IgnoreAuth` 注解,表示不需要登录验证。在实际使用中,可以根据需要添加token验证。
## 日志配置
```yaml
applet:
logging:
level: INFO
logWxApi: true # 记录微信API调用日志
logUserAction: true # 记录用户操作日志
```
## 缓存配置
```yaml
applet:
cache:
accessTokenExpire: 7000 # 微信access_token缓存时间(秒)
userInfoExpire: 3600 # 用户信息缓存时间(秒)
qrcodeExpire: 86400 # 小程序码缓存时间(秒)
```
## 开发说明
### 1. 数据库集成
当前版本使用模拟数据,实际使用时需要:
1. 创建用户表 `applet_user`
2. 创建健康信息表 `applet_health_info`
3. 创建会员信息表 `applet_member_info`
4. 在Service层实现数据库操作
### 2. 微信API集成
已集成以下微信API:
- 登录:`/sns/jscode2session`
- 获取手机号:`/wxa/business/getuserphonenumber`
- 获取access_token:`/cgi-bin/token`
- 获取小程序码:`/wxa/getwxacodeunlimit`
- 发送订阅消息:`/cgi-bin/message/subscribe/send`
### 3. 错误处理
所有接口都包含完整的异常处理:
- 微信API调用失败
- 参数验证失败
- 数据库操作失败
- 网络连接失败
### 4. 扩展开发
如需添加新功能,可以:
1. 在 `service` 包下创建新的服务类
2. 在 `controller` 包下创建对应的控制器
3. 在配置文件中添加相关配置
4. 更新本文档
## 部署说明
### 1. 打包
```bash
mvn clean package -Dmaven.test.skip=true
```
### 2. 运行
```bash
java -jar jeecgboot-boot-applet.jar --spring.profiles.active=prod
```
### 3. Docker部署
```dockerfile
FROM openjdk:8-jre-alpine
COPY jeecgboot-boot-applet.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app.jar"]
```
## 注意事项
1. **安全性**:生产环境中请务必配置正确的微信小程序密钥
2. **性能**:建议对微信API调用结果进行缓存
3. **监控**:建议添加接口调用监控和日志收集
4. **测试**:请在小程序开发工具中充分测试所有功能
5. **文档**:接口文档可通过Swagger UI查看:`http://your-domain/swagger-ui.html`
## 技术支持
如有问题,请联系开发团队或查看项目文档。

+ 13
- 59
jeecg-boot/jeecg-boot-module/jeecgboot-boot-applet/src/main/java/org/jeecg/modules/applet/controller/AppletApiAddressController.java View File

@ -101,66 +101,20 @@ public class AppletApiAddressController {
return Result.OK("编辑成功!");
}
/**
* 设置默认地址
*
* @param addressId 地址ID
* @return
*/
@Operation(summary="小程序收货地址-设置默认地址")
@PutMapping(value = "/setDefault")
@IgnoreAuth
public Result<String> setDefaultAddress(@RequestParam String addressId) {
appletAddressService.setDefaultAddress(addressId);
return Result.OK("设置默认地址成功!");
}
// /**
// * 通过id删除
// *
// * @param id
// * @return
// */
// @Operation(summary="小程序收货地址-通过id删除")
// @DeleteMapping(value = "/delete")
// public Result<String> delete(@RequestParam(name="id",required=true) String id) {
// appletAddressService.removeById(id);
// return Result.OK("删除成功!");
// }
// /**
// * 批量删除
// *
// * @param ids
// * @return
// */
// @AutoLog(value = "小程序收货地址-批量删除")
// @Operation(summary="小程序收货地址-批量删除")
// @RequiresPermissions("appletShippingAddress:applet_shipping_address:deleteBatch")
// @DeleteMapping(value = "/deleteBatch")
// public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
// this.appletAddressService.removeByIds(Arrays.asList(ids.split(",")));
// return Result.OK("批量删除成功!");
// }
// /**
// * 导出excel
// *
// * @param request
// * @param appletShippingAddress
// */
// @RequiresPermissions("appletShippingAddress:applet_shipping_address:exportXls")
// @RequestMapping(value = "/exportXls")
// public ModelAndView exportXls(HttpServletRequest request, AppletShippingAddress appletShippingAddress) {
// return super.exportXls(request, appletShippingAddress, AppletShippingAddress.class, "小程序收货地址");
// }
//
// /**
// * 通过excel导入数据
// *
// * @param request
// * @param response
// * @return
// */
// @RequiresPermissions("appletShippingAddress:applet_shipping_address:importExcel")
// @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
// public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
// return super.importExcel(request, response, AppletShippingAddress.class);
// }
}

+ 5
- 18
jeecg-boot/jeecg-boot-module/jeecgboot-boot-applet/src/main/java/org/jeecg/modules/applet/controller/AppletApiCarController.java View File

@ -72,22 +72,7 @@ public class AppletApiCarController {
return Result.OK("添加成功!");
}
/**
* 通过id查询
*
* @param id
* @return
*/
//@AutoLog(value = "购物车-通过id查询")
@Operation(summary = "购物车-通过id查询")
@GetMapping(value = "/queryById")
public Result<AppletCar> queryById(@RequestParam(name = "id", required = true) String id) {
AppletCar appletCar = appletApiCarService.getById(id);
if (appletCar == null) {
return Result.error("未找到对应数据");
}
return Result.OK(appletCar);
}
/**
* 编辑
@ -101,6 +86,8 @@ public class AppletApiCarController {
appletApiCarService.updateById(appletCar);
return Result.OK("编辑购物车!");
}
/**
* 批量删除
*
@ -109,8 +96,8 @@ public class AppletApiCarController {
*/
@Operation(summary="购物车-批量删除")
@DeleteMapping(value = "/deleteBatch")
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
this.appletApiCarService.removeById(Arrays.asList(ids.split(",")).toString());
public Result<String> deleteBatch(@RequestParam(name="ids") String ids) {
appletApiCarService.removeByIds(Arrays.asList(ids.split(",")));
return Result.OK("批量删除成功!");
}


+ 7
- 0
jeecg-boot/jeecg-boot-module/jeecgboot-boot-applet/src/main/java/org/jeecg/modules/applet/service/AppletApiAddressService.java View File

@ -39,6 +39,13 @@ public interface AppletApiAddressService {
*/
void updateById(AppletShippingAddress appletShippingAddress);
/**
* 设置默认地址
*
* @param addressId 地址ID
*/
void setDefaultAddress(String addressId);
// /**
// * 通过id删除


+ 1
- 9
jeecg-boot/jeecg-boot-module/jeecgboot-boot-applet/src/main/java/org/jeecg/modules/applet/service/AppletApiCarService.java View File

@ -1,6 +1,5 @@
package org.jeecg.modules.applet.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.jeecg.modules.demo.appletCar.entity.AppletCar;
@ -13,7 +12,7 @@ public interface AppletApiCarService {
* 查询购物车列表
*
* @param page
* @param queryWrapper
* @param appletCar
* @return
*/
IPage<AppletCar> page(Page<AppletCar> page, AppletCar appletCar);
@ -25,13 +24,6 @@ public interface AppletApiCarService {
*/
void save(AppletCar appletCar);
/**
* 根据id查询购物车
*
* @param id
* @return
*/
AppletCar getById(String id);
/**
* 修改购物车


+ 31
- 4
jeecg-boot/jeecg-boot-module/jeecgboot-boot-applet/src/main/java/org/jeecg/modules/applet/service/impl/AppletApiAddressServiceImpl.java View File

@ -15,6 +15,7 @@ import org.springframework.stereotype.Service;
@Service
@Slf4j
public class AppletApiAddressServiceImpl implements AppletApiAddressService {
@Autowired
private IAppletShippingAddressService appletShippingAddressService;
@ -32,12 +33,11 @@ public class AppletApiAddressServiceImpl implements AppletApiAddressService {
Page<AppletShippingAddress> page1 = appletShippingAddressService
.lambdaQuery()
.eq(AppletShippingAddress::getUserId, userId)//getId -> getUserId
.eq(AppletShippingAddress::getUserId, userId)
.orderByDesc(AppletShippingAddress::getDefaultFlag)
//如果你要写查询条件这样写
//.eq(AppletShippingAddress::getCity, address.getCity())//这个是 等于
//.eq(StrUtil.isNotBlank((address.getCity()), AppletShippingAddress::getCity, address.getCity())//这样加条件不为空
.page(page);
return page1;
}
@ -105,4 +105,31 @@ public class AppletApiAddressServiceImpl implements AppletApiAddressService {
appletShippingAddressService.updateById(appletShippingAddress);
}
/**
* 设置默认地址
*
* @param addressId 地址ID
*/
@Override
public void setDefaultAddress(String addressId) {
if (StrUtil.isBlank(addressId)) {
throw new IllegalArgumentException("地址ID不能为空");
}
String userId = AppletUserUtil.getCurrentAppletUserId();
// 先取消该用户所有地址的默认状态
appletShippingAddressService.lambdaUpdate()
.eq(AppletShippingAddress::getUserId, userId)
.set(AppletShippingAddress::getDefaultFlag, 0)
.update();
// 设置指定地址为默认地址
appletShippingAddressService.lambdaUpdate()
.eq(AppletShippingAddress::getId, addressId)
.eq(AppletShippingAddress::getUserId, userId)
.set(AppletShippingAddress::getDefaultFlag, 1)
.update();
}
}

+ 25
- 32
jeecg-boot/jeecg-boot-module/jeecgboot-boot-applet/src/main/java/org/jeecg/modules/applet/service/impl/AppletApiCarServiceImpl.java View File

@ -3,10 +3,12 @@ package org.jeecg.modules.applet.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.util.AppletUserUtil;
import org.jeecg.modules.applet.service.AppletApiCarService;
import org.jeecg.modules.demo.appletCar.entity.AppletCar;
import org.jeecg.modules.demo.appletCar.service.IAppletCarService;
import org.jeecg.modules.demo.appletProduct.service.IAppletProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -15,9 +17,13 @@ import java.util.stream.Collectors;
@Service
public class AppletApiCarServiceImpl implements AppletApiCarService {
@Autowired
private IAppletCarService appletCarService;
@Autowired
private IAppletProductService appletProductService;
/**
* 购物车列表查询
*
@ -32,6 +38,11 @@ public class AppletApiCarServiceImpl implements AppletApiCarService {
.lambdaQuery()
.eq(AppletCar::getUserId, userId)
.page(page);
for (AppletCar record : page1.getRecords()) {
record.setProduct(appletProductService.getById(record.getProductId()));
}
return page1;
}
@ -43,28 +54,22 @@ public class AppletApiCarServiceImpl implements AppletApiCarService {
@Override
public void save(AppletCar appletCar) {
appletCarService.save(appletCar);
}
/**
* 根据id查询购物车
*
* @param id 购物车id
* @return 购物车对象
*/
@Override
public AppletCar getById(String id) {
// 获取当前登录的小程序用户ID
String userId = AppletUserUtil.getCurrentAppletUserId();
// 使用LambdaQuery构造查询条件同时匹配购物车ID和用户ID确保数据隔离
AppletCar appletCar = appletCarService
.lambdaQuery()
.eq(AppletCar::getId, id) // 匹配购物车ID
.eq(AppletCar::getUserId, userId) // 匹配用户ID
.one(); // 查询单个结果
return appletCar;
// 验证该购物车是否属于当前用户
// AppletCar existingCar = appletCarService
// .lambdaQuery()
// .eq(AppletCar::getProductId, appletCar.getProductId()) // 匹配购物车ID
// .eq(AppletCar::getSkuId, appletCar.getSkuId()) // 匹配购物车ID
// .eq(AppletCar::getUserId, userId) // 匹配用户ID
// .one();
appletCar.setUserId(userId);
appletCarService.save(appletCar);
}
/**
* 修改购物车
*
@ -93,21 +98,9 @@ public class AppletApiCarServiceImpl implements AppletApiCarService {
*/
@Override
public void removeByIds(List<String> ids) {
// 获取当前登录的小程序用户ID
String userId = AppletUserUtil.getCurrentAppletUserId();
// 查询这些ID中属于当前用户的购物车项
List<AppletCar> appletCars = appletCarService
.lambdaQuery()
.in(AppletCar::getId, ids) // 匹配购物车ID列表
.eq(AppletCar::getUserId, userId) // 匹配用户ID
.list();
// 提取属于当前用户的购物车ID列表
List<String> userCarIds = appletCars.stream()
.map(AppletCar::getId)
.collect(Collectors.toList());
// 执行删除操作只会删除属于当前用户的购物车项
if (!userCarIds.isEmpty()) {
appletCarService.removeByIds(userCarIds);
if (!ids.isEmpty()) {
appletCarService.removeByIds(ids);
}
}
}

+ 6
- 4
jeecg-boot/jeecg-boot-module/jeecgboot-boot-applet/src/main/java/org/jeecg/modules/demo/appletCar/entity/AppletCar.java View File

@ -4,14 +4,13 @@ import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.*;
import org.jeecg.common.constant.ProvinceCityArea;
import org.jeecg.common.util.SpringContextUtils;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.jeecg.modules.demo.appletProduct.entity.AppletProduct;
import org.springframework.format.annotation.DateTimeFormat;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.jeecg.common.aspect.annotation.Dict;
@ -68,4 +67,7 @@ public class AppletCar implements Serializable {
@Excel(name = "商品规格", width = 15)
@Schema(description = "商品规格")
private java.lang.String skuId;
@TableField(exist = false)
private AppletProduct product;
}

+ 0
- 202
jeecg-boot/jeecg-boot-module/jeecgboot-boot-applet/小程序登录修复说明.md View File

@ -1,202 +0,0 @@
# 小程序登录修复说明
## 修复的问题
### 1. 用户信息获取问题
**原问题**: `AppletShiroRealm` 中的 `getAppletUser` 方法返回null,导致无法正确获取用户信息。
**修复方案**:
- 完善了 `getAppletUser` 方法,支持从数据库和Redis缓存获取用户信息
- 添加了用户信息缓存机制,提高性能
- 增加了异常处理和日志记录
### 2. Token验证逻辑不完整
**原问题**: Token验证缺少黑名单检查和刷新机制。
**修复方案**:
- 添加了token黑名单检查
- 完善了token刷新逻辑
- 统一了token管理机制
### 3. Shiro认证体系集成问题
**原问题**: 小程序登录没有正确集成到Shiro认证体系。
**修复方案**:
- 创建了专用的 `AppletShiroConfig` 配置类
- 完善了 `AppletShiroRealm` 的认证和授权逻辑
- 添加了小程序用户默认权限配置
### 4. 控制器参数验证不足
**原问题**: 控制器缺少参数验证和错误处理。
**修复方案**:
- 添加了完整的参数验证
- 增加了Swagger API文档注解
- 完善了错误处理和日志记录
## 新增功能
### 1. 用户工具类
创建了 `AppletUserUtil` 工具类,提供以下功能:
- `getCurrentAppletUser()`: 获取当前登录的小程序用户
- `getCurrentAppletUserId()`: 获取当前用户ID
- `getCurrentAppletUserOpenid()`: 获取当前用户openid
- `isAppletUserLoggedIn()`: 检查用户是否已登录
- `hasPermission()`: 检查用户权限
- `hasRole()`: 检查用户角色
### 2. 缓存机制
- 用户信息缓存(30分钟)
- Token缓存(JWT过期时间的2倍)
- Session_key缓存(7天)
- 手机号临时缓存(5分钟)
- Token黑名单缓存(24小时)
### 3. 权限控制
- 小程序用户默认角色:`applet_user`
- 小程序用户默认权限:`applet:user:*`
- 支持细粒度权限控制
## 使用示例
### 1. 在控制器中获取当前用户
```java
@GetMapping("/getCurrentUser")
public Result<AppletUser> getCurrentUser() {
AppletUser currentUser = AppletUserUtil.getCurrentAppletUser();
if (currentUser == null) {
return Result.error("用户未登录");
}
return Result.OK("获取成功", currentUser);
}
```
### 2. 权限检查
```java
@PostMapping("/sensitiveOperation")
public Result<String> sensitiveOperation() {
if (!AppletUserUtil.hasPermission("applet:user:edit")) {
return Result.error("权限不足");
}
// 执行敏感操作
return Result.OK("操作成功");
}
```
### 3. 角色检查
```java
@GetMapping("/adminOnly")
public Result<String> adminOnly() {
if (!AppletUserUtil.hasRole("applet_admin")) {
return Result.error("需要管理员权限");
}
return Result.OK("管理员操作成功");
}
```
## 配置要求
### 1. 数据库配置
确保 `applet_user` 表已创建,包含以下字段:
- `id`: 主键
- `openid`: 微信openid(唯一索引)
- `phone`: 手机号(唯一索引)
- `name`: 用户昵称
- `avatar`: 头像
- `bmi`: 体总指数
- `fat`: 脂肪
- `create_time`: 创建时间
- `update_time`: 更新时间
### 2. Redis配置
确保Redis服务正常运行,用于缓存:
- 用户信息
- Token缓存
- Session_key
- 黑名单
### 3. 微信配置
`application.yml` 中配置:
```yaml
wechat:
mpAppId: your_applet_appid
mpAppSecret: your_applet_secret
```
### 4. JWT配置
确保JWT工具类能正确读取配置:
```yaml
jeecg:
jwt:
secret: your_jwt_secret_key
expire: 604800
```
## 安全改进
### 1. Token安全
- 生产环境不返回session_key
- Token自动刷新机制
- Token黑名单管理
- 支持token主动失效
### 2. 参数验证
- 所有接口都添加了参数验证
- 防止空参数和恶意参数
- 统一的错误处理
### 3. 权限控制
- 基于Shiro的权限控制
- 支持角色和权限检查
- 细粒度权限管理
## 性能优化
### 1. 缓存策略
- 用户信息缓存减少数据库查询
- Token缓存提高验证速度
- 合理的缓存过期时间
### 2. 异常处理
- 完善的异常捕获和处理
- 详细的日志记录
- 友好的错误提示
### 3. 并发处理
- 线程安全的用户信息获取
- 原子性的token操作
- 避免并发冲突
## 测试建议
### 1. 功能测试
- 测试完整的登录流程
- 测试token刷新机制
- 测试权限控制功能
- 测试异常情况处理
### 2. 性能测试
- 测试高并发登录
- 测试缓存命中率
- 测试数据库连接池
### 3. 安全测试
- 测试token伪造防护
- 测试权限绕过防护
- 测试参数注入防护
## 注意事项
1. **生产环境配置**: 确保生产环境使用HTTPS,不要暴露敏感信息
2. **日志管理**: 合理配置日志级别,避免敏感信息泄露
3. **监控告警**: 添加关键操作的监控和告警
4. **备份策略**: 定期备份用户数据和配置信息
5. **版本兼容**: 注意API版本兼容性,避免影响现有客户端
## 后续优化建议
1. **多租户支持**: 如果需要支持多租户,可以扩展用户表结构
2. **第三方登录**: 可以扩展支持其他第三方登录方式
3. **消息推送**: 集成消息推送功能,支持实时通知
4. **数据分析**: 添加用户行为分析功能
5. **自动化测试**: 编写完整的自动化测试用例

+ 0
- 278
jeecg-boot/jeecg-boot-module/jeecgboot-boot-applet/小程序配置说明.md View File

@ -1,278 +0,0 @@
# 小程序模块配置说明
## 概述
本文档说明小程序登录服务需要配置的内容,包括数据库、Redis、微信配置等。
## 1. 数据库配置
### 1.1 数据库表结构
需要确保 `applet_user` 表已创建,表结构如下:
```sql
CREATE TABLE `applet_user` (
`id` varchar(32) NOT NULL COMMENT '主键',
`create_by` varchar(50) DEFAULT NULL COMMENT '创建人',
`create_time` datetime DEFAULT NULL COMMENT '创建日期',
`update_by` varchar(50) DEFAULT NULL COMMENT '更新人',
`update_time` datetime DEFAULT NULL COMMENT '更新日期',
`sys_org_code` varchar(64) DEFAULT NULL COMMENT '所属部门',
`name` varchar(100) DEFAULT NULL COMMENT '昵称',
`openid` varchar(100) DEFAULT NULL COMMENT '第三方认证id',
`phone` varchar(20) DEFAULT NULL COMMENT '手机号',
`bmi` decimal(10,2) DEFAULT NULL COMMENT '体总指数',
`fat` decimal(10,2) DEFAULT NULL COMMENT '脂肪',
`avatar` varchar(500) DEFAULT NULL COMMENT '头像',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_openid` (`openid`),
UNIQUE KEY `uk_phone` (`phone`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='小程序用户表';
```
### 1.2 数据库连接配置
`application.yml` 中配置数据库连接:
```yaml
spring:
datasource:
url: jdbc:mysql://localhost:3306/jeecg-boot?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
```
## 2. Redis配置
### 2.1 Redis连接配置
`application.yml` 中配置Redis:
```yaml
spring:
redis:
host: localhost
port: 6379
password:
database: 0
timeout: 10000ms
lettuce:
pool:
max-active: 8
max-wait: -1ms
max-idle: 8
min-idle: 0
```
### 2.2 Redis配置类
需要创建Redis配置类:
```java
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
// 设置key的序列化方式
template.setKeySerializer(new StringRedisSerializer());
// 设置value的序列化方式
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
// 设置hash key的序列化方式
template.setHashKeySerializer(new StringRedisSerializer());
// 设置hash value的序列化方式
template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
template.afterPropertiesSet();
return template;
}
}
```
## 3. 微信小程序配置
### 3.1 微信配置
`application.yml` 中配置微信小程序信息:
```yaml
wechat:
mpAppId: your_applet_appid
mpAppSecret: your_applet_secret
merchantId: your_merchant_id # 如果需要支付功能
```
### 3.2 微信配置类
确保 `WxHttpUtils` 类能正确读取配置:
```java
@Component
public class WxHttpUtils {
@Value("${wechat.mpAppId}")
private String appid;
@Value("${wechat.mpAppSecret}")
private String secret;
}
```
## 4. JWT配置
### 4.1 JWT密钥配置
`application.yml` 中配置JWT密钥:
```yaml
jeecg:
jwt:
secret: your_jwt_secret_key
expire: 604800 # 7天,单位秒
```
### 4.2 JWT工具类配置
确保 `JwtUtil` 类能正确读取配置:
```java
@Component
public class JwtUtil {
@Value("${jeecg.jwt.secret}")
private String secret;
@Value("${jeecg.jwt.expire}")
private long expire;
}
```
## 5. 日志配置
### 5.1 日志级别配置
`application.yml` 中配置日志级别:
```yaml
logging:
level:
org.jeecg.modules.applet: DEBUG
org.jeecg.modules.common.wxUtils: DEBUG
```
## 6. 安全配置
### 6.1 CORS配置
如果需要跨域访问,需要配置CORS:
```java
@Configuration
public class CorsConfig {
@Bean
public CorsFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}
```
## 7. 依赖配置
### 7.1 Maven依赖
确保 `pom.xml` 中包含以下依赖:
```xml
<!-- Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- HTTP客户端 -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<!-- JSON处理 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<!-- MyBatis Plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
```
## 8. 环境变量配置
### 8.1 生产环境配置
在生产环境中,建议使用环境变量或配置中心来管理敏感信息:
```yaml
wechat:
mpAppId: ${WECHAT_MP_APPID:default_appid}
mpAppSecret: ${WECHAT_MP_SECRET:default_secret}
spring:
redis:
host: ${REDIS_HOST:localhost}
port: ${REDIS_PORT:6379}
password: ${REDIS_PASSWORD:}
```
## 9. 监控配置
### 9.1 健康检查
可以添加健康检查端点:
```yaml
management:
endpoints:
web:
exposure:
include: health,info,metrics
endpoint:
health:
show-details: always
```
## 10. 注意事项
1. **安全性**:生产环境中不要将敏感信息硬编码在代码中
2. **性能**:Redis连接池配置要根据实际负载调整
3. **监控**:建议添加应用监控和日志收集
4. **备份**:定期备份数据库和Redis数据
5. **测试**:在部署前进行充分的测试
## 11. 常见问题
### 11.1 Redis连接失败
- 检查Redis服务是否启动
- 检查网络连接和防火墙设置
- 检查Redis配置是否正确
### 11.2 微信API调用失败
- 检查微信小程序配置是否正确
- 检查网络连接是否正常
- 检查微信API调用频率限制
### 11.3 数据库连接失败
- 检查数据库服务是否启动
- 检查数据库连接配置
- 检查数据库用户权限
## 12. 部署检查清单
- [ ] 数据库表已创建
- [ ] Redis服务已启动
- [ ] 微信小程序配置正确
- [ ] JWT密钥已配置
- [ ] 日志配置正确
- [ ] 网络连接正常
- [ ] 安全配置已设置
- [ ] 监控已配置
- [ ] 备份策略已制定

Loading…
Cancel
Save