![824e29c34952acf594a58cadbdc4ac52.png](https://i-blog.csdnimg.cn/blog_migrate/4a9cc79dcd4a9421fe8d99cb498a5ed8.jpeg)
广告模块
广告模块功能分析
后台管理系统的广告管理模块包含了广告位列表查询、添加&修改广告位、回显广告位名称、广告分页查询、图片上传接口、新建&修改广告、回显广告信息、广告状态上下线等接口的编写
课程管理
实现以下功能
- 广告位列表查询
- 添加 & 修改广告位
- 回显广告位名称
- 广告分页查询
- 图片上传接口
- 新建 & 修改广告接口
- 回显广告信息
- 广告状态上下线
广告模块表设计
数据库表
- promotion_ad 广告表
- promotion_space 广告位表
表关系介绍
ER 图
一个广告位表对多个广告表
数据实体描述
广告位表
CREATE TABLE `promotion_space` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `name` VARCHAR(255) DEFAULT NULL COMMENT '名称', `spaceKey` VARCHAR(255) DEFAULT NULL COMMENT '广告位key', `createTime` DATETIME DEFAULT NULL, `updateTime` DATETIME DEFAULT NULL, `isDel` INT(2) DEFAULT '0', PRIMARY KEY (`id`) USING BTREE, KEY `promotion_space_key_isDel` (`spaceKey`,`isDel`) USING BTREE) ENGINE=INNODB AUTO_INCREMENT=174 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
广告表
CREATE TABLE `promotion_ad` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `name` VARCHAR(255) DEFAULT NULL COMMENT '广告名', `spaceId` INT(11) DEFAULT NULL COMMENT '广告位id', `keyword` VARCHAR(255) DEFAULT NULL COMMENT '精确搜索关键词', `htmlContent` TEXT COMMENT '静态广告的内容', `text` VARCHAR(255) DEFAULT NULL COMMENT '文字一', `link` VARCHAR(255) DEFAULT NULL COMMENT '链接一', `startTime` DATETIME DEFAULT NULL COMMENT '开始时间', `endTime` DATETIME DEFAULT NULL COMMENT '结束时间', `createTime` DATETIME DEFAULT NULL, `updateTime` DATETIME DEFAULT NULL, `status` INT(2) NOT NULL DEFAULT '0' COMMENT '0 下线,1 上线', `priority` INT(4) DEFAULT '0' COMMENT '优先级', `img` VARCHAR(255) DEFAULT NULL COMMENT '广告图片地址', PRIMARY KEY (`id`) USING BTREE, KEY `promotion_ad_SEG` (`spaceId`,`startTime`,`endTime`,`status`) USING BTREE) ENGINE=INNODB AUTO_INCREMENT=1094 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
广告管理模块接口实现
广告位列表查询
需求分析
点击广告列表按钮进行广告列表展示
查看接口文档,进行编码
实体类 PromotionSpace
public class PromotionSpace { private Integer id; private String name; private String spaceKey; private Date createTime; private Date updateTime; private Integer isDel; // getter setter toString ... }
Dao 层 PromotionSpaceMapper
public interface PromotionSpaceMapper { List findAllPromotionSpace();}
<?xml version="1.0" encoding="UTF-8" ?> select * from promotion_space
Service 层 PromotionSpaceService
public interface PromotionSpaceService { List findAllPromotionSpace();}
@Servicepublic class PromotionSpaceServiceImpl implements PromotionSpaceService { @Autowired private PromotionSpaceMapper promotionSpaceMapper; @Override public List findAllPromotionSpace() { return promotionSpaceMapper.findAllPromotionSpace(); }}
Web 层 PromotionSpaceController
@RestController@RequestMapping("/PromotionSpace")public class PromotionSpaceController { @Autowired private PromotionSpaceService promotionSpaceService; @RequestMapping("/findAllPromotionSpace") public ResponseResult findAllPromotionSpace() { List allPromotionSpace = promotionSpaceService.findAllPromotionSpace(); return new ResponseResult(true, 200, "查询所有广告位成功", allPromotionSpace); }}
Postman 测试接口
添加 & 修改广告位
需求分析
添加:点击提交按钮,将数据提交到数据库
修改:页面回显基础上,点击提交按钮真正进行数据修改
查看接口文档,进行编码
Dao 层 PromotionSpaceMapper
/** * 添加广告位 */void savePromotionSpace(PromotionSpace promotionSpace);/** * 更新广告位名称 */void updatePromotionSpace(PromotionSpace promotionSpace);
insert into promotion_space values (null, #{name}, #{spaceKey}, #{createTime}, #{updateTime}, #{isDel}) update promotion_space set `name`=#{name}, updateTime=#{updateTime} where id=#{id}
Service 层 PromotionSpaceService
void savePromotionSpace(PromotionSpace promotionSpace);void updatePromotionSpace(PromotionSpace promotionSpace);
@Overridepublic void savePromotionSpace(PromotionSpace promotionSpace) { // 封装数据 promotionSpace.setSpaceKey(UUID.randomUUID().toString()); Date date = new Date(); promotionSpace.setCreateTime(date); promotionSpace.setUpdateTime(date); promotionSpace.setIsDel(0); // 调用 mapper 方法 promotionSpaceMapper.savePromotionSpace(promotionSpace);}@Overridepublic void updatePromotionSpace(PromotionSpace promotionSpace) { // 封装数据 promotionSpace.setUpdateTime(new Date()); // 调用 mapper promotionSpaceMapper.updatePromotionSpace(promotionSpace);}
Web 层 PromotionSpaceController
@RequestMapping("/saveOrUpdatePromotionSpace")public ResponseResult saveOrUpdatePromotionSpace(@RequestBody PromotionSpace promotionSpace){ if(promotionSpace.getId() == null){ // 新增 promotionSpaceService.savePromotionSpace(promotionSpace); return new ResponseResult(true, 200, "新增广告位成功", null); }else { // 修改 promotionSpaceService.updatePromotionSpace(promotionSpace); return new ResponseResult(true, 200, "更新广告位名称成功", null); }}
Postman 测试接口
回显广告位名称
需求分析
点击编辑按钮,进行广告位信息回显
查看接口文档,进行编码
Dao 层 PromotionSpaceMapper
PromotionSpace findPromotionSpaceById(int id);
select id, `name` from promotion_space where id = #{id}
Service 层 PromotionSpaceService
PromotionSpace findPromotionSpaceById(int id);
@Overridepublic PromotionSpace findPromotionSpaceById(int id) { return promotionSpaceMapper.findPromotionSpaceById(id);}
Web 层 PromotionSpaceController
@RequestMapping("/findPromotionSpaceById")public ResponseResult findPromotionSpaceById(int id) { PromotionSpace promotionSpace = promotionSpaceService.findPromotionSpaceById(id); return new ResponseResult(true, 200, "", promotionSpace);}
Postman 测试接口
广告分页查询
需求分析
点击广告列表,对广告信息进行分页列表展示
查看接口文档,进行编码
实体类 PromotionAd
public class PromotionAd { // 标识 private Integer id; // 广告名 private String name; // 广告位 id private Integer spaceId; // 精确搜索关键词 private String keyword; // 静态广告的内容 private String htmlContent; // 文字一 private String text; // 链接一 private String link; // 开始时间 private Date startTime; // 结束时间 private Date endTime; private Date createTime; private Date updateTime; private Integer status; // 优先级 private Integer priority; private String img; // 声明一方关系(广告位) private PromotionSpace promotionSpace; // getter setter toString ... }
PromotionAdVo
View Object 表现层对象,主要用于表现层来接收参数的
public class PromotionAdVO { // 当前页 private Integer currentPage; // 每页显示的条数 private Integer pageSize; // getter setter toString ... }
Dao 层 PromotionAdMapper
public interface PromotionAdMapper { List findAllPromotionAdByPage();}
<?xml version="1.0" encoding="UTF-8" ?> select * from promotion_ad
applicationContext-dao.xml
... helperDialect=mysql ...
Service 层 PromotionAdService
public interface PromotionAdService { PageInfo findAllPromotionAdByPage(PromotionAdVO promotionAdVO);}
@Servicepublic class PromotionAdServiceImpl implements PromotionAdService { @Autowired private PromotionAdMapper promotionAdMapper; @Override public PageInfo findAllPromotionAdByPage(PromotionAdVO promotionAdVO) { // 使用 github 的分页工具 pageHelper PageHelper.startPage(promotionAdVO.getCurrentPage(), promotionAdVO.getPageSize()); List promotionAdList = promotionAdMapper.findAllPromotionAdByPage(); return new PageInfo<>(promotionAdList); }}
Web 层 PromotionAdController
@RestController@RequestMapping("/PromotionAd")public class PromotionAdController { @Autowired private PromotionAdService promotionAdService; @RequestMapping("/findAllPromotionAdByPage") public ResponseResult findAllPromotionAdByPage(PromotionAdVO promotionAdVO) { PageInfo pageInfo = promotionAdService.findAllPromotionAdByPage(promotionAdVO); return new ResponseResult(true, 200, "", pageInfo); }}
Postman测试接口
图片上传接口
需求分析
添加广告页面,点击上传按钮,需完成图片上传
查看接口文档,进行编码
Web 层 PromotionAdController
@RequestMapping("/PromotionAdUpload")public ResponseResult fileUpload(@RequestParam("file") MultipartFile file, HttpServletRequest request) throws IOException{ // 1.判断接收到的上传文件是否为空 if (file.isEmpty()) { throw new RuntimeException(); } // 2.获取项目部署路径 // D:apache-tomcat-8.5.55webappsssm-web String realPath = request.getServletContext().getRealPath("/"); // D:apache-tomcat-8.5.56webapps String substring = realPath.substring(0, realPath.indexOf("ssm_web")); // 3.生成新文件名 String originalFilename = file.getOriginalFilename(); String newFileName = "test"; if (originalFilename != null) { newFileName = System.currentTimeMillis() + originalFilename.substring(originalFilename.lastIndexOf(".")); } // 4.文件上传 String uploadPath = substring + "upload"; File filePath = new File(uploadPath, newFileName); // 如果目录不存在就创建目录 if (!filePath.getParentFile().exists()) { if (filePath.getParentFile().mkdirs()) { System.out.println("目录已经被创建:" + filePath); } else { System.out.println("创建目录失败"); } } // 图片进行上传 file.transferTo(filePath); // 5. 将文件名和文件路径返回,进行响应 HashMap map = new HashMap<>(); map.put("fileName", newFileName); map.put("filePath", "http://localhost:8080/upload/" + newFileName); // 返回响应参数 return new ResponseResult(true, 200, "图片上传成功", map);}
Postman 测试接口
新建 & 修改广告
需求分析
新建:点击提交按钮,将页面内容保存到数据库
修改:点击编辑按钮,由前端实现数据回显,在回显页面进行数据修改,将修改后值更新到数据库中
查看接口文档,进行编码
Dao 层 PromotionAdMapper
void savePromotionAd(PromotionAd promotionAd);void updatePromotionAd(PromotionAd promotionAd);
INSERT INTO promotion_ad (`name`,`spaceId`,`startTime`,`endTime`,`status`,`img`,`link`,`text`,`createTime`,`updateTime`) VALUES (#{name}, #{spaceId}, #{startTime}, #{endTime}, #{status}, #{img}, #{link}, #{text}, #{createTime}, #{updateTime}); UPDATE promotion_ad `name`=#{name}, `spaceId`=#{spaceId}, `link`=#{link}, `status`=#{status}, `img`=#{img}, `text`=#{text}, `startTime`=#{startTime}, `endTime`=#{endTime}, `updateTime`=#{updateTime}, `id`=#{id}
Service 层 PromotionAdService
void savePromotionAd(PromotionAd promotionAd);void updatePromotionAd(PromotionAd promotionAd);
@Overridepublic void savePromotionAd(PromotionAd promotionAd) { // 封装数据 Date date = new Date(); promotionAd.setCreateTime(date); promotionAd.setUpdateTime(date); // 调用 mapper 方法 promotionAdMapper.savePromotionAd(promotionAd);}@Overridepublic void updatePromotionAd(PromotionAd promotionAd) { // 封装数据 promotionAd.setUpdateTime(new Date()); // 调用 mapper 方法 promotionAdMapper.updatePromotionAd(promotionAd);}
Web 层 PromotionAdController
@RequestMapping("/saveOrUpdatePromotionAd")public ResponseResult saveOrUpdatePromotionAd(@RequestBody PromotionAd promotionAd) { if (promotionAd.getId() == null) { // 新增 promotionAdService.savePromotionAd(promotionAd); return new ResponseResult(true, 200, "新建广告成功", null); } else { // 修改 promotionAdService.updatePromotionAd(promotionAd); return new ResponseResult(true, 200, "修改广告成功", null); }}
Postman测试接口
回显广告信息
需求分析
点击编辑按钮,进行广告位名称回显
查看接口文档,进行编码
Dao 层 PromotionAdMapper
PromotionAd findPromotionAdById(int id);
SELECT `id`, `name`, `spaceId`, `startTime`, `endTime`, `status`, `img`, `link`, `text` FROM promotion_ad WHERE id = #{id};
Service 层 PromotionAdService
PromotionAd findPromotionAdById(int id);
@Overridepublic PromotionAd findPromotionAdById(int id) { return promotionAdMapper.findPromotionAdById(id);}
Web 层 PromotionAdController
@RequestMapping("/findPromotionAdById")public ResponseResult findPromotionAdById(int id) { PromotionAd promotionAd = promotionAdService.findPromotionAdById(id); return new ResponseResult(true, 200, "根据ID查询广告信息成功", promotionAd);}
Postman测试接口
广告状态上下线
需求分析
点击按钮,实现状态的动态上下线
查看接口文档,进行编码
Dao 层 PromotionAdMapper
void updatePromotionAdStatus(PromotionAd promotionAd);
UPDATE promotion_ad SET `status` = #{status}, `updateTime` = #{updateTime} WHERE `id` = #{id}
Service 层 PromotionAdService
void updatePromotionAdStatus(int id, int status);
@Overridepublic void updatePromotionAdStatus(int id, int status) { // 封装数据 PromotionAd promotionAd = new PromotionAd(); promotionAd.setId(id); promotionAd.setStatus(status); promotionAd.setUpdateTime(new Date()); // 调用 mapper promotionAdMapper.updatePromotionAdStatus(promotionAd);}
Web 层 PromotionAdController
@RequestMapping("/updatePromotionAdStatus")public ResponseResult updatePromotionAdStatus(Integer id, Integer status) { promotionAdService.updatePromotionAdStatus(id, status); return new ResponseResult(true, 200, "广告动态上下线成功", null);}
Postman测试接口
用户模块
用户模块功能分析
后台管理系统的用户模块包含了用户分页&条件查询、用户状态设置(登陆、权限控制)等接口的编写
用户模块
实现以下功能
- 登陆(权限模块)
- 权限控制(权限模块)
- 用户分页 & 条件查询
- 用户状态设置
- 分配角色(权限模块)
用户模块表设计
数据库表
- user 用户表
- user_weixin 用户绑定微信表
- user_phone_verification_code 用户发送验证码表
表关系介绍
ER 图
一个用户表对一个用户绑定微信表和用户发送验证码表
数据实体描述
用户表
CREATE TABLE `user` ( `id` INT(11) NOT NULL AUTO_INCREMENT COMMENT '用户id', `name` VARCHAR(255) NOT NULL COMMENT '用户昵称', `portrait` VARCHAR(255) DEFAULT NULL COMMENT '用户头像地址', `phone` VARCHAR(255) NOT NULL COMMENT '注册手机', `password` VARCHAR(255) DEFAULT NULL COMMENT '用户密码(可以为空,支持只用验证码注册、登录)', `reg_ip` VARCHAR(255) DEFAULT NULL COMMENT '注册ip', `account_non_expired` BIT(1) DEFAULT b'1' COMMENT '是否有效用户', `credentials_non_expired` BIT(1) DEFAULT b'1' COMMENT '账号是否未过期', `account_non_locked` BIT(1) DEFAULT b'1' COMMENT '是否未锁定', `status` VARCHAR(20) NOT NULL DEFAULT 'ENABLE' COMMENT '用户状态:ENABLE能登录,DISABLE不能登录', `is_del` BIT(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', `create_time` DATETIME NOT NULL COMMENT '注册时间', `update_time` DATETIME NOT NULL COMMENT '记录更新时间', PRIMARY KEY (`id`) USING BTREE, UNIQUE KEY `idx_phone_is_del` (`phone`,`is_del`) USING BTREE) ENGINE=INNODB AUTO_INCREMENT=100030023 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
用户绑定微信表
CREATE TABLE `user_weixin` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `user_id` INT(11) DEFAULT NULL COMMENT '用户id', `union_id` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '认证id,微信对应的时unionId', `open_id` VARCHAR(255) DEFAULT NULL COMMENT 'openId', `nick_name` VARCHAR(255) NOT NULL COMMENT '昵称', `portrait` VARCHAR(512) DEFAULT NULL COMMENT '头像', `city` VARCHAR(255) DEFAULT NULL COMMENT '城市', `sex` INT(11) DEFAULT NULL COMMENT '性别, 1-男,2-女', `create_time` DATETIME NOT NULL COMMENT '创建时间', `update_time` DATETIME NOT NULL COMMENT '更新时间', `is_del` BIT(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', PRIMARY KEY (`id`) USING BTREE, UNIQUE KEY `oauthId_and_oauthType_unique` (`union_id`,`open_id`,`is_del`) USING BTREE, UNIQUE KEY `userId_and_oauthType_unique_index` (`user_id`,`open_id`,`is_del`) USING BTREE) ENGINE=INNODB AUTO_INCREMENT=506562 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
用户发送验证码表
CREATE TABLE `user_phone_verification_code` ( `id` INT(10) NOT NULL AUTO_INCREMENT, `phone` VARCHAR(15) DEFAULT '' COMMENT '手机号', `verification_code` VARCHAR(15) DEFAULT '' COMMENT '验证码', `create_time` DATETIME DEFAULT NULL COMMENT '创建时间', `isCheck` BIT(1) DEFAULT b'0' COMMENT '验证码是否校验过', `check_times` INT(2) DEFAULT '0' COMMENT '校验次数', PRIMARY KEY (`id`) USING BTREE, KEY `l_phone_verification_code_ind_01` (`phone`,`create_time`) USING BTREE) ENGINE=INNODB AUTO_INCREMENT=33317 DEFAULT CHARSET=utf8;
用户管理模块接口实现
用户分页 & 条件查询
需求分析
实现多条件分页组合查询
查看接口文档,进行编码
实体类 User
public class User { // 用户 id private Integer id; // 用户昵称 private String name; // 用户头像地址 private String portrait; // 注册手机 private String phone; // 用户密码(可以为空,支持只用验证码注册、登录) private String password; // 注册 ip private String reg_ip; // 是否有效用户 private Integer account_non_expired; // 账号是否未过期 private Integer credentials_non_expired; // 是否未锁定 private Integer account_non_locked; // 用户状态 private String status; // 是否删除 private Integer is_del; // 创建时间 private Date create_time; // 更新时间 private Date update_time; // getter setter toString ... }
UserVo
View Object 表现层对象,主要用于表现层来接收参数的
public class UserVo { private Integer currentPage; private Integer pageSize; // 多条件查询:用户名(手机号) private String username; // 注册起始时间。使用了 DateTimeFormat,也可以使用自定义类型转换器 @DateTimeFormat(pattern = "yyyy-MM-dd") private Date startCreateTime; // 注册结束时间 @DateTimeFormat(pattern = "yyyy-MM-dd") private Date endCreateTime; // getter setter ... }
Dao 层 UserMapper
public interface UserMapper { List findAllUserByPage(UserVo userVo);}
<?xml version="1.0" encoding="UTF-8" ?> select * from `user` and is_del != 1 and `name` = #{username} and create_time between #{startCreateTime} and #{endCreateTime}
Service 层 UserService
public interface UserService { PageInfo findAllUserByPage(UserVo userVo);}
@Servicepublic class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public PageInfo findAllUserByPage(UserVo userVo) { PageHelper.startPage(userVo.getCurrentPage(), userVo.getPageSize()); List userList = userMapper.findAllUserByPage(userVo); return new PageInfo<>(userList); }}
Web 层 UserController
@RestController@RequestMapping("/user")public class UserController { @Autowired private UserService userService; @RequestMapping("/findAllUserByPage") public ResponseResult findAllUserByPage(@RequestBody UserVo userVo) { PageInfo pageInfo = userService.findAllUserByPage(userVo); return new ResponseResult(true, 200, "分页多条件查询成功", pageInfo); }}
Postman 测试接口
用户状态设置
需求分析
点击禁用,实现用户的状态变更
用户状态:ENABLE 能登录,DISABLE 不能登录
查看接口文档,进行编码
Dao 层 UserMapper
/** * 使用注解 @Param() 获取参数,这样映射文件就不需要使用 parameterType */void updateUserStatus(@Param("id") int id, @Param("status") String status, @Param("updateTime") Date updateTime);
update `user` set `status` = #{status}, `update_time` = #{updateTime} where id = #{id}
Service 层 UserService
void updateUserStatus(int id, String status);
@Overridepublic void updateUserStatus(int id, String status) { userMapper.updateUserStatus(id, status, new Date());}
Web 层 UserController
@RequestMapping("/updateUserStatus")public ResponseResult updateUserStatus(@RequestParam int id, @RequestParam String status) { if ("ENABLE".equalsIgnoreCase(status)) { status = "DISABLE"; } else { status = "ENABLE"; } userService.updateUserStatus(id, status); return new ResponseResult(true, 200, "修改用户状态成功", status);}
Postman 测试接口
想了解更多,欢迎关注我的微信公众号:Renda_Zhang