Repository: saysky/manland
Branch: master
Commit: f536d218d785
Files: 222
Total size: 2.2 MB
Directory structure:
gitextract_uyewi9iz/
├── .gitattributes
├── .gitignore
├── README.md
├── pom.xml
└── src/
└── main/
├── java/
│ └── com/
│ └── example/
│ └── sens/
│ ├── Application.java
│ ├── common/
│ │ ├── base/
│ │ │ ├── BaseEntity.java
│ │ │ └── BaseService.java
│ │ └── constant/
│ │ └── CommonConstant.java
│ ├── config/
│ │ ├── MvcConfig.java
│ │ ├── mybatisplus/
│ │ │ └── MybatisPlusConfig.java
│ │ ├── properties/
│ │ │ └── IgnoredUrlsProperties.java
│ │ ├── schedule/
│ │ │ └── SystemSchedule.java
│ │ └── shiro/
│ │ ├── MyRealm.java
│ │ ├── ShiroConfig.java
│ │ └── URLPathMatchingFilter.java
│ ├── controller/
│ │ ├── admin/
│ │ │ ├── AdminController.java
│ │ │ ├── AttachmentController.java
│ │ │ ├── CategoryController.java
│ │ │ ├── NoticeController.java
│ │ │ ├── OrderController.java
│ │ │ ├── PermissionController.java
│ │ │ ├── PostController.java
│ │ │ ├── ProfileController.java
│ │ │ ├── RechargeRecordController.java
│ │ │ ├── RoleController.java
│ │ │ └── UserController.java
│ │ ├── common/
│ │ │ ├── BaseController.java
│ │ │ └── CommonController.java
│ │ └── home/
│ │ ├── FrontPostController.java
│ │ ├── IndexController.java
│ │ └── LoginController.java
│ ├── dto/
│ │ ├── JsonResult.java
│ │ ├── PostQueryCondition.java
│ │ └── QueryCondition.java
│ ├── entity/
│ │ ├── Category.java
│ │ ├── City.java
│ │ ├── Notice.java
│ │ ├── Order.java
│ │ ├── Permission.java
│ │ ├── Post.java
│ │ ├── RechargeRecord.java
│ │ ├── Role.java
│ │ ├── RolePermissionRef.java
│ │ ├── User.java
│ │ └── UserRoleRef.java
│ ├── enums/
│ │ ├── CommonParamsEnum.java
│ │ ├── OrderStatusEnum.java
│ │ ├── PostIsRecommendEnum.java
│ │ ├── PostIsStickyEnum.java
│ │ ├── PostStatusEnum.java
│ │ ├── PostTypeEnum.java
│ │ ├── ResourceTypeEnum.java
│ │ ├── ResultCodeEnum.java
│ │ ├── RoleEnum.java
│ │ ├── TrueFalseEnum.java
│ │ └── UserStatusEnum.java
│ ├── exception/
│ │ ├── GlobalExceptionHandler.java
│ │ └── MyBusinessException.java
│ ├── mapper/
│ │ ├── CategoryMapper.java
│ │ ├── CityMapper.java
│ │ ├── NoticeMapper.java
│ │ ├── OrderMapper.java
│ │ ├── PermissionMapper.java
│ │ ├── PostMapper.java
│ │ ├── RechargeRecordMapper.java
│ │ ├── RoleMapper.java
│ │ ├── RolePermissionRefMapper.java
│ │ ├── UserMapper.java
│ │ └── UserRoleRefMapper.java
│ ├── service/
│ │ ├── CategoryService.java
│ │ ├── CityService.java
│ │ ├── MailService.java
│ │ ├── NoticeService.java
│ │ ├── OrderService.java
│ │ ├── PermissionService.java
│ │ ├── PostService.java
│ │ ├── RechargeRecordService.java
│ │ ├── RolePermissionRefService.java
│ │ ├── RoleService.java
│ │ ├── UserRoleRefService.java
│ │ ├── UserService.java
│ │ └── impl/
│ │ ├── CategoryServiceImpl.java
│ │ ├── CityServiceImpl.java
│ │ ├── MailServiceImpl.java
│ │ ├── NoticeServiceImpl.java
│ │ ├── OrderServiceImpl.java
│ │ ├── PermissionServiceImpl.java
│ │ ├── PostServiceImpl.java
│ │ ├── RechargeRecordServiceImpl.java
│ │ ├── RolePermissionRefServiceImpl.java
│ │ ├── RoleServiceImpl.java
│ │ ├── UserRoleRefServiceImpl.java
│ │ └── UserServiceImpl.java
│ ├── util/
│ │ ├── DateUtil.java
│ │ ├── FileUtil.java
│ │ ├── IpInfoUtil.java
│ │ ├── Md5Util.java
│ │ ├── ObjectUtil.java
│ │ ├── PageUtil.java
│ │ ├── PermissionUtil.java
│ │ ├── RegexUtil.java
│ │ ├── RelativeDateFormat.java
│ │ ├── Response.java
│ │ ├── SensUtils.java
│ │ ├── SpringUtil.java
│ │ └── ThreadPoolUtil.java
│ └── vo/
│ ├── PageVo.java
│ └── SearchVo.java
└── resources/
├── application.yaml
├── mapper/
│ ├── CategoryMapper.xml
│ ├── CityMapper.xml
│ ├── OrderMapper.xml
│ ├── PermissionMapper.xml
│ ├── PostMapper.xml
│ ├── RechargeRecordMapper.xml
│ ├── RoleMapper.xml
│ ├── RolePermissionRefMapper.xml
│ ├── UserMapper.xml
│ └── UserRoleRefMapper.xml
├── static/
│ ├── css/
│ │ ├── AdminLTE.css
│ │ ├── alt/
│ │ │ ├── AdminLTE-bootstrap-social.css
│ │ │ ├── AdminLTE-select2.css
│ │ │ └── AdminLTE-without-plugins.css
│ │ ├── loader.css
│ │ ├── pay.css
│ │ ├── skins/
│ │ │ └── _all-skins.css
│ │ └── style.css
│ ├── front/
│ │ ├── css/
│ │ │ ├── pay.css
│ │ │ └── style.css
│ │ ├── js/
│ │ │ ├── contact_me.js
│ │ │ ├── custom.js
│ │ │ └── jqBootstrapValidation.js
│ │ └── vendor/
│ │ └── select2/
│ │ └── css/
│ │ └── select2-bootstrap.css
│ ├── js/
│ │ ├── adminlte.js
│ │ └── app.js
│ └── plugins/
│ ├── bootstrap/
│ │ ├── css/
│ │ │ ├── bootstrap-theme.css
│ │ │ └── bootstrap.css
│ │ └── js/
│ │ ├── bootstrap.js
│ │ └── npm.js
│ ├── bootstrapStyle/
│ │ └── bootstrapStyle.css
│ ├── bootstrapvalidator/
│ │ ├── css/
│ │ │ └── bootstrapValidator.css
│ │ └── js/
│ │ ├── bootstrapValidator.js
│ │ └── language/
│ │ └── zh_CN.js
│ ├── font-awesome/
│ │ ├── css/
│ │ │ └── font-awesome.css
│ │ └── fonts/
│ │ └── FontAwesome.otf
│ ├── froala-editor/
│ │ ├── css/
│ │ │ ├── froala_editor.css
│ │ │ ├── froala_editor.pkgd.css
│ │ │ ├── froala_style.css
│ │ │ ├── plugins/
│ │ │ │ ├── char_counter.css
│ │ │ │ ├── code_view.css
│ │ │ │ ├── colors.css
│ │ │ │ ├── draggable.css
│ │ │ │ ├── emoticons.css
│ │ │ │ ├── file.css
│ │ │ │ ├── fullscreen.css
│ │ │ │ ├── help.css
│ │ │ │ ├── image.css
│ │ │ │ ├── image_manager.css
│ │ │ │ ├── line_breaker.css
│ │ │ │ ├── quick_insert.css
│ │ │ │ ├── special_characters.css
│ │ │ │ ├── table.css
│ │ │ │ └── video.css
│ │ │ ├── themes/
│ │ │ │ ├── dark.css
│ │ │ │ ├── gray.css
│ │ │ │ ├── red.css
│ │ │ │ └── royal.css
│ │ │ └── third_party/
│ │ │ ├── embedly.css
│ │ │ ├── font_awesome.css
│ │ │ ├── image_tui.css
│ │ │ └── spell_checker.css
│ │ └── js/
│ │ └── languages/
│ │ ├── ar.js
│ │ ├── bs.js
│ │ ├── cs.js
│ │ ├── da.js
│ │ ├── de.js
│ │ ├── el.js
│ │ ├── en_ca.js
│ │ ├── en_gb.js
│ │ ├── es.js
│ │ ├── et.js
│ │ ├── fa.js
│ │ ├── fi.js
│ │ ├── fr.js
│ │ ├── he.js
│ │ ├── hr.js
│ │ ├── hu.js
│ │ ├── id.js
│ │ ├── it.js
│ │ ├── ja.js
│ │ ├── ko.js
│ │ ├── ku.js
│ │ ├── me.js
│ │ ├── nb.js
│ │ ├── nl.js
│ │ ├── pl.js
│ │ ├── pt_br.js
│ │ ├── pt_pt.js
│ │ ├── ro.js
│ │ ├── ru.js
│ │ ├── sk.js
│ │ ├── sr.js
│ │ ├── sv.js
│ │ ├── th.js
│ │ ├── tr.js
│ │ ├── uk.js
│ │ ├── vi.js
│ │ ├── zh_cn.js
│ │ └── zh_tw.js
│ ├── highlight/
│ │ ├── highlight.css
│ │ └── highlight.js
│ ├── layer/
│ │ ├── layer.js
│ │ ├── mobile/
│ │ │ ├── layer.js
│ │ │ └── need/
│ │ │ └── layer.css
│ │ └── theme/
│ │ └── default/
│ │ └── layer.css
│ ├── lazyload/
│ │ └── jquery.lazyload.js
│ ├── loaders/
│ │ └── loaders.css
│ ├── pace/
│ │ ├── pace.css
│ │ └── pace.js
│ ├── pjax/
│ │ └── jquery.pjax.js
│ └── pretty-checkbox/
│ └── pretty-checkbox.css
└── 需要前端代码联系博主.txt
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitattributes
================================================
*.js linguist-language=Java
*.css linguist-language=Java
*.html linguist-language=Java
================================================
FILE: .gitignore
================================================
target/
logs/
out/
!.mvn/wrapper/maven-wrapper.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
log/
### NetBeans ###
nbproject/private/
build/
nbbuild/
dist/
nbdist/
.nb-gradle/
### Mac
.DS_Store
*/.DS_Store
### VS Code ###
*.project
*.factorypath
### 屏蔽,需要完整代码联系博主:微信847064370
*.html
templates/
webapp/
*.sql
================================================
FILE: README.md
================================================
最新消息,博主已开通B站账号:[Java刘哥](https://space.bilibili.com/160340478)
# 租房系统
基于SpringBoot实现的租房系统,包括三种角色:管理员、房东、租客。
- 详细介绍:[https://liuyanzhao.com/shop/manland.html](https://liuyanzhao.com/shop/manland.html)
- 预览地址:[http://manland.liuyanzhao.com](http://manland.liuyanzhao.com)
## 博主开发的其他租房或房屋交易项目全部在这里
[https://liuyanzhao.com/shop.html?k=房屋](https://liuyanzhao.com/shop.html?k=房屋)
- [基于SpringBoot+Vue房屋租赁系统 租房 Verio的Vue版本](https://liuyanzhao.com/shop/verio-vue.html)
- [基于SpringBoot的房屋租赁平台 房屋展示平台 留学生房屋租赁平台](https://liuyanzhao.com/shop/housekey.html)
- [基于SpringBoot/SSM的最新最轻量级最漂亮的的二手房屋交易系统RentUP](https://liuyanzhao.com/shop/rentup.html)
- [基于SpringBoot/SSM的房屋租赁系统租房系统Rello](https://liuyanzhao.com/shop/rello.html)
- [基于SpringBoot/SSM房屋租赁系统 verio3.0/协同过滤,房屋合租系统 租房系统](https://liuyanzhao.com/shop/verio.html)
- [基于SpringBoot房屋租赁系统manland4.0](https://liuyanzhao.com/shop/manland.html)
# 功能介绍
#### 管理员功能:
- 房屋管理
- 租房类型管理(合租/整租)
- 房屋管理
- 订单管理
- 新闻公告管理
- 收支明细
- 用户管理
- 角色管理、权限管理
#### 房东功能
- 房屋管理
- 订单管理:取消订单、审核退租、查看合同、下载打印合同
- 收支明细
- 个人信息修改、账号密码修改
## 租客功能
订单管理:创建订单、确认合同、支付订单、取消订单、退租、电子合同查看、下载打印合同
收支明细
个人信息修改、账号密码修改
## 技术组成
- SpringBoot
- MyBatis
- Shiro
- Thymeleaf
- Bootstrap + jQuery
- MySQL
- Maven
## 预览
1-首页1.png

2-首页2.png

3-房屋列表1.png

4-房屋列表2.png

5-房屋详情1.png

6-房屋详情2.png

7-新闻公告列表.png

8-新闻公告详情.png

10-注册页面.png

10-登录页面.png

11-点击预定.png

12-签订合同页面.png

13-支付订单页面.png

14-租客订单列表.png

15-租客的房屋信息.png

16-充值管理.png

17-个人信息.png

18-出租者的房屋信息列表.png

19-出租者的订单管理.png

20-管理员房屋管理.png

21-出租分类.png

22-财务统计.png

23-公告管理.png

24-编辑发布新闻公告.png

25-用户管理.png

26-房屋信息发布.png

27-房屋信息编辑.png

其他页面,请直接通过演示网站访问
管理员账号admin/123456,房东mayun/123456,租客zhangsan/123456
## 联系方式
目前只开源后端代码,需要前端和sql等完整代码请联系博主
同时也提供部署或讲解服务
微信/QQ:847064370
[博主博客主页](https://liuyanzhao.com)
## 日志
- 2021/11/13 4.0版本
- 新增中介角色,功能跟房东类似,需要填写房东信息
- 注册登录增加验证码,不区分大小写
- 2021/3/17 3.0版本
- 大改
- 角色改成 管理员、房东和租客三种,将原来用户角色拆分成房东和租客
- 租房时间单位由月改成日,租房时可以选择租到具体哪一天
- 新增退租功能
- 取消充值,用户余额字段,新增收支明细
- 管理员可以对订单做任何操作操作
- 2020/12/14 2.0版本
- 根据部分同学要求,重构代码
— 修改导航菜单,加入图标
- 固定顶部导航
- 添加城市切换切换卡
- 添加合租室友信息
- 2020/12/06
- 根据部分同学要求,重构代码
- 把房东和租客两种角色合二为一,用户既可以租房也可以发布出租信息。
- 把租房分类改成了整租和合租。
- 新增余额充值和收支明细,以及付款后租客余额减少,出租人越增加,定时返回押金
- 修改了合同内容,新增合同下载和打印
- 新增新闻公告
- 新增联系我们页面
- 新增押金字段
- 新增支持租金和面积检索
- 2020/10/18 1.0 版本
- 完成初步开发
- 管理员功能:登录,房屋管理、房屋类型管理、订单管理、房东管理,租客管理、财务统计,个人信息等。还要角色管理和权限管理,这里隐藏了。
- 房东功能:注册,登录,房屋管理(房屋添加修改删除上架等)、订单管理、查看电子合同。
- 租客功能:注册,登录,房屋检索,房屋租赁,查看订单,查看电子合同。
================================================
FILE: pom.xml
================================================
4.0.0
com.example
Manland
4.0.0
Manland
基于SpringBoot的房租租赁系统
saysky
言曌
admin@example.com
https://example.com
org.springframework.boot
spring-boot-starter-parent
2.1.7.RELEASE
UTF-8
UTF-8
1.8
1.1.10
1.18.2
3.8
4.1.13
saysky
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-tomcat
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-starter-aop
org.springframework.boot
spring-boot-starter-undertow
com.baomidou
mybatis-plus-boot-starter
3.1.2
org.springframework.boot
spring-boot-starter-jdbc
mysql
mysql-connector-java
runtime
com.alibaba
druid-spring-boot-starter
${druid.version}
org.springframework.boot
spring-boot-starter-thymeleaf
org.projectlombok
lombok
${lombok.version}
provided
org.apache.commons
commons-lang3
${commons-lang3.version}
cn.hutool
hutool-all
${hutool-all.version}
org.springframework.boot
spring-boot-devtools
true
com.alibaba
fastjson
1.2.72
com.google.guava
guava
26.0-jre
org.apache.shiro
shiro-spring
1.4.0
com.github.theborakompanioni
thymeleaf-extras-shiro
2.0.0
com.google.code.gson
gson
2.8.5
io.github.biezhi
oh-my-email
0.0.3
junit
junit
4.12
com.github.penggle
kaptcha
2.3.2
aliyun
http://maven.aliyun.com/nexus/content/groups/public
aliyun
http://maven.aliyun.com/nexus/content/groups/public
manland
org.springframework.boot
spring-boot-maven-plugin
true
================================================
FILE: src/main/java/com/example/sens/Application.java
================================================
package com.example.sens;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
*
* SENS run!
*
*
* @author : saysky
* @date : 2019/11/14
*/
@Slf4j
@SpringBootApplication
@EnableCaching
@EnableScheduling
@MapperScan("com.example.sens.mapper*")
public class Application {
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(Application.class, args);
String serverPort = context.getEnvironment().getProperty("server.port");
log.info("SENS started at http://localhost:" + serverPort);
}
}
================================================
FILE: src/main/java/com/example/sens/common/base/BaseEntity.java
================================================
package com.example.sens.common.base;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.example.sens.common.constant.CommonConstant;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* @author 言曌
* @date 2019-08-07 00:28
*/
@Data
public class BaseEntity implements Serializable {
/**
* ID,自动生成
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 删除状态:1删除,0未删除
*/
@TableField(value = "del_flag")
@TableLogic
private Integer delFlag = CommonConstant.STATUS_NORMAL;
/**
* 创建人账号
*/
private String createBy;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新人
*/
private String updateBy;
/**
* 更新时间
*/
private Date updateTime;
}
================================================
FILE: src/main/java/com/example/sens/common/base/BaseService.java
================================================
package com.example.sens.common.base;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.sens.vo.SearchVo;
import com.example.sens.dto.QueryCondition;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.util.Date;
import java.util.List;
/**
* @author 言曌
* @date 2019-09-04 22:47
*/
// JDK8函数式接口注解 仅能包含一个抽象方法
public interface BaseService {
/**
* @return
*/
BaseMapper getRepository();
/**
* 根据ID获取
*
* @param id
* @return
*/
default E get(ID id) {
return getRepository().selectById(id);
}
/**
* 获取所有列表
*
* @return
*/
default List getAll() {
return getRepository().selectList(null);
}
/**
* 获取总数
*
* @return
*/
default Integer getTotalCount() {
return getRepository().selectCount(null);
}
/**
* 添加
*
* @param entity
* @return
*/
default E insert(E entity) {
getRepository().insert(entity);
return entity;
}
/**
* 修改
*
* @param entity
* @return
*/
default E update(E entity) {
getRepository().updateById(entity);
return entity;
}
/**
* 保存或者更新
* @param entity
* @return
*/
default E insertOrUpdate(E entity) {
try {
Object id = entity.getClass().getMethod("getId").invoke(entity);
if (id != null) {
update(entity);
} else {
insert(entity);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
return entity;
}
/**
* 批量保存与修改
*
* @param list
* @return
*/
default List batchInsert(List list) {
for (E e : list) {
getRepository().insert(e);
}
return list;
}
/**
* 根据Id删除
*
* @param id
*/
default void delete(ID id) {
getRepository().deleteById(id);
}
/**
* 批量删除
*
* @param ids
*/
default void batchDelete(List ids) {
getRepository().deleteBatchIds(ids);
}
/**
* 根据id批量查询
* @param ids
* @return
*/
default List findByBatchIds(List ids) {
return getRepository().selectBatchIds(ids);
}
/**
* 获取所有
*
* @return
*/
default List findAll() {
return getRepository().selectList(null);
}
/**
* 根据条件查询获取
*
* @param queryWrapper
* @return
*/
default List findAll(QueryWrapper queryWrapper) {
return getRepository().selectList(queryWrapper);
}
/**
* 根据查询条件不分页获取
*
* @param condition
* @return
*/
default List findAll(QueryCondition condition) {
E e = condition.getData();
//对指定字段查询
QueryWrapper queryWrapper = getQueryWrapper(e);
return getRepository().selectList(queryWrapper);
}
/**
* 分页获取
*
* @param page
* @return
*/
default Page findAll(Page page) {
return (Page) getRepository().selectPage(page, null);
}
/**
* 获得查询器
*
* @param e
* @return
*/
QueryWrapper getQueryWrapper(E e);
/**
* 根据查询条件分页获取
*
* @param page
* @param condition
* @return
*/
default Page findAll(Page page, QueryCondition condition) {
E e = condition.getData();
SearchVo searchVo = condition.getSearchVo();
//对指定字段查询
QueryWrapper queryWrapper = getQueryWrapper(e);
//查询日期范围
if (searchVo != null) {
String startDate = searchVo.getStartDate();
String endDate = searchVo.getEndDate();
if (StrUtil.isNotBlank(startDate) && StrUtil.isNotBlank(endDate)) {
Date start = DateUtil.parse(startDate);
Date end = DateUtil.parse(endDate);
queryWrapper.between("create_time", start, end);
}
}
return (Page) getRepository().selectPage(page, queryWrapper);
}
/**
* 获取查询条件的结果数
*
* @param queryWrapper
* @return
*/
default long count(QueryWrapper queryWrapper) {
return getRepository().selectCount(queryWrapper);
}
}
================================================
FILE: src/main/java/com/example/sens/common/constant/CommonConstant.java
================================================
package com.example.sens.common.constant;
/**
* 常量
* @author 言曌
*/
public interface CommonConstant {
/**
* 正常状态
*/
Integer STATUS_NORMAL = 0;
/**
* 用户密码加盐的盐
*/
String PASSWORD_SALT = "sens";
/**
* none
*/
String NONE = "none";
String CONDITION = "condition";
}
================================================
FILE: src/main/java/com/example/sens/config/MvcConfig.java
================================================
package com.example.sens.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import java.util.Locale;
/**
* 拦截器,资源路径配置
*/
@Slf4j
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.example.sens.controller")
@PropertySource(value = "classpath:application.yaml", ignoreResourceNotFound = true, encoding = "UTF-8")
public class MvcConfig implements WebMvcConfigurer {
/**
* 配置静态资源路径
*
* @param registry registry
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**")
.addResourceLocations("classpath:/static/");
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/templates/themes/")
.addResourceLocations("classpath:/robots.txt");
registry.addResourceHandler("/upload/**")
.addResourceLocations("file:///" + System.getProperties().getProperty("user.home") + "/sens/upload/");
registry.addResourceHandler("/favicon.png")
.addResourceLocations("classpath:/static/images/favicon.png");
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowCredentials(true)
.allowedHeaders("*")
.allowedOrigins("*")
.allowedMethods("*");
}
@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver slr = new SessionLocaleResolver();
slr.setDefaultLocale(Locale.CHINA);
return slr;
}
}
================================================
FILE: src/main/java/com/example/sens/config/mybatisplus/MybatisPlusConfig.java
================================================
package com.example.sens.config.mybatisplus;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author 言曌
* @date 2018/12/22 下午1:49
*/
@Configuration
public class MybatisPlusConfig {
/***
* plus 的性能优化
* @return
*/
@Bean
public PerformanceInterceptor performanceInterceptor() {
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
/**/
performanceInterceptor.setMaxTime(1000);
/**/
performanceInterceptor.setFormat(false);
return performanceInterceptor;
}
/**
* mybatis-plus分页插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
================================================
FILE: src/main/java/com/example/sens/config/properties/IgnoredUrlsProperties.java
================================================
package com.example.sens.config.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.List;
/**
* @author example
*/
@Data
@Configuration
@ConfigurationProperties(prefix = "ignored")
public class IgnoredUrlsProperties {
private List urls = new ArrayList<>();
}
================================================
FILE: src/main/java/com/example/sens/config/schedule/SystemSchedule.java
================================================
package com.example.sens.config.schedule;
import com.example.sens.entity.Order;
import com.example.sens.entity.Post;
import com.example.sens.entity.User;
import com.example.sens.enums.OrderStatusEnum;
import com.example.sens.enums.PostStatusEnum;
import com.example.sens.mapper.OrderMapper;
import com.example.sens.mapper.PostMapper;
import com.example.sens.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* 定时器
*
* @author 言曌
* @date 2020/3/21 7:18 下午
*/
@Component
public class SystemSchedule {
@Autowired
private PostMapper postMapper;
@Autowired
private OrderMapper orderMapper;
@Autowired
private UserMapper userMapper;
/**
* 更新到期的订单
*/
@Scheduled(fixedRate = 10000)
@Transactional(rollbackFor = Exception.class)
public void updatePostStatus() {
List orderList = orderMapper.findOverDueOrder();
for (Order order : orderList) {
// 更新房屋状态
Post post = postMapper.selectById(order.getPostId());
if (post == null) {
return;
}
// 退还押金
User user = userMapper.selectById(order.getUserId());
if (user == null) {
return;
}
User ownerUser = userMapper.selectById(post.getId());
if (ownerUser == null) {
return;
}
if (ownerUser.getMoney() < post.getDeposit()) {
// 业主余额不足,无法退回押金
// 结束订单
order.setStatus(OrderStatusEnum.DEPOSIT_RETURN_FAIL.getCode());
orderMapper.updateById(order);
return;
}
// 以下代码暂不考虑并发问题,暂不用乐观锁实现
// 业主余额减少
ownerUser.setMoney(ownerUser.getMoney() - post.getDeposit());
userMapper.updateById(ownerUser);
// 租客余额增加
user.setMoney(user.getMoney() + post.getDeposit());
userMapper.updateById(user);
// 结束订单
order.setStatus(OrderStatusEnum.FINISHED.getCode());
orderMapper.updateById(order);
post.setPostStatus(PostStatusEnum.ON_SALE.getCode());
postMapper.updateById(post);
}
}
}
================================================
FILE: src/main/java/com/example/sens/config/shiro/MyRealm.java
================================================
package com.example.sens.config.shiro;
import com.example.sens.common.constant.CommonConstant;
import com.example.sens.entity.Permission;
import com.example.sens.entity.Role;
import com.example.sens.service.PermissionService;
import com.example.sens.service.RoleService;
import com.example.sens.service.UserService;
import com.example.sens.entity.User;
import com.example.sens.enums.UserStatusEnum;
import com.example.sens.util.RegexUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
@Slf4j
public class MyRealm extends AuthorizingRealm {
@Autowired
@Lazy
private UserService userService;
@Autowired
@Lazy
private RoleService roleService;
@Autowired
@Lazy
private PermissionService permissionService;
/**
* 认证信息(身份验证) Authentication 是用来验证用户身份
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
log.info("认证-->MyShiroRealm.doGetAuthenticationInfo()");
//1.验证账号
User user;
String account = (String) token.getPrincipal();
if (RegexUtil.isIdCard(account)) {
user = userService.findByIdCard(account);
} else {
user = userService.findByUserName(account);
}
if (user == null) {
//用户不存在
log.info("用户不存在! 登录名:{}, 密码:{}", account, token.getCredentials());
return null;
}
Role role = roleService.findByUserId(user.getId());
if (role != null) {
user.setRole(role);
}
//2.判断账号是否被封号
if (!Objects.equals(user.getStatus(), UserStatusEnum.NORMAL.getCode())) {
throw new LockedAccountException("账号被封禁");
}
//3.封装authenticationInfo,准备验证密码
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
user, // 账号
user.getUserPass(), // 密码
ByteSource.Util.bytes(CommonConstant.PASSWORD_SALT), // 盐
getName() // realm name
);
System.out.println("realName:" + getName());
return authenticationInfo;
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
User user = (User) principals.getPrimaryPrincipal();
Role role = roleService.findByUserId(user.getId());
authorizationInfo.addRole(role.getRole());
List permissions = permissionService.listPermissionsByRoleId(role.getId());
//把权限的URL全部放到authorizationInfo中去
Set urls = permissions.stream().map(p -> p.getUrl()).collect(Collectors.toSet());
authorizationInfo.addStringPermissions(urls);
return authorizationInfo;
}
}
================================================
FILE: src/main/java/com/example/sens/config/shiro/ShiroConfig.java
================================================
package com.example.sens.config.shiro;
import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import com.example.sens.config.properties.IgnoredUrlsProperties;
import org.apache.shiro.authc.credential.AllowAllCredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@Configuration
public class ShiroConfig {
@Bean
public ShiroDialect shiroDialect() {
return new ShiroDialect();
}
@Bean
IgnoredUrlsProperties getIgnoredUrlsProperties() {
return new IgnoredUrlsProperties();
}
@Bean
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
//自定义拦截器
Map filtersMap = new LinkedHashMap();
//访问权限配置
filtersMap.put("requestURL", getURLPathMatchingFilter());
shiroFilterFactoryBean.setFilters(filtersMap);
//拦截器.
Map filterChainDefinitionMap = new LinkedHashMap();
// 配置不会被拦截的链接 顺序判断
List urls = getIgnoredUrlsProperties().getUrls();
for (String url : urls) {
filterChainDefinitionMap.put(url, "anon");
}
filterChainDefinitionMap.put("/admin", "authc");
filterChainDefinitionMap.put("/admin/**", "requestURL");
filterChainDefinitionMap.put("/**", "anon");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
// 如果不设置默认会自动寻找Web工程根目录下的"/login"页面
shiroFilterFactoryBean.setLoginUrl("/");
// 登录成功后要跳转的链接
shiroFilterFactoryBean.setSuccessUrl("/");
//未授权界面;
shiroFilterFactoryBean.setUnauthorizedUrl("/403");
return shiroFilterFactoryBean;
}
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myRealm());
return securityManager;
}
@Bean
public MyRealm myRealm() {
MyRealm normalRealm = new MyRealm();
normalRealm.setCredentialsMatcher(hashedCredentialsMatcher());
return normalRealm;
}
/**
* 访问 权限 拦截器
*
* @return
*/
public URLPathMatchingFilter getURLPathMatchingFilter() {
return new URLPathMatchingFilter();
}
/**
* MD5加盐加密十次
*
* @return
*/
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher() {
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
//散列算法:这里使用MD5算法;
hashedCredentialsMatcher.setHashAlgorithmName("md5");
//散列的次数,md5("")
hashedCredentialsMatcher.setHashIterations(10);
return hashedCredentialsMatcher;
}
@Bean
public AllowAllCredentialsMatcher allowAllCredentialsMatcher() {
return new AllowAllCredentialsMatcher();
}
================================================
FILE: src/main/java/com/example/sens/config/shiro/URLPathMatchingFilter.java
================================================
package com.example.sens.config.shiro;
import com.alibaba.fastjson.JSONObject;
import com.example.sens.service.PermissionService;
import com.example.sens.util.SpringUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.PathMatchingFilter;
import org.apache.shiro.web.util.WebUtils;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* URL拦截器
*/
public class URLPathMatchingFilter extends PathMatchingFilter {
PermissionService permissionService = null;
private PermissionService permissionService() {
if (permissionService == null) {
permissionService = (PermissionService) SpringUtil.getBean("permissionServiceImpl");
}
return permissionService;
}
@Override
protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
//请求的url
String requestURL = getPathWithinApplication(request);
System.out.println("请求的url :" + requestURL);
Subject subject = SecurityUtils.getSubject();
if (!subject.isAuthenticated()) {
// 如果没有登录, 进入登录流程
WebUtils.issueRedirect(request, response, "/login");
return false;
}
//从session里读取当前用户的权限URL列表
Set urls = (Set) subject.getSession().getAttribute("permissionUrls");
if (urls.contains(requestURL)) {
return true;
}
//没有权限
if (isAjax((HttpServletRequest) request)) {
response.setCharacterEncoding("utf-8");
response.setContentType("application/json; charset=utf-8");
PrintWriter writer = response.getWriter();
Map map = new HashMap<>();
map.put("code", 0);
map.put("msg", "没有权限访问");
writer.write(JSONObject.toJSONString(map));
} else {
WebUtils.issueRedirect(request, response, "/403");
}
return false;
}
public static boolean isAjax(HttpServletRequest httpRequest) {
return (httpRequest.getHeader("X-Requested-With") != null
&& "XMLHttpRequest"
.equals(httpRequest.getHeader("X-Requested-With").toString()));
}
================================================
FILE: src/main/java/com/example/sens/controller/admin/AdminController.java
================================================
package com.example.sens.controller.admin;
import com.example.sens.entity.Permission;
import com.example.sens.entity.Role;
import com.example.sens.entity.User;
import com.example.sens.service.PermissionService;
import com.example.sens.controller.common.BaseController;
import com.example.sens.dto.JsonResult;
import com.example.sens.service.RoleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.util.*;
/**
*
* 后台首页控制器
*
*/
@Slf4j
@Controller
@RequestMapping(value = "/admin")
public class AdminController extends BaseController {
@Autowired
private PermissionService permissionService;
@Autowired
private RoleService roleService;
/**
* 请求后台页面
*
* @param model model
* @return 模板路径admin/admin_index
*/
@GetMapping
public String index(Model model) {
return "admin/admin_index";
}
/**
* 获得当前用户的菜单
*
* @return
*/
@GetMapping(value = "/currentMenus")
@ResponseBody
public JsonResult getMenu() {
Long userId = getLoginUserId();
List permissions = permissionService.findPermissionTreeByUserIdAndResourceType(userId, "menu");
return JsonResult.success("", permissions);
}
/**
* 获得当前登录用户
*/
@GetMapping(value = "/currentUser")
@ResponseBody
public JsonResult currentUser() {
User user = getLoginUser();
if (user != null) {
return JsonResult.success("", user);
}
return JsonResult.error("用户未登录");
}
/**
* 获得当前用户角色编码
*/
@GetMapping(value = "/currentRole")
@ResponseBody
public JsonResult currentRole() {
Role role = roleService.findByUserId(getLoginUserId());
if (role == null) {
return JsonResult.error("用户未登录或无角色");
}
return JsonResult.success("", role.getRole());
}
@GetMapping("/pay")
public String pay(@RequestParam("money") Integer money, Model model) {
model.addAttribute("money", money);
return "admin/alipay";
}
}
================================================
FILE: src/main/java/com/example/sens/controller/admin/AttachmentController.java
================================================
package com.example.sens.controller.admin;
import com.example.sens.controller.common.BaseController;
import com.example.sens.util.FileUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.HashMap;
import java.util.Map;
/**
*
* 后台附件控制器
*
*
* @author : saysky
* @date : 2019/12/19
*/
@Slf4j
@Controller
@RequestMapping(value = "/admin/file")
public class AttachmentController extends BaseController {
/**
* 上传文件
*
* @param file file
* @return Map
*/
@PostMapping(value = "/upload", produces = {"application/json;charset=UTF-8"})
@ResponseBody
public Map uploadFile(@RequestParam("file") MultipartFile file) {
Map map = new HashMap<>(1);
String path = FileUtil.upload(file);
map.put("link", path);
return map;
}
}
================================================
FILE: src/main/java/com/example/sens/controller/admin/CategoryController.java
================================================
package com.example.sens.controller.admin;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.sens.controller.common.BaseController;
import com.example.sens.entity.Category;
import com.example.sens.dto.JsonResult;
import com.example.sens.service.CategoryService;
import com.example.sens.util.PageUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
/**
*
* 后台分类管理控制器
*
*
*/
@Slf4j
@Controller
@RequestMapping(value = "/admin/category")
public class CategoryController extends BaseController {
@Autowired
private CategoryService categoryService;
/**
* 查询所有分类并渲染category页面
*
* @return 模板路径admin/admin_category
*/
@GetMapping
public String categories(@RequestParam(value = "page", defaultValue = "0") Integer pageNumber,
@RequestParam(value = "size", defaultValue = "10") Integer pageSize,
@RequestParam(value = "sort", defaultValue = "cateSort") String sort,
@RequestParam(value = "order", defaultValue = "desc") String order, Model model) {
Page page = PageUtil.initMpPage(pageNumber, pageSize, sort, order);
Page categoryPage = categoryService.findAll(page);
model.addAttribute("categories", categoryPage.getRecords());
model.addAttribute("pageInfo", PageUtil.convertPageVo(page));
return "admin/admin_category";
}
/**
* 新增/修改分类目录
*
* @param category category对象
* @return 重定向到/admin/category
*/
@PostMapping(value = "/save")
@ResponseBody
public JsonResult saveCategory(@ModelAttribute Category category) {
categoryService.insertOrUpdate(category);
return JsonResult.success("保存成功");
}
/**
* 删除分类
*
* @param cateId 分类Id
* @return JsonResult
*/
@DeleteMapping(value = "/delete")
@ResponseBody
public JsonResult checkDelete(@RequestParam("id") Long cateId) {
//1.判断这个分类有房屋
Integer count = categoryService.countPostByCateId(cateId);
if (count != 0) {
return JsonResult.error("该分类已经有了房屋,无法删除");
}
categoryService.delete(cateId);
return JsonResult.success("删除成功");
}
/**
* 跳转到修改页面
*
* @param cateId cateId
* @param model model
* @return 模板路径admin/admin_category
*/
@GetMapping(value = "/edit")
public String toEditCategory(Model model,
@RequestParam(value = "page", defaultValue = "0") Integer pageNumber,
@RequestParam(value = "size", defaultValue = "10") Integer pageSize,
@RequestParam(value = "sort", defaultValue = "cateSort") String sort,
@RequestParam(value = "order", defaultValue = "desc") String order,
@RequestParam("id") Long cateId) {
Page page = PageUtil.initMpPage(pageNumber, pageSize, sort, order);
//更新的分类
Category category = categoryService.get(cateId);
if (category == null) {
return this.renderNotFound();
}
model.addAttribute("updateCategory", category);
// 所有分类
Page categoryPage = categoryService.findAll(page);
model.addAttribute("categories", categoryPage.getRecords());
model.addAttribute("pageInfo", PageUtil.convertPageVo(page));
return "admin/admin_category";
}
}
================================================
FILE: src/main/java/com/example/sens/controller/admin/NoticeController.java
================================================
package com.example.sens.controller.admin;
import cn.hutool.http.HtmlUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.sens.controller.common.BaseController;
import com.example.sens.dto.JsonResult;
import com.example.sens.entity.Notice;
import com.example.sens.exception.MyBusinessException;
import com.example.sens.service.NoticeService;
import com.example.sens.util.PageUtil;
import com.example.sens.vo.SearchVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
*
* 后台公告管理控制器
*
*
* @author : saysky
* @date : 2020/12/6
*/
@Slf4j
@Controller
@RequestMapping(value = "/admin/notice")
public class NoticeController extends BaseController {
@Autowired
private NoticeService noticeService;
/**
* 处理后台获取公告列表的请求
*
* @param model model
* @return 模板路径admin/admin_notice
*/
@GetMapping
public String notices(Model model,
@RequestParam(value = "page", defaultValue = "1") Integer pageNumber,
@RequestParam(value = "size", defaultValue = "10") Integer pageSize,
@RequestParam(value = "sort", defaultValue = "createTime") String sort,
@RequestParam(value = "order", defaultValue = "desc") String order,
@ModelAttribute SearchVo searchVo) {
Page page = PageUtil.initMpPage(pageNumber, pageSize, sort, order);
Page noticePage = noticeService.findAll(page);
List noticeList = noticePage.getRecords();
model.addAttribute("notices", noticeList);
model.addAttribute("pageInfo", PageUtil.convertPageVo(page));
model.addAttribute("order", order);
model.addAttribute("sort", sort);
return "admin/admin_notice";
}
/**
* 处理跳转到新建公告页面
*
* @return 模板路径admin/admin_editor
*/
@GetMapping(value = "/new")
public String newNotice(Model model) {
return "admin/admin_notice_new";
}
/**
* 添加/更新公告
*
* @param notice Notice实体
*/
@PostMapping(value = "/save")
@ResponseBody
public JsonResult pushNotice(@ModelAttribute Notice notice) {
// 1、提取摘要
int postSummary = 100;
//房屋摘要
String summaryText = HtmlUtil.cleanHtmlTag(notice.getContent());
if (summaryText.length() > postSummary) {
String summary = summaryText.substring(0, postSummary);
notice.setSummary(summary);
} else {
notice.setSummary(summaryText);
}
noticeService.insertOrUpdate(notice);
return JsonResult.success("发布成功");
}
/**
* 处理删除公告的请求
*
* @param noticeId 公告编号
* @return 重定向到/admin/notice
*/
@DeleteMapping(value = "/delete")
@ResponseBody
public JsonResult removeNotice(@RequestParam("id") Long noticeId) {
noticeService.delete(noticeId);
return JsonResult.success("删除成功");
}
/**
* 跳转到编辑公告页面
*
* @param noticeId 公告编号
* @param model model
* @return 模板路径admin/admin_editor
*/
@GetMapping(value = "/edit")
public String editNotice(@RequestParam("id") Long noticeId, Model model) {
Notice notice = noticeService.get(noticeId);
if (notice == null) {
throw new MyBusinessException("公告不存在");
}
model.addAttribute("notice", notice);
return "admin/admin_notice_edit";
}
}
================================================
FILE: src/main/java/com/example/sens/controller/admin/OrderController.java
================================================
package com.example.sens.controller.admin;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.sens.controller.common.BaseController;
import com.example.sens.dto.JsonResult;
import com.example.sens.entity.Order;
import com.example.sens.enums.OrderStatusEnum;
import com.example.sens.service.OrderService;
import com.example.sens.util.PageUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
/**
*
* 订单管理控制器
*
*/
@Slf4j
@Controller
@RequestMapping(value = "/admin/order")
public class OrderController extends BaseController {
@Autowired
private OrderService orderService;
/**
* 查询所有订单并渲染order页面
*
* @return 模板路径admin/admin_order
*/
@GetMapping
public String orders(@RequestParam(value = "page", defaultValue = "0") Integer pageNumber,
@RequestParam(value = "size", defaultValue = "10") Integer pageSize,
@RequestParam(value = "sort", defaultValue = "id") String sort,
@RequestParam(value = "order", defaultValue = "desc") String order, Model model) {
Page page = PageUtil.initMpPage(pageNumber, pageSize, sort, order);
Page orderPage = null;
Order orderCondition = new Order();
orderPage = orderService.findAll(orderCondition, page);
model.addAttribute("orders", orderPage.getRecords());
model.addAttribute("pageInfo", PageUtil.convertPageVo(page));
return "admin/admin_order";
}
/**
* 我出租的房屋订单
*
* @return 模板路径admin/admin_order
*/
@GetMapping("/lease")
public String lease(@RequestParam(value = "page", defaultValue = "0") Integer pageNumber,
@RequestParam(value = "size", defaultValue = "10") Integer pageSize,
@RequestParam(value = "sort", defaultValue = "id") String sort,
@RequestParam(value = "order", defaultValue = "desc") String order, Model model) {
Page page = PageUtil.initMpPage(pageNumber, pageSize, sort, order);
Order orderCondition = new Order();
orderCondition.setOwnerUserId(getLoginUserId());
Page orderPage = orderService.findAll(orderCondition, page);
model.addAttribute("orders", orderPage.getRecords());
model.addAttribute("pageInfo", PageUtil.convertPageVo(page));
model.addAttribute("type", "lease");
return "admin/admin_order";
}
/**
* 我的租房订单
*
* @return 模板路径admin/admin_order
*/
@GetMapping("/rent")
public String rent(@RequestParam(value = "page", defaultValue = "0") Integer pageNumber,
@RequestParam(value = "size", defaultValue = "10") Integer pageSize,
@RequestParam(value = "sort", defaultValue = "id") String sort,
@RequestParam(value = "order", defaultValue = "desc") String order, Model model) {
Page page = PageUtil.initMpPage(pageNumber, pageSize, sort, order);
Order orderCondition = new Order();
orderCondition.setUserId(getLoginUserId());
Page orderPage = orderService.findAll(orderCondition, page);
model.addAttribute("orders", orderPage.getRecords());
model.addAttribute("pageInfo", PageUtil.convertPageVo(page));
model.addAttribute("type", "rent");
return "admin/admin_order";
}
/**
* 删除订单
*
* @param id 订单Id
* @return JsonResult
*/
@DeleteMapping(value = "/delete")
@ResponseBody
public JsonResult delete(@RequestParam("id") Long id) {
Order order = orderService.get(id);
if (order == null) {
return JsonResult.error("订单不存在");
}
if (OrderStatusEnum.HAS_PAY.getCode().equals(order.getStatus())) {
return JsonResult.error("订单生效中,不能删除");
}
orderService.delete(id);
return JsonResult.success("删除成功");
}
/**
* 完结订单
*
* @param id 订单Id
* @return JsonResult
*/
@PostMapping(value = "/finish")
@ResponseBody
public JsonResult finish(@RequestParam("id") Long id) {
Order order = orderService.get(id);
if (order == null) {
return JsonResult.error("订单不存在");
}
order.setStatus(OrderStatusEnum.FINISHED.getCode());
orderService.update(order);
return JsonResult.success("完结成功");
}
/**
* 关闭订单
*
* @param id 订单Id
* @return JsonResult
*/
@PostMapping(value = "/close")
@ResponseBody
@Transactional
public JsonResult close(@RequestParam("id") Long id) {
// 修改订单状态
Order order = orderService.get(id);
if (order == null) {
return JsonResult.error("订单不存在");
}
order.setStatus(OrderStatusEnum.CLOSED.getCode());
orderService.update(order);
return JsonResult.success("取消订单成功");
}
/**
* 财务页面
*
* @param model
* @return
*/
@GetMapping("/finance")
public String finance(@RequestParam(value = "startDate", required = false) String startDate,
@RequestParam(value = "endDate", required = false) String endDate,
@RequestParam(value = "page", defaultValue = "0") Integer pageNumber,
@RequestParam(value = "size", defaultValue = "10") Integer pageSize,
@RequestParam(value = "sort", defaultValue = "id") String sort,
@RequestParam(value = "order", defaultValue = "desc") String order,
Model model) throws ParseException {
Page page = PageUtil.initMpPage(pageNumber, pageSize, sort, order);
Order condition = new Order();
Page orderPage = null;
Order orderCondition = new Order();
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
if (StringUtils.isNotEmpty(startDate)) {
orderCondition.setStartDate(dateFormat.parse(startDate));
}
if (StringUtils.isNotEmpty(endDate)) {
orderCondition.setEndDate(dateFormat.parse(endDate));
}
if (loginUserIsUser()) {
// 用户
orderCondition.setUserId(getLoginUserId());
}
orderPage = orderService.findAll(orderCondition, page);
model.addAttribute("orders", orderPage.getRecords());
model.addAttribute("pageInfo", PageUtil.convertPageVo(page));
Integer totalPrice = orderService.getTotalPriceSum(condition);
model.addAttribute("totalPrice", totalPrice == null ? 0 : totalPrice);
model.addAttribute("startDate", startDate);
model.addAttribute("endDate", endDate);
return "admin/admin_finance";
}
}
================================================
FILE: src/main/java/com/example/sens/controller/admin/PermissionController.java
================================================
package com.example.sens.controller.admin;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.sens.entity.Permission;
import com.example.sens.dto.JsonResult;
import com.example.sens.enums.ResourceTypeEnum;
import com.example.sens.service.PermissionService;
import com.example.sens.util.PageUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 后台权限管理控制器
*/
@Slf4j
@Controller
@RequestMapping(value = "/admin/permission")
public class PermissionController {
@Autowired
private PermissionService permissionService;
/**
* 查询所有权限并渲染permission页面
*
* @return 模板路径admin/admin_permission
*/
@GetMapping
public String permissions(@RequestParam(value = "page", defaultValue = "1") Integer pageNumber,
@RequestParam(value = "size", defaultValue = "10") Integer pageSize,
@RequestParam(value = "sort", defaultValue = "id") String sort,
@RequestParam(value = "order", defaultValue = "asc") String order, Model model) {
//权限列表
Page page = PageUtil.initMpPage(pageNumber, pageSize, sort, order);
Page permissions = permissionService.findAll(page);
model.addAttribute("permissionList", permissions.getRecords());
model.addAttribute("pageInfo", PageUtil.convertPageVo(page));
// 所有权限
model.addAttribute("permissions", getPermissionList());
return "admin/admin_permission";
}
/**
* 新增/修改权限
*
* @param permission permission对象
* @return 重定向到/admin/permission
*/
@PostMapping(value = "/save")
public String savePermission(@ModelAttribute Permission permission) {
permissionService.insertOrUpdate(permission);
return "redirect:/admin/permission";
}
/**
* 删除权限
*
* @param permissionId 权限Id
* @return JsonResult
*/
@DeleteMapping(value = "/delete")
@ResponseBody
public JsonResult checkDelete(@RequestParam("id") Long permissionId) {
// // 请先删除子权限
Integer childCount = permissionService.countChildPermission(permissionId);
if (childCount > 0) {
return JsonResult.error("请先删除子节点");
}
permissionService.delete(permissionId);
return JsonResult.success();
}
/**
* 跳转到新增页面
*
* @param model model
* @return 模板路径admin/admin_permission
*/
@GetMapping(value = "/new")
public String toAddPermission(Model model) {
// 带有等级的权限列表
model.addAttribute("permissionList", permissionService.findPermissionListWithLevel());
// 权限列表
model.addAttribute("permissions", getPermissionList());
return "admin/admin_permission_new";
}
/**
* 跳转到修改页面
*
* @param permissionId permissionId
* @param model model
* @return 模板路径admin/admin_permission
*/
@GetMapping(value = "/edit")
public String toEditPermission(Model model, @RequestParam("id") Long permissionId) {
//更新的权限
Permission permission = permissionService.get(permissionId);
model.addAttribute("updatePermission", permission);
// 带有等级的权限列表
model.addAttribute("permissionList", permissionService.findPermissionListWithLevel());
// 权限列表
model.addAttribute("permissions", getPermissionList());
// 设置URL为编辑的URL
return "admin/admin_permission_edit";
}
/**
* 所有权限
* @return
*/
public List getPermissionList() {
//权限列表
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.orderByAsc("sort");
List permissions = permissionService.findAll(queryWrapper);
// 设置URL为编辑的URL
for (Permission permission : permissions) {
permission.setUrl("/admin/permission/edit?id=" + permission.getId());
if (ResourceTypeEnum.MENU.getCode().equals(permission.getResourceType())) {
permission.setName(permission.getName() + "[" + ResourceTypeEnum.MENU.getDescription() + "]");
} else if (ResourceTypeEnum.BUTTON.getCode().equals(permission.getResourceType())) {
permission.setName(permission.getName() + "[" + ResourceTypeEnum.BUTTON.getDescription() + "]");
} else if (ResourceTypeEnum.PAGE.getCode().equals(permission.getResourceType())) {
permission.setName(permission.getName() + "[" + ResourceTypeEnum.PAGE.getDescription() + "]");
}
}
return permissions;
}
}
================================================
FILE: src/main/java/com/example/sens/controller/admin/PostController.java
================================================
package com.example.sens.controller.admin;
import cn.hutool.http.HtmlUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.sens.controller.common.BaseController;
import com.example.sens.dto.JsonResult;
import com.example.sens.exception.MyBusinessException;
import com.example.sens.entity.*;
import com.example.sens.enums.*;
import com.example.sens.service.*;
import com.example.sens.util.PageUtil;
import com.example.sens.util.RegexUtil;
import com.example.sens.util.SensUtils;
import com.example.sens.vo.SearchVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Objects;
/**
*
* 后台房屋管理控制器
*
*
* @author : saysky
* @date : 2019/12/10
*/
@Slf4j
@Controller
@RequestMapping(value = "/admin/post")
public class PostController extends BaseController {
@Autowired
private PostService postService;
@Autowired
private CityService cityService;
@Autowired
private CategoryService categoryService;
@Autowired
private OrderService orderService;
public static final String TITLE = "title";
public static final String CONTENT = "content";
/**
* 处理后台获取房屋列表的请求
*
* @param model model
* @return 模板路径admin/admin_post
*/
@GetMapping
public String posts(Model model,
@RequestParam(value = "status", defaultValue = "-1") Integer status,
@RequestParam(value = "page", defaultValue = "1") Integer pageNumber,
@RequestParam(value = "size", defaultValue = "10") Integer pageSize,
@RequestParam(value = "sort", defaultValue = "createTime") String sort,
@RequestParam(value = "order", defaultValue = "desc") String order,
@ModelAttribute SearchVo searchVo) {
Post condition = new Post();
condition.setPostStatus(status);
Page page = PageUtil.initMpPage(pageNumber, pageSize, sort, order);
Post postCondition = new Post();
Page postPage = postService.findPostByCondition(postCondition, page);
List postList = postPage.getRecords();
//封装分类和标签
model.addAttribute("posts", postList);
model.addAttribute("pageInfo", PageUtil.convertPageVo(page));
model.addAttribute("status", status);
model.addAttribute("order", order);
model.addAttribute("sort", sort);
model.addAttribute("type", "all");
return "admin/admin_post";
}
/**
* 我的出租
*
* @param model model
* @return 模板路径admin/admin_post
*/
@GetMapping("/lease")
public String lease(Model model,
@RequestParam(value = "status", defaultValue = "-1") Integer status,
@RequestParam(value = "page", defaultValue = "1") Integer pageNumber,
@RequestParam(value = "size", defaultValue = "10") Integer pageSize,
@RequestParam(value = "sort", defaultValue = "createTime") String sort,
@RequestParam(value = "order", defaultValue = "desc") String order,
@ModelAttribute SearchVo searchVo) {
Post condition = new Post();
condition.setPostStatus(status);
condition.setUserId(getLoginUserId());
Page page = PageUtil.initMpPage(pageNumber, pageSize, sort, order);
Page postPage = postService.findPostByCondition(condition, page);
List postList = postPage.getRecords();
//封装分类和标签
model.addAttribute("posts", postList);
model.addAttribute("pageInfo", PageUtil.convertPageVo(page));
model.addAttribute("status", status);
model.addAttribute("order", order);
model.addAttribute("sort", sort);
model.addAttribute("type", "lease");
return "admin/admin_post";
}
/**
* 我的租赁
*
* @param model model
* @return 模板路径admin/admin_post
*/
@GetMapping("/rent")
public String rent(Model model,
@RequestParam(value = "status", defaultValue = "-1") Integer status,
@RequestParam(value = "page", defaultValue = "1") Integer pageNumber,
@RequestParam(value = "size", defaultValue = "10") Integer pageSize,
@RequestParam(value = "sort", defaultValue = "createTime") String sort,
@RequestParam(value = "order", defaultValue = "desc") String order,
@ModelAttribute SearchVo searchVo) {
Page page = PageUtil.initMpPage(pageNumber, pageSize, sort, order);
Page postPage = postService.findByRentUserId(getLoginUserId(), page);
List postList = postPage.getRecords();
//封装分类和标签
model.addAttribute("posts", postList);
model.addAttribute("pageInfo", PageUtil.convertPageVo(page));
model.addAttribute("status", status);
model.addAttribute("order", order);
model.addAttribute("sort", sort);
model.addAttribute("type", "rent");
return "admin/admin_post";
}
/**
* 处理跳转到新建房屋页面
*
* @return 模板路径admin/admin_editor
*/
@GetMapping(value = "/new")
public String newPost(Model model) {
//所有分类
List allCategories = categoryService.findAll();
model.addAttribute("categories", allCategories);
//所有城市
List cities = cityService.findAll();
model.addAttribute("cities", cities);
return "admin/admin_post_new";
}
/**
* 添加/更新房屋
*
* @param post Post实体
*/
@PostMapping(value = "/save")
@ResponseBody
public JsonResult pushPost(@ModelAttribute Post post) {
if (post.getId() != null) {
// 只允许更新部分字段
Post temp = new Post();
temp.setId(post.getId());
temp.setPostContent(post.getPostContent());
temp.setPostSummary(post.getPostSummary());
temp.setPostEditor(post.getPostEditor());
post = temp;
}
// 1、提取摘要
int postSummary = 100;
//房屋摘要
String summaryText = HtmlUtil.cleanHtmlTag(post.getPostContent());
if (summaryText.length() > postSummary) {
String summary = summaryText.substring(0, postSummary);
post.setPostSummary(summary);
} else {
post.setPostSummary(summaryText);
}
// 2.处理imgUrl
String postEditor = post.getPostEditor();
if (StringUtils.isNotEmpty(postEditor)) {
List urlList = RegexUtil.getImgSrc(postEditor);
String imgUrl = SensUtils.listToStr(urlList);
post.setImgUrl(imgUrl);
}
// 2.添加/更新入库
if (post.getId() == null) {
post.setUserId(getLoginUserId());
}
postService.insertOrUpdate(post);
return JsonResult.success("发布成功");
}
/**
* 处理房屋为发布的状态
*
* @param postId 房屋编号
* @return 重定向到/admin/post
*/
@PostMapping(value = "/revert")
@ResponseBody
public JsonResult moveToPublish(@RequestParam("id") Long postId) {
Post post = postService.get(postId);
if (post == null) {
throw new MyBusinessException("房屋不存在");
}
post.setPostStatus(PostStatusEnum.ON_SALE.getCode());
postService.update(post);
return JsonResult.success("操作成功");
}
/**
* 处理删除房屋的请求
*
* @param postId 房屋编号
* @return 重定向到/admin/post
*/
@DeleteMapping(value = "/delete")
@ResponseBody
public JsonResult removePost(@RequestParam("id") Long postId) {
Post post = postService.get(postId);
if (post == null) {
throw new MyBusinessException("房屋不存在");
}
if (PostStatusEnum.OFF_SALE.getCode().equals(post.getPostStatus())) {
throw new MyBusinessException("该房屋已出租,不能删除");
}
// 判断是否有有效订单
// 如果有有效订单,不能删除
Order order = orderService.findByPostId(postId);
if (order != null) {
throw new MyBusinessException("该房屋已出租,不能删除");
}
// 判断权限
if(!Objects.equals(post.getUserId(), getLoginUserId()) && !loginUserIsAdmin()) {
throw new MyBusinessException("没有权限操作");
}
postService.delete(postId);
return JsonResult.success("删除成功");
}
/**
* 跳转到编辑房屋页面
*
* @param postId 房屋编号
* @param model model
* @return 模板路径admin/admin_editor
*/
@GetMapping(value = "/edit")
public String editPost(@RequestParam("id") Long postId, Model model) {
Post post = postService.get(postId);
if (post == null) {
throw new MyBusinessException("房屋不存在");
}
//当前房屋分类
Category category = categoryService.get(post.getCateId());
post.setCategory(category);
model.addAttribute("post", post);
//所有分类
List allCategories = categoryService.findAll();
model.addAttribute("categories", allCategories);
//所有城市
List cities = cityService.findAll();
model.addAttribute("cities", cities);
return "admin/admin_post_edit";
}
}
================================================
FILE: src/main/java/com/example/sens/controller/admin/ProfileController.java
================================================
package com.example.sens.controller.admin;
import com.example.sens.common.constant.CommonConstant;
import com.example.sens.controller.common.BaseController;
import com.example.sens.entity.User;
import com.example.sens.dto.JsonResult;
import com.example.sens.service.UserService;
import com.example.sens.util.Md5Util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.util.Objects;
/**
* 后台用户管理控制器
*/
@Slf4j
@Controller
@RequestMapping(value = "/admin/user")
public class ProfileController extends BaseController {
@Autowired
private UserService userService;
/**
* 获取用户信息并跳转
*
* @return 模板路径admin/admin_profile
*/
@GetMapping("/profile")
public String profile(Model model) {
User user = userService.get(getLoginUserId());
model.addAttribute("user", user);
return "admin/admin_profile";
}
/**
* 获取用户信息并跳转
*
* @return 模板路径admin/admin_info
*/
@GetMapping("/info")
public String info(@RequestParam("userId") Long userId, Model model) {
//1.用户信息
User user = userService.get(userId);
if(user == null) {
return this.renderNotFound();
}
model.addAttribute("user", user);
return "admin/admin_user_info";
}
/**
* 处理修改用户资料的请求
*
* @param user user
* @return JsonResult
*/
@PostMapping(value = "/profile/save")
@ResponseBody
public JsonResult saveProfile(@ModelAttribute User user) {
User loginUser = getLoginUser();
User saveUser = userService.get(loginUser.getId());
saveUser.setId(loginUser.getId());
saveUser.setUserName(user.getUserName());
saveUser.setUserDisplayName(user.getUserDisplayName());
saveUser.setUserAvatar(user.getUserAvatar());
saveUser.setUserDesc(user.getUserDesc());
saveUser.setIdCard(user.getIdCard());
saveUser.setEmail(user.getEmail());
saveUser.setPhone(user.getPhone());
userService.insertOrUpdate(saveUser);
return JsonResult.success("资料修改成功,请重新登录");
}
/**
* 处理修改密码的请求
*
* @param beforePass 旧密码
* @param newPass 新密码
* @return JsonResult
*/
@RequestMapping(method = RequestMethod.POST, value = "/changePass")
@ResponseBody
public JsonResult changePass(@RequestParam(value = "id", required = false) Long id,
@RequestParam(value = "beforePass", required = false) String beforePass,
@RequestParam("newPass") String newPass) {
User loginUser = getLoginUser();
if (id == null) {
// 用户修改密码
User user = userService.get(loginUser.getId());
if (user != null && Objects.equals(user.getUserPass(), Md5Util.toMd5(beforePass, CommonConstant.PASSWORD_SALT, 10))) {
userService.updatePassword(user.getId(), newPass);
} else {
return JsonResult.error("旧密码错误");
}
} else {
// 管理员修改用户密码
if (!loginUserIsAdmin()) {
return JsonResult.error("无权操作");
}
userService.updatePassword(id, newPass);
}
return JsonResult.success("密码重置成功");
}
}
================================================
FILE: src/main/java/com/example/sens/controller/admin/RechargeRecordController.java
================================================
package com.example.sens.controller.admin;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.sens.controller.common.BaseController;
import com.example.sens.dto.JsonResult;
import com.example.sens.entity.RechargeRecord;
import com.example.sens.entity.User;
import com.example.sens.service.RechargeRecordService;
import com.example.sens.service.UserService;
import com.example.sens.util.PageUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
/**
* @author 言曌
* @date 2020/3/17 11:39 下午
*/
@Slf4j
@Controller
@RequestMapping(value = "/admin/rechargeRecord")
public class RechargeRecordController extends BaseController {
@Autowired
private RechargeRecordService rechargeRecordService;
@Autowired
private UserService userService;
/**
* 查询所有充值记录并渲染rechargeRecord页面
*
* @return 模板路径admin/admin_rechargeRecord
*/
@GetMapping
public String rechargeRecords(@RequestParam(value = "startDate", defaultValue = "") String startDate,
@RequestParam(value = "endDate", defaultValue = "") String endDate,
@RequestParam(value = "page", defaultValue = "1") Integer pageNumber,
@RequestParam(value = "size", defaultValue = "10") Integer pageSize,
@RequestParam(value = "sort", defaultValue = "createTime") String sort,
@RequestParam(value = "order", defaultValue = "desc") String order, Model model) {
Page page = PageUtil.initMpPage(pageNumber, pageSize, sort, order);
Page rechargeRecords = null;
if (loginUserIsAdmin()) {
rechargeRecords = rechargeRecordService.findAll(startDate, endDate, page);
} else {
rechargeRecords = rechargeRecordService.findByUserId(startDate, endDate, getLoginUserId(), page);
}
model.addAttribute("rechargeRecords", rechargeRecords.getRecords());
model.addAttribute("pageInfo", PageUtil.convertPageVo(page));
model.addAttribute("startDate", startDate);
model.addAttribute("endDate", endDate);
return "admin/admin_rechargeRecord";
}
/**
* 删除充值记录
*
* @param rechargeRecordId 充值记录Id
* @return JsonResult
*/
@DeleteMapping(value = "/delete")
@ResponseBody
public JsonResult checkDelete(@RequestParam("id") Long rechargeRecordId) {
rechargeRecordService.delete(rechargeRecordId);
return JsonResult.success("删除充值记录成功");
}
/**
* 充值界面
*
* @return JsonResult
*/
@GetMapping(value = "/new")
public String rechargePage(Model model) {
User user = userService.get(getLoginUserId());
model.addAttribute("currentMoney", user.getMoney());
return "admin/admin_rechargeRecord_new";
}
/**
* 充值保存
*
* @param money
* @return
*/
@PostMapping(value = "/save")
@ResponseBody
public JsonResult recharge(@RequestParam("money") Long money) {
if (money > 10000 || money < 10) {
return JsonResult.error("充值金额不合法(最少10元,最多1万元)");
}
// 充值操作
// 忽略,假设直接充值成功
// 修改余额
User loginUser = getLoginUser();
User user = userService.get(loginUser.getId());
user.setMoney(user.getMoney() + money);
userService.insertOrUpdate(user);
// 添加充值记录
RechargeRecord rechargeRecord = new RechargeRecord();
rechargeRecord.setUserId(loginUser.getId());
rechargeRecord.setMoney(money);
rechargeRecord.setCreateTime(new Date());
rechargeRecordService.insert(rechargeRecord);
return JsonResult.success("充值成功", user.getMoney());
}
}
================================================
FILE: src/main/java/com/example/sens/controller/admin/RoleController.java
================================================
package com.example.sens.controller.admin;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.sens.entity.Permission;
import com.example.sens.entity.Role;
import com.example.sens.dto.JsonResult;
import com.example.sens.enums.ResourceTypeEnum;
import com.example.sens.service.PermissionService;
import com.example.sens.service.RoleService;
import com.example.sens.util.PageUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* 后台角色管理控制器
*/
@Slf4j
@Controller
@RequestMapping(value = "/admin/role")
public class RoleController {
@Autowired
private RoleService roleService;
@Autowired
private PermissionService permissionService;
/**
* 查询所有角色并渲染role页面
*
* @return 模板路径admin/admin_role
*/
@GetMapping
public String roles(@RequestParam(value = "page", defaultValue = "1") Integer pageNumber,
@RequestParam(value = "size", defaultValue = "10") Integer pageSize,
@RequestParam(value = "sort", defaultValue = "level") String sort,
@RequestParam(value = "order", defaultValue = "desc") String order, Model model) {
//角色列表
Page page = PageUtil.initMpPage(pageNumber, pageSize, sort, order);
Page roles = roleService.findAll(page);
model.addAttribute("roles", roles.getRecords());
model.addAttribute("pageInfo", PageUtil.convertPageVo(page));
return "admin/admin_role";
}
/**
* 新增/修改角色
*
* @param role role对象
* @return 重定向到/admin/role
*/
@PostMapping(value = "/save")
@ResponseBody
public JsonResult saveRole(@ModelAttribute Role role,
@RequestParam(value = "permissionIds") String permissionIds) {
if (Strings.isNotEmpty(permissionIds)) {
String[] arr = permissionIds.split(",");
List permissions = new ArrayList<>();
for (String permissionId : arr) {
Permission permission = new Permission();
permission.setId(Long.valueOf(permissionId));
permissions.add(permission);
}
role.setPermissions(permissions);
}
roleService.insertOrUpdate(role);
return JsonResult.success();
}
/**
* 删除角色
*
* @param roleId 角色Id
* @return JsonResult
*/
@DeleteMapping(value = "/delete")
@ResponseBody
public JsonResult checkDelete(@RequestParam("id") Long roleId) {
//判断这个角色有没有用户
Integer userCount = roleService.countUserByRoleId(roleId);
if (userCount != 0) {
return JsonResult.error("当前角色已关联用户,无法删除");
}
roleService.delete(roleId);
return JsonResult.success("删除角色成功");
}
/**
* 添加用户页面
*
* @return 模板路径admin/admin_edit
*/
@GetMapping("/new")
public String addRole(Model model) {
// 所有权限
model.addAttribute("permissions", getPermissionList());
return "admin/admin_role_add";
}
/**
* 跳转到修改页面
*
* @param roleId roleId
* @param model model
* @return 模板路径admin/admin_role
*/
@GetMapping(value = "/edit")
public String toEditRole(Model model, @RequestParam("id") Long roleId) {
//更新的角色
Role role = roleService.findByRoleId(roleId);
//当前角色的权限列表
role.setPermissions(permissionService.listPermissionsByRoleId(roleId));
model.addAttribute("updateRole", role);
// 所有权限
model.addAttribute("permissions", getPermissionList());
// 当前角色的权限列表
List currentPermissionIds = permissionService.findPermissionByRoleId(roleId).stream().map(p -> p.getId()).collect(Collectors.toList());
model.addAttribute("currentPermissionIds", currentPermissionIds);
return "admin/admin_role_edit";
}
/**
* 所有权限
* @return
*/
public List getPermissionList() {
//权限列表
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.orderByAsc("sort");
List permissions = permissionService.findAll(queryWrapper);
// 设置URL为编辑的URL
for (Permission permission : permissions) {
permission.setUrl("/admin/permission/edit?id=" + permission.getId());
if (ResourceTypeEnum.MENU.getCode().equals(permission.getResourceType())) {
permission.setName(permission.getName() + "[" + ResourceTypeEnum.MENU.getDescription() + "]");
} else if (ResourceTypeEnum.BUTTON.getCode().equals(permission.getResourceType())) {
permission.setName(permission.getName() + "[" + ResourceTypeEnum.BUTTON.getDescription() + "]");
} else if (ResourceTypeEnum.PAGE.getCode().equals(permission.getResourceType())) {
permission.setName(permission.getName() + "[" + ResourceTypeEnum.PAGE.getDescription() + "]");
}
}
return permissions;
}
}
================================================
FILE: src/main/java/com/example/sens/controller/admin/UserController.java
================================================
package com.example.sens.controller.admin;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.sens.common.constant.CommonConstant;
import com.example.sens.entity.*;
import com.example.sens.enums.RoleEnum;
import com.example.sens.service.*;
import com.example.sens.controller.common.BaseController;
import com.example.sens.dto.JsonResult;
import com.example.sens.util.Md5Util;
import com.example.sens.util.PageUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 后台用户管理控制器
*/
@Slf4j
@Controller
@RequestMapping(value = "/admin/user")
public class UserController extends BaseController {
@Autowired
private UserService userService;
@Autowired
private RoleService roleService;
@Autowired
private UserRoleRefService userRoleRefService;
public static final String USER_NAME = "userName";
public static final String USER_DISPLAY_NAME = "userDisplayName";
public static final String EMAIL = "email";
/**
* 查询所有分类并渲染user页面
*
* @return 模板路径admin/admin_user
*/
@GetMapping
public String users(
@RequestParam(value = "status", defaultValue = "0") Integer status,
@RequestParam(value = "keywords", defaultValue = "") String keywords,
@RequestParam(value = "searchType", defaultValue = "") String searchType,
@RequestParam(value = "page", defaultValue = "1") Integer pageNumber,
@RequestParam(value = "size", defaultValue = "10") Integer pageSize,
@RequestParam(value = "sort", defaultValue = "createTime") String sort,
@RequestParam(value = "order", defaultValue = "desc") String order, Model model) {
//用户列表
Page page = PageUtil.initMpPage(pageNumber, pageSize, sort, order);
User condition = new User();
condition.setStatus(status);
if (!StringUtils.isBlank(keywords)) {
if (USER_NAME.equals(searchType)) {
condition.setUserName(keywords);
} else if (USER_DISPLAY_NAME.equals(searchType)) {
condition.setUserDisplayName(keywords);
} else if (EMAIL.equals(searchType)) {
condition.setIdCard(keywords);
}
}
Page users = userService.findByRoleAndCondition(CommonConstant.NONE, condition, page);
for(User user : users.getRecords()) {
user.setRole(roleService.findByUserId(user.getId()));
}
model.addAttribute("users", users.getRecords());
model.addAttribute("pageInfo", PageUtil.convertPageVo(page));
model.addAttribute("status", status);
model.addAttribute("keywords", keywords);
model.addAttribute("searchType", searchType);
model.addAttribute("sort", sort);
model.addAttribute("order", order);
return "admin/admin_user";
}
/**
* 删除用户
*
* @param userId 用户Id
* @return JsonResult
*/
@DeleteMapping(value = "/delete")
@ResponseBody
public JsonResult removeUser(@RequestParam("id") Long userId) {
userService.delete(userId);
return JsonResult.success("删除成功");
}
/**
* 添加用户页面
*
* @return 模板路径admin/admin_edit
*/
@GetMapping("/new")
public String addUser(Model model) {
//角色列表
List roles = roleService.findAll();
model.addAttribute("roles", roles);
return "admin/admin_user_add";
}
/**
* 编辑用户页面
*
* @return 模板路径admin/admin_edit
*/
@GetMapping("/edit")
public String edit(@RequestParam("id") Long userId, Model model) {
User user = userService.get(userId);
if (user != null) {
model.addAttribute("user", user);
//该用户的角色
Role currentRole = roleService.findByUserId(userId);
model.addAttribute("currentRole", currentRole);
//角色列表
List roles = roleService.findAll();
model.addAttribute("roles", roles);
return "admin/admin_user_edit";
}
return this.renderNotFound();
}
/**
* 批量删除
*
* @param ids 用户ID列表
* @return
*/
@DeleteMapping(value = "/batchDelete")
@ResponseBody
public JsonResult batchDelete(@RequestParam("ids") List ids) {
//批量操作
if (ids == null || ids.size() == 0 || ids.size() >= 100) {
return JsonResult.error("参数不合法!");
}
List userList = userService.findByBatchIds(ids);
for (User user : userList) {
userService.delete(user.getId());
}
return JsonResult.success("删除成功");
}
/**
* 新增/修改用户
*
* @param user user
* @return 重定向到/admin/user
*/
@PostMapping(value = "/save")
@ResponseBody
@Transactional(rollbackFor = Exception.class)
public JsonResult saveUser(@ModelAttribute User user,
@RequestParam(value = "roleId", required = false) Long roleId) {
// 1.添加用户
if(user.getId() == null) {
user.setUserPass(Md5Util.toMd5(user.getUserPass(), CommonConstant.PASSWORD_SALT, 10));
}
userService.insertOrUpdate(user);
if(roleId != null) {
// 2.先删除该用户的角色关联
userRoleRefService.deleteByUserId(user.getId());
// 3.添加角色关联
userRoleRefService.insert(new UserRoleRef(user.getId(), roleId));
}
return JsonResult.success("保存成功");
}
}
================================================
FILE: src/main/java/com/example/sens/controller/common/BaseController.java
================================================
package com.example.sens.controller.common;
import com.example.sens.entity.User;
import com.example.sens.enums.RoleEnum;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
/**
* Controller抽象类
*/
public abstract class BaseController {
/**
* 渲染404页面
*
* @return redirect:/404
*/
public String renderNotFound() {
return "forward:/404";
}
/**
* 渲染404页面
*
* @return redirect:/404
*/
public String renderNotAllowAccess() {
return "redirect:/403";
}
/**
* 当前登录用户
*
* @return
*/
public User getLoginUser() {
Subject subject = SecurityUtils.getSubject();
if (subject.isAuthenticated()) {
return (User) subject.getPrincipal();
}
return null;
}
/**
* 当前用户ID
*
* @return
*/
public Long getLoginUserId() {
return getLoginUser().getId();
}
/**
* 当前用户是管理员
*
* @return
*/
public Boolean loginUserIsAdmin() {
User loginUser = getLoginUser();
if (loginUser != null) {
return RoleEnum.ADMIN.getValue().equalsIgnoreCase(loginUser.getRole().getRole());
}
return false;
}
/**
* 当前用户是消费者
*
* @return
*/
public Boolean loginUserIsUser() {
User loginUser = getLoginUser();
if (loginUser != null) {
return RoleEnum.USER.getValue().equalsIgnoreCase(loginUser.getRole().getRole());
}
return false;
}
}
================================================
FILE: src/main/java/com/example/sens/controller/common/CommonController.java
================================================
package com.example.sens.controller.common;
import com.example.sens.enums.CommonParamsEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import javax.servlet.http.HttpServletRequest;
/**
* 错误页面控制器
*/
@Slf4j
@Controller
public class CommonController implements ErrorController {
/**
* 渲染404,500
*
* @param request request
* @return String
*/
@GetMapping(value = "/error")
public String handleError(HttpServletRequest request) {
Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
if (statusCode.equals(CommonParamsEnum.NOT_FOUND.getValue())) {
return "redirect:/404";
} else {
return "redirect:/500";
}
}
/**
* 渲染403页面
*
* @return String
*/
@GetMapping(value = "/403")
public String fourZeroThree() {
return "common/error/403";
}
/**
* 渲染404页面
*
* @return String
*/
@GetMapping(value = "/404")
public String fourZeroFour() {
return "common/error/404";
}
/**
* 渲染500页面
*
* @return String
*/
@GetMapping(value = "/500")
public String fiveZeroZero() {
return "common/error/500";
}
/**
* Returns the path of the error page.
*
* @return the error path
*/
@Override
public String getErrorPath() {
return "/error";
}
}
================================================
FILE: src/main/java/com/example/sens/controller/home/FrontPostController.java
================================================
package com.example.sens.controller.home;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.sens.controller.common.BaseController;
import com.example.sens.dto.JsonResult;
import com.example.sens.entity.*;
import com.example.sens.enums.OrderStatusEnum;
import com.example.sens.enums.PostStatusEnum;
import com.example.sens.service.*;
import com.example.sens.util.DateUtil;
import com.example.sens.util.FileUtil;
import com.example.sens.util.PageUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* @author 言曌
* @date 2020/3/11 4:59 下午
*/
@Controller
public class FrontPostController extends BaseController {
@Autowired
private CategoryService categoryService;
@Autowired
private PostService postService;
@Autowired
private CityService cityService;
@Autowired
private OrderService orderService;
@Autowired
private UserService userService;
/**
* 房屋列表
*
* @param model
* @return
*/
@GetMapping("/post")
public String postList(@RequestParam(value = "page", defaultValue = "1") Integer pageNumber,
@RequestParam(value = "size", defaultValue = "6") Integer pageSize,
@RequestParam(value = "sort", defaultValue = "createTime") String sort,
@RequestParam(value = "order", defaultValue = "desc") String order,
@RequestParam(value = "postTitle", defaultValue = "") String postTitle,
@RequestParam(value = "cityId", defaultValue = "-1") Long cityId,
@RequestParam(value = "cateId", defaultValue = "-1") Long cateId,
@RequestParam(value = "area", defaultValue = "") String area,
@RequestParam(value = "price", defaultValue = "") String price,
@RequestParam(value = "status", defaultValue = "-1") Integer status,
HttpSession session,
Model model) {
Post condition = new Post();
List categoryList = categoryService.findAll();
model.addAttribute("categoryList", categoryList);
List cityList = cityService.findAll();
model.addAttribute("cityList", cityList);
model.addAttribute("postCount", postService.count(null));
try {
if (StringUtils.isNotEmpty(price)) {
String[] priceArr = price.split("-");
if (priceArr.length == 2) {
condition.setMinPrice(Integer.valueOf(priceArr[0]));
condition.setMaxPrice(Integer.valueOf(priceArr[1]));
}
}
if (StringUtils.isNotEmpty(area)) {
String[] areaArr = price.split("-");
if (areaArr.length == 2) {
condition.setMinArea(Integer.valueOf(areaArr[0]));
condition.setMaxArea(Integer.valueOf(areaArr[1]));
}
}
} catch (Exception e) {
e.printStackTrace();
}
// 查询日期列表
Page page = PageUtil.initMpPage(pageNumber, pageSize, sort, order);
condition.setPostTitle(postTitle);
condition.setPostStatus(status);
condition.setCateId(cateId);
condition.setCityId(cityId);
Page postPage = postService.findPostByCondition(condition, page);
model.addAttribute("page", postPage);
model.addAttribute("postTitle", postTitle);
model.addAttribute("cityId", cityId);
model.addAttribute("cateId", cateId);
model.addAttribute("status", status);
model.addAttribute("area", area);
model.addAttribute("price", price);
// 侧边栏
model.addAttribute("onCount", postService.countByStatus(PostStatusEnum.ON_SALE.getCode()));
model.addAttribute("offCount", postService.countByStatus(PostStatusEnum.OFF_SALE.getCode()));
if (cityId != null && cityId != -1) {
City city = cityService.get(cityId);
if (city != null) {
session.setAttribute("city", city);
}
} else {
session.removeAttribute("city");
}
return "home/postList";
}
/**
* 房屋详情
*
* @param id
* @param model
* @return
*/
@GetMapping("/post/{id}")
public String postDetails(@PathVariable("id") Long id,
@RequestParam(value = "startDate", required = false) String start,
@RequestParam(value = "quantity", defaultValue = "1") Integer quantity,
HttpSession session,
Model model) {
// 房屋
Post post = postService.get(id);
if (post == null) {
return renderNotFound();
}
// 分类和城市
Category category = categoryService.get(post.getCateId());
City city = cityService.get(post.getCityId());
User user = userService.get(post.getUserId());
post.setCategory(category);
post.setCity(city);
post.setUser(user);
model.addAttribute("post", post);
boolean allowEdit = getLoginUser() != null && (loginUserIsAdmin() || Objects.equals(post.getUserId(), getLoginUserId()));
model.addAttribute("allowEdit", allowEdit);
String[] imgUrlList = post.getImgUrl().split(",");
model.addAttribute("imgUrlList", imgUrlList);
List categoryList = categoryService.findAll();
model.addAttribute("categoryList", categoryList);
List cityList = cityService.findAll();
model.addAttribute("cityList", cityList);
City citySession = (City) session.getAttribute("city");
Long cityId = citySession == null ? null : citySession.getId();
List latestPostList = postService.getLatestPost(cityId, 6);
model.addAttribute("latestPostList", latestPostList);
// 可以考虑优化下,暂时没有时间优化
List unionRentPost = postService.getUnionRentPost(post);
List orderList = new ArrayList<>();
for (Post temp : unionRentPost) {
Order order = orderService.findByPostId(temp.getId());
if (order == null) {
order = new Order();
} else {
order.setUser(userService.get(order.getUserId()));
}
order.setPost(temp);
orderList.add(order);
}
model.addAttribute("orderList", orderList);
return "home/post";
}
/**
* 结算页面
*
* @param postId
* @param start
* @param quantity
* @param model
* @return
*/
@GetMapping("/checkout")
public String checkout(@RequestParam("postId") Long postId,
@RequestParam(value = "startDate", required = false) String start,
@RequestParam(value = "quantity", defaultValue = "1") Integer quantity,
Model model) {
DateFormat dateFormat = new SimpleDateFormat(DateUtil.FORMAT);
if (quantity == null || quantity < 1) {
quantity = 1;
}
Date today = new Date();
// 判断入住日期是否合法
if (StringUtils.isEmpty(start)) {
start = dateFormat.format(today);
} else {
try {
Date startDate = dateFormat.parse(start);
if (startDate.before(today)) {
start = dateFormat.format(today);
}
} catch (ParseException e) {
start = dateFormat.format(today);
e.printStackTrace();
}
}
Post post = postService.get(postId);
if (post == null) {
return this.renderNotFound();
}
User user = getLoginUser();
if (user == null) {
return "redirect:/";
}
// 分类列表
List categoryList = categoryService.findAll();
model.addAttribute("categoryList", categoryList);
List cityList = cityService.findAll();
model.addAttribute("cityList", cityList);
model.addAttribute("post", post);
model.addAttribute("startDate", start);
model.addAttribute("quantity", quantity);
model.addAttribute("user", user);
return "home/checkout";
}
/**
* 创建订单
*
* @param postId
* @param quantity
* @return
*/
@PostMapping("/order")
@Transactional
@ResponseBody
public JsonResult addOrder(@RequestParam(value = "postId") Long postId,
@RequestParam(value = "quantity") Integer quantity) {
User user = getLoginUser();
if (user == null) {
return JsonResult.error("请先登录");
}
if (quantity == null || quantity < 1 || quantity > 12) {
return JsonResult.error("月数不合法");
}
Post post = postService.get(postId);
if (post == null) {
return JsonResult.error("房屋不存在");
}
if (Objects.equals(post.getUserId(), user.getId())) {
return JsonResult.error("不能租赁自己的房子哦");
}
if (!PostStatusEnum.ON_SALE.getCode().equals(post.getPostStatus())) {
return JsonResult.error("房屋已租出,暂时无法预定");
}
Date today = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(today);
cal.add(Calendar.MONTH, quantity);
// 添加订单
Order order = new Order();
order.setPostId(postId);
order.setQuantity(quantity);
order.setStartDate(today);
order.setEndDate(cal.getTime());
order.setUserId(user.getId());
order.setOwnerUserId(post.getUserId());
order.setStatus(OrderStatusEnum.NOT_PAY.getCode());
order.setPrice(post.getPrice() * quantity + post.getDeposit());
order.setCreateTime(new Date());
order.setUpdateTime(new Date());
orderService.insert(order);
return JsonResult.success("订单创建成功", order.getId());
}
@GetMapping("/order/{id}")
public String order(@PathVariable("id") Long id, Model model) {
Order order = orderService.get(id);
if (order == null) {
return this.renderNotFound();
}
User user = getLoginUser();
if (user == null) {
return "redirect:/login";
}
if (!Objects.equals(user.getId(), order.getUserId()) && !Objects.equals(user.getId(), order.getOwnerUserId()) && !loginUserIsAdmin()) {
return this.renderNotAllowAccess();
}
model.addAttribute("order", order);
// 分类列表
List categoryList = categoryService.findAll();
model.addAttribute("categoryList", categoryList);
List cityList = cityService.findAll();
model.addAttribute("cityList", cityList);
model.addAttribute("user", userService.get(order.getUserId()));
return "home/order";
}
/**
* 电子合同
*
* @param orderId
* @return
*/
@GetMapping("/agreement")
public String agreement(@RequestParam("orderId") Long orderId, Model model) {
Order order = orderService.get(orderId);
if (order == null) {
return this.renderNotFound();
}
Post post = postService.get(order.getPostId());
order.setPost(post);
order.setUser(userService.get(order.getUserId()));
order.setOwnerUser(userService.get(order.getOwnerUserId()));
// User user = getLoginUser();
// if (user == null) {
// return "redirect:/login";
// }
//
// if (!Objects.equals(user.getId(), order.getUserId()) && !Objects.equals(user.getId(), order.getOwnerUserId()) && !loginUserIsAdmin()) {
// return this.renderNotAllowAccess();
// }
model.addAttribute("order", order);
List cityList = cityService.findAll();
model.addAttribute("cityList", cityList);
List categoryList = categoryService.findAll();
model.addAttribute("categoryList", categoryList);
return "home/agreement";
}
/**
* 下载合同
*
* @param orderId
* @param response
*/
@GetMapping("/agreement/download")
public void agreementDownload(@RequestParam("orderId") Long orderId,
HttpServletRequest request,
HttpServletResponse response) {
StringBuffer requestURL = request.getRequestURL();
String tempContextUrl = requestURL.delete(requestURL.length() - request.getRequestURI().length(), requestURL.length()).append("/").toString();
ServletOutputStream out = null;
InputStream inputStream = null;
try {
Order order = orderService.get(orderId);
User user = userService.get(order.getUserId());
User ownerUser = userService.get(order.getOwnerUserId());
String pdfName = ownerUser.getUserDisplayName() + "&" + user.getUserDisplayName() + "租房合同.html";
// 获取外部文件流
URL url = new URL(tempContextUrl + "agreement?orderId=" + orderId);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(3 * 1000);
//防止屏蔽程序抓取而返回403错误
conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
inputStream = conn.getInputStream();
int len = 0;
// 输出 下载的响应头,如果下载的文件是中文名,文件名需要经过url编码
response.setContentType("text/html;charset=utf-8");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(pdfName, "UTF-8"));
response.setHeader("Cache-Control", "no-cache");
out = response.getOutputStream();
byte[] buffer = new byte[1024];
while ((len = inputStream.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
out.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (out != null) {
try {
out.close();
} catch (Exception e) {
}
}
}
}
/**
* 支付页面
*
* @param orderId
* @param model
* @return
*/
@GetMapping("/pay")
public String pay(@RequestParam("orderId") Long orderId, Model model) {
Order order = orderService.get(orderId);
if (order == null) {
return this.renderNotFound();
}
Post post = postService.get(order.getPostId());
order.setPost(post);
User user = getLoginUser();
if (user == null) {
return "redirect:/login";
}
if (!Objects.equals(user.getId(), order.getUserId()) && !Objects.equals(user.getId(), order.getOwnerUserId()) && !loginUserIsAdmin()) {
return this.renderNotAllowAccess();
}
if (!Objects.equals(OrderStatusEnum.NOT_PAY.getCode(), order.getStatus())) {
return this.renderNotAllowAccess();
}
model.addAttribute("order", order);
List cityList = cityService.findAll();
model.addAttribute("cityList", cityList);
List categoryList = categoryService.findAll();
model.addAttribute("categoryList", categoryList);
return "home/pay";
}
/**
* 支付
*
* @return orderId
*/
@PostMapping("/pay")
@Transactional
@ResponseBody
public JsonResult paySuccess(@RequestParam(value = "orderId") Long orderId) {
User user = userService.get(getLoginUserId());
if (user == null) {
return JsonResult.error("请先登录");
}
Order order = orderService.get(orderId);
if (order == null) {
return JsonResult.error("订单不存在");
}
if (user.getMoney() < order.getPrice()) {
return JsonResult.error("余额不足,请充值");
}
if (!Objects.equals(user.getId(), order.getUserId())) {
return JsonResult.error("没有权限");
}
Post post = postService.get(order.getPostId());
if (post == null || !Objects.equals(post.getPostStatus(), PostStatusEnum.ON_SALE.getCode())) {
return JsonResult.error("房屋已租出,暂时无法预定");
}
order.setStatus(OrderStatusEnum.HAS_PAY.getCode());
orderService.update(order);
post.setPostStatus(PostStatusEnum.OFF_SALE.getCode());
postService.update(post);
// 这里暂不用乐观锁实现,忽略并发问题
// 我的余额减少
user.setMoney(user.getMoney() - order.getPrice());
userService.update(user);
// 对方的余额增加
User ownerUser = userService.get(order.getOwnerUserId());
ownerUser.setMoney(ownerUser.getMoney() + order.getPrice());
userService.update(ownerUser);
return JsonResult.success("支付成功", order.getId());
}
@GetMapping("/login")
public String login() {
return "home/login";
}
@GetMapping("/register")
public String register() {
return "home/register";
}
}
================================================
FILE: src/main/java/com/example/sens/controller/home/IndexController.java
================================================
package com.example.sens.controller.home;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.sens.controller.common.BaseController;
import com.example.sens.entity.*;
import com.example.sens.enums.PostStatusEnum;
import com.example.sens.service.*;
import com.example.sens.util.PageUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.Objects;
/**
* @author 言曌
* @date 2020/3/9 11:00 上午
*/
@Controller
public class IndexController extends BaseController {
@Autowired
private PostService postService;
@Autowired
private CategoryService categoryService;
@Autowired
private CityService cityService;
@Autowired
private NoticeService noticeService;
@GetMapping("/")
public String index(Model model, HttpSession session) {
List categoryList = categoryService.findAll();
model.addAttribute("categoryList", categoryList);
List cityList = cityService.findAll();
model.addAttribute("cityList", cityList);
City city = (City) session.getAttribute("city");
Long cityId = city == null ? null : city.getId();
List latestPostList = postService.getLatestPost(cityId, 6);
model.addAttribute("latestPostList", latestPostList);
return "home/index";
}
@GetMapping("/contact")
public String contact(Model model) {
List categoryList = categoryService.findAll();
model.addAttribute("categoryList", categoryList);
List cityList = cityService.findAll();
model.addAttribute("cityList", cityList);
return "home/contact";
}
/**
* 新闻列表
*
* @param model
* @return
*/
@GetMapping("/notice")
public String noticeList(@RequestParam(value = "page", defaultValue = "1") Integer pageNumber,
@RequestParam(value = "size", defaultValue = "10") Integer pageSize,
@RequestParam(value = "sort", defaultValue = "createTime") String sort,
@RequestParam(value = "order", defaultValue = "desc") String order,
Model model) {
List categoryList = categoryService.findAll();
model.addAttribute("categoryList", categoryList);
List cityList = cityService.findAll();
model.addAttribute("cityList", cityList);
Page page = PageUtil.initMpPage(pageNumber, pageSize, sort, order);
Page postPage = noticeService.findAll(page);
model.addAttribute("page", postPage);
model.addAttribute("noticeList", postPage.getRecords());
return "home/noticeList";
}
/**
* 新闻详情
*
* @param id
* @param model
* @return
*/
@GetMapping("/notice/{id}")
public String noticeDetails(@PathVariable("id") Long id,
@RequestParam(value = "startDate", required = false) String start,
@RequestParam(value = "quantity", defaultValue = "1") Integer quantity,
Model model) {
// 新闻
Notice notice = noticeService.get(id);
if (notice == null) {
return renderNotFound();
}
model.addAttribute("notice", notice);
List categoryList = categoryService.findAll();
model.addAttribute("categoryList", categoryList);
List cityList = cityService.findAll();
model.addAttribute("cityList", cityList);
return "home/notice";
}
}
================================================
FILE: src/main/java/com/example/sens/controller/home/LoginController.java
================================================
package com.example.sens.controller.home;
import com.example.sens.common.constant.CommonConstant;
import com.example.sens.controller.common.BaseController;
import com.example.sens.entity.Role;
import com.example.sens.entity.User;
import com.example.sens.entity.UserRoleRef;
import com.example.sens.dto.JsonResult;
import com.example.sens.enums.RoleEnum;
import com.example.sens.enums.UserStatusEnum;
import com.example.sens.service.*;
import com.example.sens.util.Md5Util;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import java.util.Set;
@Controller
@Slf4j
public class LoginController extends BaseController {
@Autowired
private PermissionService permissionService;
@Autowired
private UserService userService;
@Autowired
private RoleService roleService;
@Autowired
private UserRoleRefService userRoleRefService;
/**
* 验证登录信息
*
* @param userName 登录名:身份证号码/账号
* @param userPass password 密码
* @return JsonResult JsonResult
*/
@PostMapping(value = "/login")
@ResponseBody
public JsonResult getLogin(@RequestParam("userName") String userName,
@RequestParam("userPass") String userPass) {
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(userName, userPass);
try {
subject.login(token);
if (subject.isAuthenticated()) {
//登录成功,修改登录错误次数为0
User user = (User) subject.getPrincipal();
Set permissionUrls = permissionService.findPermissionUrlsByUserId(user.getId());
subject.getSession().setAttribute("permissionUrls", permissionUrls);
return JsonResult.success("登录成功");
}
} catch (UnknownAccountException e) {
return JsonResult.error("账号不存在");
} catch (IncorrectCredentialsException e) {
e.printStackTrace();
return JsonResult.error("账号或密码错误");
} catch (LockedAccountException e) {
return JsonResult.error(e.getMessage());
} catch (Exception e) {
e.printStackTrace();
log.info(e.getMessage());
}
return JsonResult.error("服务器内部错误");
}
/**
* 退出登录
*
* @return 重定向到/login
*/
@GetMapping(value = "/logout")
public String logOut() {
Subject subject = SecurityUtils.getSubject();
subject.logout();
return "redirect:/";
}
/**
* 退出登录
*
* @return 重定向到/login
*/
@PostMapping(value = "/logout")
@ResponseBody
public JsonResult ajaxLogOut() {
Subject subject = SecurityUtils.getSubject();
subject.logout();
return JsonResult.success();
}
/**
* 验证注册信息
*
* @param userName 账号
* @param idCard 身份证号码
* @return JsonResult JsonResult
*/
@PostMapping(value = "/register")
@ResponseBody
@Transactional
public JsonResult getRegister(@RequestParam("userName") String userName,
@RequestParam("userPass") String userPass,
@RequestParam("idCard") String idCard,
@RequestParam("userDisplayName") String userDisplayName) {
// 1.校验是否输入完整
if (StringUtils.isEmpty(userName) || StringUtils.isEmpty(userPass) || StringUtils.isEmpty(idCard)) {
return JsonResult.error("请填写完整信息");
}
// 2.密码长度是否合法
if (userPass.length() > 20 || userPass.length() < 6) {
return JsonResult.error("用户密码长度为6-20位!");
}
// 3.密码长度是否合法
Role role = roleService.findByRoleName(RoleEnum.USER.getValue());
//3.创建用户
User user = new User();
user.setUserName(userName);
user.setUserDisplayName(userDisplayName);
user.setIdCard(idCard);
user.setUserPass(Md5Util.toMd5(userPass, CommonConstant.PASSWORD_SALT, 10));
user.setUserAvatar("/static/images/avatar/" + RandomUtils.nextInt(1, 41) + ".jpeg");
user.setStatus(UserStatusEnum.NORMAL.getCode());
userService.insert(user);
//4.关联角色
userRoleRefService.insert(new UserRoleRef(user.getId(), role.getId()));
return JsonResult.success("注册成功");
}
/**
* 检查用户是否登录
*
* @return JsonResult
*/
@GetMapping(value = "/checkLogin")
@ResponseBody
public JsonResult checkLogin() {
User user = getLoginUser();
if (user == null) {
return JsonResult.error("请先登录");
} else {
return JsonResult.success();
}
}
}
================================================
FILE: src/main/java/com/example/sens/dto/JsonResult.java
================================================
package com.example.sens.dto;
import lombok.Data;
/**
*
* Json格式
*
*
* @author : saysky
* @date : 2018/5/24
*/
@Data
public class JsonResult {
/**
* 返回的状态码,0:失败,1:成功
*/
private Integer code;
/**
* 返回信息
*/
private String msg;
/**
* 返回的数据
*/
private Object result;
/**
* 不返回数据的构造方法
*
* @param code 状态码
* @param msg 信息
*/
public JsonResult(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
/**
* 返回数据的构造方法
*
* @param code 状态码
* @param msg 信息
* @param result 数据
*/
public JsonResult(Integer code, String msg, Object result) {
this.code = code;
this.msg = msg;
this.result = result;
}
/**
* 返回状态码和数据
*
* @param code 状态码
* @param result 数据
*/
public JsonResult(Integer code, Object result) {
this.code = code;
this.result = result;
}
public static JsonResult error(String msg) {
return new JsonResult(0, msg);
}
public static JsonResult error(String msg, Object data) {
return new JsonResult(0, msg, data);
}
public static JsonResult success() {
return new JsonResult(1, "操作成功");
}
public static JsonResult success(String msg) {
return new JsonResult(1, msg);
}
public static JsonResult success(String msg, Object result) {
return new JsonResult(1, msg, result);
}
}
================================================
FILE: src/main/java/com/example/sens/dto/PostQueryCondition.java
================================================
package com.example.sens.dto;
import lombok.Data;
import java.util.List;
/**
* @author 言曌
* @date 2020/3/12 4:53 下午
*/
@Data
public class PostQueryCondition {
/**
* 用户ID
*/
private Long userId;
/**
* 分类ID
*/
private Long cateId;
/**
* 预订的日期集合
*/
private List dateList;
}
================================================
FILE: src/main/java/com/example/sens/dto/QueryCondition.java
================================================
package com.example.sens.dto;
import com.example.sens.vo.SearchVo;
import lombok.Data;
import java.io.Serializable;
/**
* 查询封装类
* @author 言曌
* @date 2019-08-16 13:45
*/
@Data
public class QueryCondition implements Serializable {
/**
* 根据字段筛选
*/
private T data;
/**
* 一般筛选
*/
private SearchVo searchVo;
public QueryCondition() {
}
public QueryCondition(T data) {
this.data = data;
}
public QueryCondition(T data, SearchVo searchVo) {
this.data = data;
this.searchVo = searchVo;
}
}
================================================
FILE: src/main/java/com/example/sens/entity/Category.java
================================================
package com.example.sens.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.example.sens.common.base.BaseEntity;
import lombok.Data;
/**
*
* 房屋分类
*
*
* @author : saysky
* @date : 2019/11/30
*/
@Data
@TableName("category")
public class Category extends BaseEntity {
/**
* 分类名称
*/
private String cateName;
/**
* 分类排序号
*/
private Integer cateSort;
/**
* 分类描述
*/
private String cateDesc;
/**
* 房屋数量
*/
@TableField(exist = false)
private Integer count;
}
================================================
FILE: src/main/java/com/example/sens/entity/City.java
================================================
package com.example.sens.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.example.sens.common.base.BaseEntity;
import lombok.Data;
/**
*
* 城市
*
*
* @author : saysky
* @date : 2019/11/30
*/
@Data
@TableName("city")
public class City extends BaseEntity {
/**
* 分类名称
*/
private String cityName;
/**
* 房屋数
*/
@TableField(exist = false)
private Integer count;
}
================================================
FILE: src/main/java/com/example/sens/entity/Notice.java
================================================
package com.example.sens.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.example.sens.common.base.BaseEntity;
import lombok.Data;
/**
*
* 新闻公告
*
*/
@Data
@TableName("notice")
public class Notice extends BaseEntity {
/**
* 标题
*/
private String title;
/**
* 内容
*/
private String content;
/**
* 摘要
*/
private String summary;
}
================================================
FILE: src/main/java/com/example/sens/entity/Order.java
================================================
package com.example.sens.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.example.sens.common.base.BaseEntity;
import lombok.Data;
import java.util.Date;
/**
* 订单
* @author 言曌
* @date 2020/4/5 3:25 下午
*/
@Data
@TableName("t_order")
public class Order extends BaseEntity {
/**
* 下单用户ID
*/
private Long userId;
/**
* 业主用户ID
*/
private Long ownerUserId;
/**
* 房间ID
*/
private Long postId;
/**
* 数量
*/
private Integer quantity;
/**
* 开始日期
*/
private Date startDate;
/**
* 结束日期
*/
private Date endDate;
/**
* 订单状态:0待支付,1已支付生效中,2已完结
*/
private Integer status;
/**
* 总价
*/
private Long price;
/**
* 房屋
*/
@TableField(exist = false)
private Post post;
/**
* 下单用户
*/
@TableField(exist = false)
private User user;
/**
* 业主用户
*/
@TableField(exist = false)
private User ownerUser;
}
================================================
FILE: src/main/java/com/example/sens/entity/Permission.java
================================================
package com.example.sens.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.example.sens.common.base.BaseEntity;
import lombok.Data;
import java.util.List;
/**
*
* 权限,后台的菜单
* @author example
*/
@Data
@TableName("permission")
public class Permission extends BaseEntity {
/**
* 权限名称
*/
private String name;
/**
* pid
*/
private Long pid;
/**
* 资源类型
*/
private String resourceType;
/**
* 请求URL
*/
private String url;
/**
* 图标
*/
private String icon;
/**
* 序号(越小越靠前)
*/
private Double sort;
/**
* 级别
*/
@TableField(exist = false)
private Integer level;
/**
* 子权限列表
*/
@TableField(exist = false)
private List childPermissions;
================================================
FILE: src/main/java/com/example/sens/entity/Post.java
================================================
package com.example.sens.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.example.sens.common.base.BaseEntity;
import lombok.Data;
/**
* @author example
*/
@Data
@TableName("post")
public class Post extends BaseEntity {
/**
* 用户ID
*/
private Long userId;
/**
* 房屋标题
*/
private String postTitle;
/**
* 房屋描述
*/
private String postContent;
/**
* 房屋摘要
*/
private String postSummary;
/**
* 缩略图
*/
private String postThumbnail;
/**
* 0 正在出租
* 1 已经租出去
* 2 已删除
*/
private Integer postStatus;
/**
* 月付价格
*/
private Integer price;
/**
* 房间编号
*/
private String number;
/**
* 分类ID
*/
private Long cateId;
/**
* 城市ID
*/
private Long cityId;
/**
* 图片URL
*/
private String imgUrl;
/**
* 富文本
*/
private String postEditor;
/**
* 面积
*/
private Double area;
/**
* 卧室数量
*/
private Integer roomCount;
/**
* 洗手间数量
*/
private Integer toiletCount;
/**
* 押金
*/
private Long deposit;
/**
* 房屋所属分类
*/
@TableField(exist = false)
private Category category;
/**
* 房屋所属城市
*/
@TableField(exist = false)
private City city;
/**
* 房屋业主
*/
@TableField(exist = false)
private User user;
/**
* 用于搜索
*/
@TableField(exist = false)
private Integer minArea;
/**
* 用于搜索
*/
@TableField(exist = false)
private Integer maxArea;
/**
* 用于搜索
*/
@TableField(exist = false)
private Integer minPrice;
/**
* 用于搜索
*/
@TableField(exist = false)
private Integer maxPrice;
================================================
FILE: src/main/java/com/example/sens/entity/RechargeRecord.java
================================================
package com.example.sens.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.example.sens.common.base.BaseEntity;
import lombok.Data;
/**
* @author 言曌
* @date 2020/3/22 3:15 下午
*/
@TableName("recharge_record")
@Data
public class RechargeRecord extends BaseEntity {
/**
* 用户ID
*/
private Long userId;
/**
* 金额
*/
private Long money;
/**
* 用户
*/
@TableField(exist = false)
private User user;
}
================================================
FILE: src/main/java/com/example/sens/entity/Role.java
================================================
package com.example.sens.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.example.sens.common.base.BaseEntity;
import lombok.Data;
import java.util.List;
/**
* @author example
*/
@Data
@TableName("role")
public class Role extends BaseEntity {
/**
* 角色名称:admin,author,subscriber
*/
private String role;
/**
* 描述:管理员,作者,订阅者
*/
private String description;
/**
* 级别
*/
private Integer level;
/**
* 用户注册默认角色
*/
private Integer isRegisterDefault;
/**
* 该角色对应的用户数量,非数据库字段
*/
@TableField(exist = false)
private Integer count;
/**
* 当前角色的权限列表
*/
@TableField(exist = false)
private List permissions;
================================================
FILE: src/main/java/com/example/sens/entity/RolePermissionRef.java
================================================
package com.example.sens.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.example.sens.common.base.BaseEntity;
import lombok.Data;
@Data
@TableName("role_permission_ref")
public class RolePermissionRef extends BaseEntity {
/**
* 角色Id
*/
private Long roleId;
/**
* 权限Id
*/
private Long permissionId;
public RolePermissionRef() {
}
public RolePermissionRef(Long roleId, Long permissionId) {
this.roleId = roleId;
this.permissionId = permissionId;
}
================================================
FILE: src/main/java/com/example/sens/entity/User.java
================================================
package com.example.sens.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.example.sens.common.base.BaseEntity;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import java.util.Date;
/**
* 用户信息
*/
@Data
@TableName("user")
public class User extends BaseEntity {
/**
* 账号
*/
private String userName;
/**
* 姓名称
*/
private String userDisplayName;
/**
* 密码
*/
@JsonIgnore
private String userPass;
/**
* 身份证号码
*/
private String idCard;
/**
* 头像
*/
private String userAvatar;
/**
* 说明
*/
private String userDesc;
/**
* 0 正常
* 1 禁用
* 2 已删除
*/
private Integer status = 0;
/**
* 创建时间
*/
private Date createTime;
/**
* 电子邮箱
*/
private String email;
/**
* 手机号
*/
private String phone;
/**
* 余额
*/
private Long money;
/**
* 角色名称
*/
@TableField(exist = false)
private Role role;
}
================================================
FILE: src/main/java/com/example/sens/entity/UserRoleRef.java
================================================
package com.example.sens.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.example.sens.common.base.BaseEntity;
import lombok.Data;
/**
* 用户和角色关联
* @author example
*/
@Data
@TableName("user_role_ref")
public class UserRoleRef extends BaseEntity {
/**
* 用户Id
*/
private Long userId;
/**
* 角色Id
*/
private Long roleId;
public UserRoleRef(Long userId, Long roleId) {
this.userId = userId;
this.roleId = roleId;
}
public UserRoleRef() {
}
================================================
FILE: src/main/java/com/example/sens/enums/CommonParamsEnum.java
================================================
package com.example.sens.enums;
/**
* 常用数字
*/
public enum CommonParamsEnum {
/**
* 数字10
*/
TEN(10),
/**
* 数字5
*/
FIVE(5),
/**
* 数字404
*/
NOT_FOUND(404),
/**
* 数字1024
*/
BYTE(1024);
private Integer value;
CommonParamsEnum(Integer value) {
this.value = value;
}
public Integer getValue() {
return value;
}
}
================================================
FILE: src/main/java/com/example/sens/enums/OrderStatusEnum.java
================================================
package com.example.sens.enums;
/**
*
* 订单状态enum
*
*/
public enum OrderStatusEnum {
/**
* 待支付
*/
NOT_PAY(0),
/**
* 已支付
*/
HAS_PAY(1),
/**
* 已完结
*/
FINISHED(2),
/**
* 已关闭,已取消
*/
CLOSED(3),
/**
* 押金退回失败
*/
DEPOSIT_RETURN_FAIL(4)
;
private Integer code;
OrderStatusEnum(Integer code) {
this.code = code;
}
public Integer getCode() {
return code;
}
}
================================================
FILE: src/main/java/com/example/sens/enums/PostIsRecommendEnum.java
================================================
package com.example.sens.enums;
/**
* 房屋推荐枚举
*/
public enum PostIsRecommendEnum {
/**
* 真
*/
TRUE(1),
/**
* 假
*/
FALSE(0);
private Integer value;
PostIsRecommendEnum(Integer value) {
this.value = value;
}
public Integer getValue() {
return value;
}
}
================================================
FILE: src/main/java/com/example/sens/enums/PostIsStickyEnum.java
================================================
package com.example.sens.enums;
/**
* 房屋置顶枚举
*/
public enum PostIsStickyEnum {
/**
* 真
*/
TRUE(1),
/**
* 假
*/
FALSE(0);
private Integer value;
PostIsStickyEnum(Integer value) {
this.value = value;
}
public Integer getValue() {
return value;
}
}
================================================
FILE: src/main/java/com/example/sens/enums/PostStatusEnum.java
================================================
package com.example.sens.enums;
/**
*
* 房屋状态enum
*
*
* @author : saysky
* @date : 2018/7/1
*/
public enum PostStatusEnum {
/**
* 正在出租
*/
ON_SALE(0),
/**
* 已出租
*/
OFF_SALE(1),
/**
* 已删除
*/
RECYCLE(2);
private Integer code;
PostStatusEnum(Integer code) {
this.code = code;
}
public Integer getCode() {
return code;
}
}
================================================
FILE: src/main/java/com/example/sens/enums/PostTypeEnum.java
================================================
package com.example.sens.enums;
/**
*
* 房屋类型enum
*
*
* @author : saysky
* @date : 2018/7/1
*/
public enum PostTypeEnum {
/**
* 房屋
*/
POST_TYPE_POST("post"),
/**
* 页面
*/
POST_TYPE_PAGE("page"),
/**
* 公告
*/
POST_TYPE_NOTICE("notice");
private String value;
PostTypeEnum(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
================================================
FILE: src/main/java/com/example/sens/enums/ResourceTypeEnum.java
================================================
package com.example.sens.enums;
/**
* 资源类型
*/
public enum ResourceTypeEnum {
/**
* 菜单
*/
MENU("menu", "菜单"),
/**
* 接口
*/
BUTTON("button", "接口"),
/**
* 菜单
*/
PAGE("page", "页面");
private String code;
private String description;
ResourceTypeEnum(String code, String description) {
this.code = code;
this.description = description;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
================================================
FILE: src/main/java/com/example/sens/enums/ResultCodeEnum.java
================================================
package com.example.sens.enums;
/**
* 返回结果enum
*/
public enum ResultCodeEnum {
/**
* 成功
*/
SUCCESS(1),
/**
* 失败
*/
FAIL(0);
Integer code;
ResultCodeEnum(Integer code) {
this.code = code;
}
public Integer getCode() {
return code;
}
}
================================================
FILE: src/main/java/com/example/sens/enums/RoleEnum.java
================================================
package com.example.sens.enums;
/**
*
* 角色枚举
*
*
*/
public enum RoleEnum {
/**
* 管理员
*/
ADMIN("admin"),
/**
* 用户
*/
USER("user");
private String value;
RoleEnum(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
================================================
FILE: src/main/java/com/example/sens/enums/TrueFalseEnum.java
================================================
package com.example.sens.enums;
/**
* true or false enum
*/
public enum TrueFalseEnum {
/**
* 真
*/
TRUE("true"),
/**
* 假
*/
FALSE("false");
private String value;
TrueFalseEnum(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
================================================
FILE: src/main/java/com/example/sens/enums/UserStatusEnum.java
================================================
package com.example.sens.enums;
/**
* 用户状态enum
*/
public enum UserStatusEnum {
/**
* 正常
*/
NORMAL(0),
/**
* 禁止登录
*/
BAN(1);
private Integer code;
UserStatusEnum(Integer code) {
this.code = code;
}
public Integer getCode() {
return code;
}
}
================================================
FILE: src/main/java/com/example/sens/exception/GlobalExceptionHandler.java
================================================
package com.example.sens.exception;
import com.example.sens.dto.JsonResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.ui.Model;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* 全局异常捕获
*/
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
//错误显示页面
public static final String viewName = "common/error/error";
/**
* 是否是ajax请求
*/
public static boolean isAjax(HttpServletRequest httpRequest) {
return (httpRequest.getHeader("X-Requested-With") != null
&& "XMLHttpRequest"
.equals(httpRequest.getHeader("X-Requested-With").toString()));
}
/**
* 400 - Bad Request
*/
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MissingServletRequestParameterException.class)
public String handleMissingServletRequestParameterException(MissingServletRequestParameterException e, Model model) {
log.error("缺少请求参数", e);
String message = "【缺少请求参数】" + e.getMessage();
model.addAttribute("message", message);
model.addAttribute("code", 400);
return viewName;
}
/**
* 400 - Bad Request
*/
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(HttpMessageNotReadableException.class)
public String handleHttpMessageNotReadableException(HttpMessageNotReadableException e, Model model) {
log.error("参数解析失败", e);
String message = "【参数解析失败】" + e.getMessage();
model.addAttribute("message", message);
model.addAttribute("code", 400);
return viewName;
}
/**
* 400 - Bad Request
*/
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentNotValidException.class)
public String handleMethodArgumentNotValidException(MethodArgumentNotValidException e, Model model) {
log.error("参数验证失败", e);
BindingResult result = e.getBindingResult();
FieldError error = result.getFieldError();
String field = error.getField();
String code = error.getDefaultMessage();
String message = "【参数验证失败】" + String.format("%s:%s", field, code);
model.addAttribute("message", message);
model.addAttribute("code", 400);
return viewName;
}
/**
* 400 - Bad Request
*/
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(BindException.class)
public String handleBindException(BindException e, Model model) {
log.error("参数绑定失败", e);
BindingResult result = e.getBindingResult();
FieldError error = result.getFieldError();
String field = error.getField();
String code = error.getDefaultMessage();
String message = "【参数绑定失败】" + String.format("%s:%s", field, code);
model.addAttribute("message", message);
model.addAttribute("code", 400);
return viewName;
}
/**
* 400 - Bad Request
*/
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(ConstraintViolationException.class)
public String handleServiceException(ConstraintViolationException e, Model model) {
log.error("参数验证失败", e);
Set> violations = e.getConstraintViolations();
ConstraintViolation> violation = violations.iterator().next();
String message = "【参数验证失败】" + violation.getMessage();
model.addAttribute("message", message);
model.addAttribute("code", 400);
return viewName;
}
/**
* 400 - Bad Request
*/
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(ValidationException.class)
public String handleValidationException(ValidationException e, Model model) {
log.error("参数验证失败", e);
String message = "【参数验证失败】" + e.getMessage();
model.addAttribute("message", message);
model.addAttribute("code", 400);
return viewName;
}
/**
* 404 - Not Found
*/
@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler(NoHandlerFoundException.class)
public String noHandlerFoundException(NoHandlerFoundException e, Model model) {
log.error("Not Found", e);
String message = "【页面不存在】" + e.getMessage();
model.addAttribute("message", message);
model.addAttribute("code", 404);
return viewName;
}
/**
* 405 - Method Not Allowed
*/
@ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
public String handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e, Model model) {
log.error("不支持当前请求方法", e);
String message = "【不支持当前请求方法】" + e.getMessage();
model.addAttribute("message", message);
model.addAttribute("code", 405);
return viewName;
}
/**
* 415 - Unsupported Media Type
*/
@ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
@ExceptionHandler(HttpMediaTypeNotSupportedException.class)
public String handleHttpMediaTypeNotSupportedException(HttpMediaTypeNotSupportedException e, Model model) {
log.error("不支持当前媒体类型", e);
String message = "【不支持当前媒体类型】" + e.getMessage();
model.addAttribute("message", message);
model.addAttribute("code", 415);
return viewName;
}
/**
* 统一异常处理
*
* @param response
* @param e
* @return
*/
@ExceptionHandler(MyBusinessException.class)
@ResponseBody
public JsonResult processApiException(HttpServletResponse response,
MyBusinessException e) {
JsonResult result = new JsonResult(0, e.getMessage());
response.setStatus(200);
response.setContentType("application/json;charset=UTF-8");
log.error("业务异常,提示前端操作不合法", e.getMessage(), e);
return result;
}
/**
* 获取其它异常。包括500
*
* @param e
* @return
* @throws Exception
*/
@ExceptionHandler(value = Exception.class)
public ModelAndView defaultErrorHandler(HttpServletRequest request,
HttpServletResponse response,
Exception e, Model model) throws IOException {
e.printStackTrace();
if (isAjax(request)) {
ModelAndView mav = new ModelAndView();
MappingJackson2JsonView view = new MappingJackson2JsonView();
Map attributes = new HashMap();
if (e instanceof UnauthorizedException) {
attributes.put("msg", "没有权限");
} else {
attributes.put("msg", e.getMessage());
}
attributes.put("code", "0");
view.setAttributesMap(attributes);
mav.setView(view);
return mav;
}
if (e instanceof UnauthorizedException) {
//请登录
log.error("无权访问", e);
return new ModelAndView("common/error/403");
}
//其他异常
String message = e.getMessage();
model.addAttribute("code", 500);
model.addAttribute("message", message);
return new ModelAndView("common/error/500");
}
}
================================================
FILE: src/main/java/com/example/sens/exception/MyBusinessException.java
================================================
package com.example.sens.exception;
/**
* @author 言曌
* @date 2019-08-09 16:47
*/
public class MyBusinessException extends RuntimeException {
private Integer code;
private String message;
public MyBusinessException() {
super();
}
public MyBusinessException(String message) {
this.code = 500;
this.message = message;
}
public MyBusinessException(Integer code, String message) {
this.code = code;
this.message = message;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
@Override
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
================================================
FILE: src/main/java/com/example/sens/mapper/CategoryMapper.java
================================================
package com.example.sens.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.sens.entity.Category;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author liuyanzhao
*/
@Mapper
public interface CategoryMapper extends BaseMapper {
/**
* 获得子分类Id列表
*
* @param pathTrace /138/ 这种格式
* @return 子分类Id列表
*/
List selectChildCateIds(@Param("pathTrace") String pathTrace);
/**
* 根据用户ID删除
* @param userId
* @return
*/
Integer deleteByUserId(Long userId);
/**
* 获取所有分类
* @return
*/
List findAllWithCount();
}
================================================
FILE: src/main/java/com/example/sens/mapper/CityMapper.java
================================================
package com.example.sens.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.sens.entity.City;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* @author liuyanzhao
*/
@Mapper
public interface CityMapper extends BaseMapper {
/**
* 获取所有城市
* @return
*/
List findAllWithCount();
}
================================================
FILE: src/main/java/com/example/sens/mapper/NoticeMapper.java
================================================
package com.example.sens.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.sens.entity.Notice;
import org.apache.ibatis.annotations.Mapper;
/**
* @author liuyanzhao
*/
@Mapper
public interface NoticeMapper extends BaseMapper {
}
================================================
FILE: src/main/java/com/example/sens/mapper/OrderMapper.java
================================================
package com.example.sens.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.sens.entity.Order;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author liuyanzhao
*/
@Mapper
public interface OrderMapper extends BaseMapper {
/**
* 根据条件查询订单
*
* @param condition
* @return
*/
List findAll(@Param("condition") Order condition, Page page);
/**
* 根据条件查询总金额
*
* @param condition
* @return
*/
Integer getTotalPriceSum(@Param("condition") Order condition);
/**
* 更新超时订单状态为超时
*
* @return
*/
Integer updateOverDueOrder();
/**
* 根据房屋ID删除
* @param postId
* @return
*/
Integer deleteByPostId(Long postId);
/**
* 获得到期的订单
* @return
*/
List findOverDueOrder();
/**
* 查询有效订单
* @param postId
* @return
*/
Order findByPostId(Long postId);
}
================================================
FILE: src/main/java/com/example/sens/mapper/PermissionMapper.java
================================================
package com.example.sens.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.sens.entity.Permission;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author example
*/
@Mapper
public interface PermissionMapper extends BaseMapper {
/**
* 根据角色Id获得权限列表
*
* @param roleId 角色Id
* @return 权限列表
*/
List findByRoleId(Long roleId);
/**
* 获得某个用户的权限列表
*
* @param userId
* @return
*/
List findPermissionByUserId(Long userId);
/**
* 获得某个用户的权限列表
*
* @param userId
* @param resourceType
* @return
*/
List findPermissionByUserIdAndResourceType(@Param("userId") Long userId,
@Param("resourceType") String resourceType);
/**
* 获得权限列表
*
* @param resourceType
* @return
*/
List findPermissionByResourceType(Integer resourceType);
/**
* 根据角色ID获得权限列表
* @param roleId
* @return
*/
List findPermissionByRoleId(Long roleId);
/**
* 统计子节点数量
* @param id
* @return
*/
Integer countChildPermission(Long id);
/**
* 根据URL获得权限
* @param url
* @return
*/
Permission findByUrl(String url);
}
================================================
FILE: src/main/java/com/example/sens/mapper/PostMapper.java
================================================
package com.example.sens.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.sens.common.constant.CommonConstant;
import com.example.sens.entity.Post;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author liuyanzhao
*/
@Mapper
public interface PostMapper extends BaseMapper {
/**
* 根据条件查询房屋
*
* @param condition
* @param page
* @return
*/
List findPostByCondition(@Param(CommonConstant.CONDITION) Post condition, Page page);
/**
* 根据租客用户ID查询
*
* @param userId
* @param page
* @return
*/
List findByRentUserId(@Param("userId") Long userId, Page page);
/**
* 统计该分类的房屋
*
* @param cateId
* @return
*/
Integer countPostByCateId(Long cateId);
/**
* 获得最新房屋
*
* @param cityId
* @param limit
* @return
*/
List getLatestPost(@Param("cityId") Long cityId, @Param("limit") Integer limit);
/**
* 根据状态统计
*
* @param postStatus 状态
* @return
*/
Integer countByStatus(Integer postStatus);
/**
* 获得合租房屋
*
* @return
*/
List getUnionRentPost(Post post);
}
================================================
FILE: src/main/java/com/example/sens/mapper/RechargeRecordMapper.java
================================================
package com.example.sens.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.sens.entity.RechargeRecord;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author example
*/
@Mapper
public interface RechargeRecordMapper extends BaseMapper {
/**
* 删除用户和预定关联
*
* @param userId 用户ID
* @return 影响行数
*/
Integer deleteByUserId(Long userId);
/**
* 查询所有充值记录
*
* @return
*/
List findAll(@Param("startDate") String startDate,
@Param("endDate") String endDate,
Page page);
/**
* 获得该用户的充值记录
*
* @return
*/
List findByUserId(@Param("startDate") String startDate,
@Param("endDate") String endDate,
@Param("userId") Long userId, Page page);
/**
* 根据时间范围查询总金额
*
* @param startDate
* @param endDate
* @return
*/
Integer getTotalMoneySum(@Param("startDate") String startDate,
@Param("endDate") String endDate);
}
================================================
FILE: src/main/java/com/example/sens/mapper/RoleMapper.java
================================================
package com.example.sens.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.sens.entity.Role;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* @author example
*/
@Mapper
public interface RoleMapper extends BaseMapper {
/**
* 根据用户Id获得角色
*
* @param userId 用户Id
* @return 角色列表
*/
Role findByUserId(Long userId);
/**
* 删除用户和角色管理
*
* @param userId 用户ID
* @return 影响行数
*/
Integer deleteByUserId(Long userId);
/**
* 统计某个角色的用户数
*
* @param roleId 角色Id
* @return 用户数
*/
Integer countUserByRoleId(Long roleId);
/**
* 获得所有角色和对应用户数量
* @return
*/
List findAllWithCount();
/**
* 查询小于等于该等级的角色
* @param level
* @return
*/
List findByLessThanLevel(Integer level);
/**
* 查询某个用户最大的角色等级
* @param userId
* @return
*/
Integer findMaxLevelByUserId(Long userId);
/**
* 获得用户注册默认角色
* @return
*/
Role findDefaultRole();
}
================================================
FILE: src/main/java/com/example/sens/mapper/RolePermissionRefMapper.java
================================================
package com.example.sens.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.sens.entity.RolePermissionRef;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* @author example
*/
@Mapper
public interface RolePermissionRefMapper extends BaseMapper {
/**
* 根据角色Id删除
*
* @param roleId 角色Id
* @return 影响行数
*/
Integer deleteByRoleId(Long roleId);
/**
* 根据权限Id删除
*
* @param permissionId 权限Id
* @return 影响行数
*/
Integer deleteByPermissionId(Long permissionId);
/**
* 批量添加
*
* @param rolePermissionRefList 列表
* @return 影响喊你高数
*/
Integer batchInsert(List rolePermissionRefList);
}
================================================
FILE: src/main/java/com/example/sens/mapper/UserMapper.java
================================================
package com.example.sens.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.sens.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author example
*/
@Mapper
public interface UserMapper extends BaseMapper {
/**
* 根据角色Id获得用户
*
* @param roleId 角色Id
* @param page 分页信息
* @return 用户列表
*/
List findByRoleId(@Param("roleId") Long roleId, Page page);
/**
* 根据角色Id和条件获得用户
*
* @param roleId 角色Id
* @param user 条件
* @param page 分页信息
* @return 用户列表
*/
List findByRoleIdAndCondition(@Param("roleId") Long roleId,
@Param("user") User user, Page page);
/**
* 根据条件查询
*
* @param user 用户
* @param page 分页
* @return 用户列表
*/
List findByCondition( @Param("user") User user, Page page);
/**
* 获得今日新增数量
* @return
*/
Integer getTodayCount();
/**
* 获得用户房屋数排名
* @param limit 查询数量
* @return
*/
List getUserPostRanking(Integer limit);
/**
* 获得最新注册用户
* @param limit
* @return
*/
List getLatestUser(Integer limit);
/**
* 获得热门用户
* @param limit 用户数量
* @return
*/
List getHotUsers(Integer limit);
}
================================================
FILE: src/main/java/com/example/sens/mapper/UserRoleRefMapper.java
================================================
package com.example.sens.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.sens.entity.UserRoleRef;
import org.apache.ibatis.annotations.Mapper;
/**
* @author example
*/
@Mapper
public interface UserRoleRefMapper extends BaseMapper {
/**
* 根据用户Id删除
*
* @param userId 用户Id
* @return 影响行数
*/
Integer deleteByUserId(Long userId);
}
================================================
FILE: src/main/java/com/example/sens/service/CategoryService.java
================================================
package com.example.sens.service;
import com.example.sens.common.base.BaseService;
import com.example.sens.entity.Category;
import java.util.List;
/**
*
* 分类业务逻辑接口
*
*
* @author : saysky
* @date : 2019/11/30
*/
public interface CategoryService extends BaseService {
/**
* 查询所有分类目录,带count和根据level封装name
*
* @return 返回List集合
*/
List findByUserId(Long userId);
/**
* 获得某个分类的所有房屋数
*
* @param cateId 分类Id
* @return 房屋数
*/
Integer countPostByCateId(Long cateId);
/**
* 根据用户ID删除
*
* @param userId
* @return
*/
Integer deleteByUserId(Long userId);
/**
* 将分类ID列表转成分类
*
* @param cateIds
* @param userId
* @return
*/
List cateIdsToCateList(List cateIds, Long userId);
}
================================================
FILE: src/main/java/com/example/sens/service/CityService.java
================================================
package com.example.sens.service;
import com.example.sens.common.base.BaseService;
import com.example.sens.entity.City;
public interface CityService extends BaseService {
}
================================================
FILE: src/main/java/com/example/sens/service/MailService.java
================================================
package com.example.sens.service;
import javax.mail.MessagingException;
/**
*
* 邮件发送业务逻辑接口
*
*/
public interface MailService {
/**
* 发送邮件
*
* @param to 接收者
* @param title 标题
* @param content 内容
*/
void sendMail(String to, String title, String content) throws MessagingException;
}
================================================
FILE: src/main/java/com/example/sens/service/NoticeService.java
================================================
package com.example.sens.service;
import com.example.sens.common.base.BaseService;
import com.example.sens.entity.Notice;
public interface NoticeService extends BaseService {
}
================================================
FILE: src/main/java/com/example/sens/service/OrderService.java
================================================
package com.example.sens.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.sens.common.base.BaseService;
import com.example.sens.entity.Order;
/**
* 订单
*
* @author 言曌
* @date 2020/4/6 2:00 下午
*/
public interface OrderService extends BaseService {
/**
* 查询总金额
*
* @return
*/
Integer getTotalPriceSum(Order condition);
/**
* 根据条件查询
*
* @param condition
* @param page
* @return
*/
Page findAll(Order condition, Page page);
/**
* 查询有效订单
* @param postId
* @return
*/
Order findByPostId(Long postId);
}
================================================
FILE: src/main/java/com/example/sens/service/PermissionService.java
================================================
package com.example.sens.service;
import com.example.sens.entity.Permission;
import com.example.sens.common.base.BaseService;
import java.util.List;
import java.util.Set;
/**
* 权限逻辑接口
*/
public interface PermissionService extends BaseService {
/**
* 根据角色Id获得权限列表
*
* @param roleId 角色Id
* @return 权限列表
*/
List listPermissionsByRoleId(Long roleId);
/**
* 获得某个用户的权限URL列表
*
* @param userId
* @return
*/
Set findPermissionUrlsByUserId(Long userId);
/**
* 获得某个用户的用户ID和资源类型
*
* @param userId
* @param resourceType
* @return
*/
List findPermissionTreeByUserIdAndResourceType(Long userId, String resourceType);
/**
* 根据角色ID获得权限列表
* @param roleId
* @return
*/
List findPermissionByRoleId(Long roleId);
/**
* 获得所有权限,带有等级
* @return
*/
List findPermissionListWithLevel();
/**
* 统计子节点数量
* @param id
* @return
*/
Integer countChildPermission(Long id);
/**
* 根据URL获得权限
* @param url
* @return
*/
Permission findByUrl(String url);
}
================================================
FILE: src/main/java/com/example/sens/service/PostService.java
================================================
package com.example.sens.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.sens.common.base.BaseService;
import com.example.sens.entity.Post;
import java.util.List;
/**
*
* 记录/页面业务逻辑接口
*
*/
public interface PostService extends BaseService {
/**
* 根据条件获得列表
*
* @param condition
* @return
*/
Page findPostByCondition(Post condition, Page page);
/**
* 根据租客userId查询
*
* @param userId
* @return
*/
Page findByRentUserId(Long userId, Page page);
/**
* 获得最新房屋
*
* @param cityId
* @param limit
* @return
*/
List getLatestPost(Long cityId, int limit);
/**
* 根据状态统计
*
* @param postStatus 状态
* @return
*/
Integer countByStatus(Integer postStatus);
/**
* 获得合租房屋
*
* @return
*/
List getUnionRentPost(Post post);
}
================================================
FILE: src/main/java/com/example/sens/service/RechargeRecordService.java
================================================
package com.example.sens.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.sens.common.base.BaseService;
import com.example.sens.entity.RechargeRecord;
/**
* @author 言曌
* @date 2020/3/22 3:18 下午
*/
public interface RechargeRecordService extends BaseService {
Page findAll(String startDate, String endDate, Page page);
/**
* 根据用户ID获得预定列表
*
* @param userId
* @param page
* @return
*/
Page findByUserId(String startDate, String endDate, Long userId, Page page);
/**
* 根据时间范围查询总金额
*
* @param startDate
* @param endDate
* @return
*/
Integer getTotalMoneySum(String startDate, String endDate);
}
================================================
FILE: src/main/java/com/example/sens/service/RolePermissionRefService.java
================================================
package com.example.sens.service;
import com.example.sens.entity.RolePermissionRef;
import java.util.List;
public interface RolePermissionRefService {
/**
* 删除某个角色的所有关联
*
* @param roleId 角色Id
*/
void deleteRefByRoleId(Long roleId);
/**
* 添加角色和权限关联
*
* @param rolePermissionRef RolePermissionRef
* @return UserRoleRef
*/
void saveByRolePermissionRef(RolePermissionRef rolePermissionRef);
/**
* 批量添加
*
* @param rolePermissionRefs 列表
*/
void batchSaveByRolePermissionRef(List rolePermissionRefs);
}
================================================
FILE: src/main/java/com/example/sens/service/RoleService.java
================================================
package com.example.sens.service;
import com.example.sens.entity.Role;
import com.example.sens.common.base.BaseService;
import java.util.List;
/**
* 角色逻辑接口
*/
public interface RoleService extends BaseService {
/**
* 删除某个用户的所有关联
*
* @param userId 用户Id
*/
void deleteByUserId(Long userId);
/**
* 根据编号查询单个权限
*
* @param roleId roleId
* @return Role
*/
Role findByRoleId(Long roleId);
/**
* 根据编号查询单个权限
*
* @param roleName roleName
* @return Role
*/
Role findByRoleName(String roleName);
/**
* 根据用户Id获得角色
*
* @param userId 用户Id
* @return 角色列表
*/
Role findByUserId(Long userId);
/**
* 统计这个角色的用户数
*
* @param roleId 角色Id
*/
Integer countUserByRoleId(Long roleId);
/**
* 查询某个用户最大的角色等级
* @param userId
* @return
*/
Integer findMaxLevelByUserId(Long userId);
/**
* 查询小于等于该等级的角色
* @param level
* @return
*/
List findByLessThanLevel(Integer level);
/**
* 获得用户注册默认角色
* @return
*/
Role findDefaultRole();
/**
* 获得用户注册默认角色
* @return
*/
Role getMaxRoleByUserId(Long userId);
}
================================================
FILE: src/main/java/com/example/sens/service/UserRoleRefService.java
================================================
package com.example.sens.service;
import com.example.sens.entity.UserRoleRef;
import com.example.sens.common.base.BaseService;
public interface UserRoleRefService extends BaseService {
/**
* 根据用户Id删除
*
* @param userId 用户Id
*/
void deleteByUserId(Long userId);
}
================================================
FILE: src/main/java/com/example/sens/service/UserService.java
================================================
package com.example.sens.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.sens.common.base.BaseService;
import com.example.sens.entity.User;
/**
* 用户业务逻辑接口
*/
public interface UserService extends BaseService {
/**
* 根据账号获得用户
*
* @param userName 账号
* @return 用户
*/
User findByUserName(String userName);
/**
* 根据身份证号码查找用户
*
* @param idCard 身份证号码
* @return User
*/
User findByIdCard(String idCard);
/**
* 更新密码
*
* @param userId 用户Id
* @param password 密码
*/
void updatePassword(Long userId, String password);
/**
* 分页获取所有用户
*
* @param roleName 角色名称
* @param condition 查询条件
* @param page 分页信息
* @return 用户列表
*/
Page findByRoleAndCondition(String roleName, User condition, Page page);
}
================================================
FILE: src/main/java/com/example/sens/service/impl/CategoryServiceImpl.java
================================================
package com.example.sens.service.impl;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.sens.entity.Category;
import com.example.sens.mapper.CategoryMapper;
import com.example.sens.mapper.PostMapper;
import com.example.sens.service.CategoryService;
import com.example.sens.service.PostService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
*
* 分类业务逻辑实现类
*
*
*/
@Service
public class CategoryServiceImpl implements CategoryService {
@Autowired
private CategoryMapper categoryMapper;
@Autowired
private PostMapper postMapper;
@Autowired
private PostService postService;
@Override
public BaseMapper getRepository() {
return categoryMapper;
}
@Override
public QueryWrapper getQueryWrapper(Category category) {
//对指定字段查询
QueryWrapper queryWrapper = new QueryWrapper<>();
if (category != null) {
if (StrUtil.isNotBlank(category.getCateName())) {
queryWrapper.like("cate_name", category.getCateName());
}
}
return queryWrapper;
}
@Override
public Category insert(Category category) {
categoryMapper.insert(category);
return category;
}
@Override
public Category update(Category category) {
categoryMapper.updateById(category);
return category;
}
@Override
public void delete(Long id) {
// 删除分类
categoryMapper.deleteById(id);
}
@Override
public List findByUserId(Long userId) {
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("user_id", userId);
return categoryMapper.selectList(queryWrapper);
}
@Override
public Integer countPostByCateId(Long cateId) {
return postMapper.countPostByCateId(cateId);
}
@Override
public Category insertOrUpdate(Category entity) {
if (entity.getId() == null) {
insert(entity);
} else {
update(entity);
}
return entity;
}
@Override
public Integer deleteByUserId(Long userId) {
return categoryMapper.deleteByUserId(userId);
}
@Override
public List cateIdsToCateList(List cateIds, Long userId) {
List categoryList = this.findByUserId(userId);
List allCateIds = categoryList.stream().map(Category::getId).collect(Collectors.toList());
List result = new ArrayList<>();
for(Long id : cateIds) {
if(allCateIds.contains(id)) {
Category category = new Category();
category.setId(id);
result.add(category);
}
}
return result;
}
@Override
public List findAll() {
return categoryMapper.findAllWithCount();
}
}
================================================
FILE: src/main/java/com/example/sens/service/impl/CityServiceImpl.java
================================================
package com.example.sens.service.impl;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.sens.entity.City;
import com.example.sens.mapper.CityMapper;
import com.example.sens.service.CityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
*
* 城市业务服务实现类
*
*/
@Service
public class CityServiceImpl implements CityService {
@Autowired
private CityMapper cityMapper;
@Override
public BaseMapper getRepository() {
return cityMapper;
}
@Override
public QueryWrapper getQueryWrapper(City city) {
//对指定字段查询
QueryWrapper queryWrapper = new QueryWrapper<>();
if (city != null) {
if (StrUtil.isNotBlank(city.getCityName())) {
queryWrapper.like("city_name", city.getCityName());
}
}
return queryWrapper;
}
@Override
public List findAll() {
return cityMapper.findAllWithCount();
}
}
================================================
FILE: src/main/java/com/example/sens/service/impl/MailServiceImpl.java
================================================
package com.example.sens.service.impl;
import com.example.sens.service.MailService;
import com.example.sens.util.SensUtils;
import io.github.biezhi.ome.OhMyEmail;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.mail.MessagingException;
/**
*
* 邮件发送业务逻辑实现类
*
*
* @author : saysky
* @date : 2018/1/23
*/
@Service
public class MailServiceImpl implements MailService {
@Value("${mail.smtp.host}")
private String host;
@Value("${mail.smtp.username}")
private String username;
@Value("${mail.smtp.password}")
private String password;
@Value("${mail.from.name}")
private String fromName;
/**
* 发送邮件
*
* @param to to 接收者
* @param title subject 标题
* @param content content 内容
*/
@Override
public void sendMail(String to, String title, String content) throws MessagingException {
//配置邮件服务器
SensUtils.configMail(host, username, password);
OhMyEmail.subject(title)
.from(fromName)
.to(to)
.text(content)
.send();
}
}
================================================
FILE: src/main/java/com/example/sens/service/impl/NoticeServiceImpl.java
================================================
package com.example.sens.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.sens.entity.Notice;
import com.example.sens.mapper.NoticeMapper;
import com.example.sens.service.NoticeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
*
* 城市业务服务实现类
*
*/
@Service
public class NoticeServiceImpl implements NoticeService {
@Autowired
private NoticeMapper noticeMapper;
@Override
public BaseMapper getRepository() {
return noticeMapper;
}
@Override
public QueryWrapper getQueryWrapper(Notice notice) {
//对指定字段查询
QueryWrapper queryWrapper = new QueryWrapper<>();
return queryWrapper;
}
}
================================================
FILE: src/main/java/com/example/sens/service/impl/OrderServiceImpl.java
================================================
package com.example.sens.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.sens.entity.Order;
import com.example.sens.mapper.OrderMapper;
import com.example.sens.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author 言曌
* @date 2020/4/6 2:01 下午
*/
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private OrderMapper orderMapper;
@Override
public BaseMapper getRepository() {
return orderMapper;
}
@Override
public QueryWrapper getQueryWrapper(Order order) {
//对指定字段查询
QueryWrapper queryWrapper = new QueryWrapper<>();
if (order != null) {
if (order.getUserId() != null) {
queryWrapper.eq("user_id", order.getUserId());
}
if (order.getOwnerUserId() != null) {
queryWrapper.eq("owner_user_id", order.getOwnerUserId());
}
if (order.getPostId() != null) {
queryWrapper.eq("post_id", order.getPostId());
}
if (order.getStatus() != null) {
queryWrapper.eq("status", order.getStatus());
}
if (order.getStartDate() != null) {
queryWrapper.eq("start_date", order.getStartDate());
}
if (order.getEndDate() != null) {
queryWrapper.eq("end_date", order.getEndDate());
}
}
return queryWrapper;
}
@Override
public Integer getTotalPriceSum(Order condition) {
return orderMapper.getTotalPriceSum(condition);
}
@Override
public Page findAll(Order condition, Page page) {
return page.setRecords(orderMapper.findAll(condition, page));
}
@Override
public Order findByPostId(Long postId) {
return orderMapper.findByPostId(postId);
}
}
================================================
FILE: src/main/java/com/example/sens/service/impl/PermissionServiceImpl.java
================================================
package com.example.sens.service.impl;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.sens.entity.Permission;
import com.example.sens.mapper.PermissionMapper;
import com.example.sens.mapper.RolePermissionRefMapper;
import com.example.sens.service.PermissionService;
import com.example.sens.util.PermissionUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 角色业务逻辑实现类
*/
@Service
public class PermissionServiceImpl implements PermissionService {
@Autowired
private PermissionMapper permissionMapper;
@Autowired
private RolePermissionRefMapper rolePermissionRefMapper;
@Override
public List listPermissionsByRoleId(Long roleId) {
return permissionMapper.findByRoleId(roleId);
}
@Override
public Set findPermissionUrlsByUserId(Long userId) {
List permissions = permissionMapper.findPermissionByUserId(userId);
Set urls = permissions.stream().map(p -> p.getUrl()).collect(Collectors.toSet());
return urls;
}
@Override
public List findPermissionTreeByUserIdAndResourceType(Long userId, String resourceType) {
List permissions = permissionMapper.findPermissionByUserIdAndResourceType(userId, resourceType);
return PermissionUtil.getPermissionTree(permissions);
}
@Override
public List findPermissionByRoleId(Long roleId) {
return permissionMapper.findPermissionByRoleId(roleId);
}
@Override
public BaseMapper getRepository() {
return permissionMapper;
}
@Override
public QueryWrapper getQueryWrapper(Permission permission) {
//对指定字段查询
QueryWrapper queryWrapper = new QueryWrapper<>();
if (permission != null) {
if (StrUtil.isNotBlank(permission.getResourceType())) {
queryWrapper.eq("resource_type", permission.getResourceType());
}
if (StrUtil.isNotBlank(permission.getResourceType())) {
queryWrapper.eq("resource_type", permission.getResourceType());
}
if (StrUtil.isNotBlank(permission.getUrl())) {
queryWrapper.eq("url", permission.getUrl());
}
if (StrUtil.isNotBlank(permission.getName())) {
queryWrapper.eq("name", permission.getName());
}
}
return queryWrapper;
}
@Override
public Permission insertOrUpdate(Permission entity) {
if (entity.getId() == null) {
insert(entity);
} else {
update(entity);
}
return entity;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void delete(Long id) {
permissionMapper.deleteById(id);
rolePermissionRefMapper.deleteByPermissionId(id);
}
@Override
public List findPermissionListWithLevel() {
List permissionList = permissionMapper.selectList(null);
permissionList = PermissionUtil.getPermissionList(permissionList);
// 加空格以展示等级
for (Permission permission : permissionList) {
for (int i = 1; i < permission.getLevel(); i++) {
permission.setName(" "+permission.getName());
}
}
return permissionList;
}
@Override
public Integer countChildPermission(Long id) {
return permissionMapper.countChildPermission(id);
}
@Override
public Permission findByUrl(String url) {
return permissionMapper.findByUrl(url);
}
}
================================================
FILE: src/main/java/com/example/sens/service/impl/PostServiceImpl.java
================================================
package com.example.sens.service.impl;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.sens.entity.*;
import com.example.sens.mapper.*;
import com.example.sens.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
*
* 房屋业务逻辑实现类
*
*/
@Service
@Slf4j
public class PostServiceImpl implements PostService {
@Autowired
private PostMapper postMapper;
@Override
public Page findPostByCondition(Post condition, Page page) {
List postList = postMapper.findPostByCondition(condition, page);
return page.setRecords(postList);
}
@Override
public Page findByRentUserId(Long userId, Page page) {
List postList = postMapper.findByRentUserId(userId, page);
return page.setRecords(postList);
}
@Override
public BaseMapper getRepository() {
return postMapper;
}
@Override
public Post insert(Post post) {
postMapper.insert(post);
return post;
}
@Override
public Post update(Post post) {
postMapper.updateById(post);
return post;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void delete(Long postId) {
postMapper.deleteById(postId);
}
@Override
public QueryWrapper getQueryWrapper(Post post) {
//对指定字段查询
QueryWrapper queryWrapper = new QueryWrapper<>();
if (post != null) {
if (StrUtil.isNotBlank(post.getPostTitle())) {
queryWrapper.like("post_title", post.getPostTitle());
}
if (StrUtil.isNotBlank(post.getPostContent())) {
queryWrapper.like("post_content", post.getPostContent());
}
if (post.getPostStatus() != null && post.getPostStatus() != -1) {
queryWrapper.eq("post_status", post.getPostStatus());
}
}
return queryWrapper;
}
@Override
public Post insertOrUpdate(Post post) {
if (post.getId() == null) {
insert(post);
} else {
update(post);
}
return post;
}
@Override
public List getLatestPost(Long cityId, int limit) {
return postMapper.getLatestPost(cityId, limit);
}
@Override
public Integer countByStatus(Integer postStatus) {
return postMapper.countByStatus(postStatus);
}
@Override
public List getUnionRentPost(Post post) {
Post temp = new Post();
temp.setNumber(post.getNumber());
temp.setUserId(post.getUserId());
temp.setPostTitle(post.getPostTitle());
temp.setCityId(post.getCityId());
if (temp.getNumber() != null && temp.getNumber().length() > 2) {
if (temp.getNumber().indexOf("室") != -1) {
temp.setNumber(temp.getNumber().substring(0, temp.getNumber().indexOf("室") + 1));
}
}
return postMapper.getUnionRentPost(temp);
}
}
================================================
FILE: src/main/java/com/example/sens/service/impl/RechargeRecordServiceImpl.java
================================================
package com.example.sens.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.sens.entity.RechargeRecord;
import com.example.sens.mapper.RechargeRecordMapper;
import com.example.sens.service.RechargeRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author 言曌
* @date 2020/3/22 3:19 下午
*/
@Service
public class RechargeRecordServiceImpl implements RechargeRecordService {
@Autowired
private RechargeRecordMapper rechargeRecordMapper;
@Override
public BaseMapper getRepository() {
return rechargeRecordMapper;
}
@Override
public QueryWrapper getQueryWrapper(RechargeRecord rechargeRecord) {
//对指定字段查询
QueryWrapper queryWrapper = new QueryWrapper<>();
if (rechargeRecord != null) {
if (rechargeRecord.getUserId() != null) {
queryWrapper.eq("user_id", rechargeRecord.getUserId());
}
}
return queryWrapper;
}
@Override
public Page findAll(String startDate, String endDate, Page page) {
return page.setRecords(rechargeRecordMapper.findAll(startDate, endDate, page));
}
@Override
public Page findByUserId(String startDate, String endDate, Long userId, Page page) {
return page.setRecords(rechargeRecordMapper.findByUserId(startDate, endDate, userId, page));
}
@Override
public Integer getTotalMoneySum(String startDate, String endDate) {
return rechargeRecordMapper.getTotalMoneySum(startDate, endDate);
}
}
================================================
FILE: src/main/java/com/example/sens/service/impl/RolePermissionRefServiceImpl.java
================================================
package com.example.sens.service.impl;
import com.example.sens.entity.RolePermissionRef;
import com.example.sens.mapper.RolePermissionRefMapper;
import com.example.sens.service.RolePermissionRefService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class RolePermissionRefServiceImpl implements RolePermissionRefService {
@Autowired
private RolePermissionRefMapper rolePermissionRefMapper;
@Override
public void deleteRefByRoleId(Long roleId) {
rolePermissionRefMapper.deleteByRoleId(roleId);
}
@Override
public void saveByRolePermissionRef(RolePermissionRef rolePermissionRef) {
rolePermissionRefMapper.insert(rolePermissionRef);
}
@Override
public void batchSaveByRolePermissionRef(List rolePermissionRefs) {
rolePermissionRefMapper.batchInsert(rolePermissionRefs);
}
================================================
FILE: src/main/java/com/example/sens/service/impl/RoleServiceImpl.java
================================================
package com.example.sens.service.impl;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.sens.entity.Permission;
import com.example.sens.entity.Role;
import com.example.sens.entity.RolePermissionRef;
import com.example.sens.mapper.RoleMapper;
import com.example.sens.service.RolePermissionRefService;
import com.example.sens.service.RoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
/**
* 角色业务逻辑实现类
*/
@Service
public class RoleServiceImpl implements RoleService {
@Autowired
private RoleMapper roleMapper;
@Autowired
private RolePermissionRefService rolePermissionRefService;
@Override
public BaseMapper getRepository() {
return roleMapper;
}
@Override
public QueryWrapper getQueryWrapper(Role role) {
//对指定字段查询
QueryWrapper queryWrapper = new QueryWrapper<>();
if (role != null) {
if (StrUtil.isNotBlank(role.getRole())) {
queryWrapper.eq("role", role.getRole());
}
if (StrUtil.isNotBlank(role.getDescription())) {
queryWrapper.eq("description", role.getDescription());
}
}
return queryWrapper;
}
@Override
public void deleteByUserId(Long userId) {
roleMapper.deleteByUserId(userId);
}
@Override
public Role findByRoleId(Long roleId) {
return roleMapper.selectById(roleId);
}
@Override
public Role findByRoleName(String roleName) {
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("role", roleName);
return roleMapper.selectOne(queryWrapper);
}
@Override
public Role findByUserId(Long userId) {
return roleMapper.findByUserId(userId);
}
@Override
public Integer countUserByRoleId(Long roleId) {
return roleMapper.countUserByRoleId(roleId);
}
@Override
public Integer findMaxLevelByUserId(Long userId) {
return roleMapper.findMaxLevelByUserId(userId);
}
@Override
public List findByLessThanLevel(Integer level) {
return roleMapper.findByLessThanLevel(level);
}
@Override
public Role findDefaultRole() {
return roleMapper.findDefaultRole();
}
@Override
public Role getMaxRoleByUserId(Long userId) {
return null;
}
@Override
@Transactional(rollbackFor = Exception.class)
public Role insert(Role role) {
roleMapper.insert(role);
if (role.getPermissions() != null && role.getPermissions().size() > 0) {
List rolePermissionRefs = new ArrayList<>(role.getPermissions().size());
for (Permission permission : role.getPermissions()) {
rolePermissionRefs.add(new RolePermissionRef(role.getId(), permission.getId()));
}
rolePermissionRefService.batchSaveByRolePermissionRef(rolePermissionRefs);
}
return role;
}
@Override
@Transactional(rollbackFor = Exception.class)
public Role update(Role role) {
roleMapper.updateById(role);
if (role.getPermissions() != null && role.getPermissions().size() > 0) {
// 删除关联
rolePermissionRefService.deleteRefByRoleId(role.getId());
// 添加关联
List rolePermissionRefs = new ArrayList<>(role.getPermissions().size());
for (Permission permission : role.getPermissions()) {
rolePermissionRefs.add(new RolePermissionRef(role.getId(), permission.getId()));
}
rolePermissionRefService.batchSaveByRolePermissionRef(rolePermissionRefs);
}
return role;
}
@Override
public Role insertOrUpdate(Role entity) {
if (entity.getId() == null) {
insert(entity);
} else {
update(entity);
}
return entity;
}
}
================================================
FILE: src/main/java/com/example/sens/service/impl/UserRoleRefServiceImpl.java
================================================
package com.example.sens.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.sens.entity.UserRoleRef;
import com.example.sens.mapper.UserRoleRefMapper;
import com.example.sens.service.UserRoleRefService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserRoleRefServiceImpl implements UserRoleRefService {
@Autowired
private UserRoleRefMapper roleRefMapper;
@Override
public void deleteByUserId(Long userId) {
roleRefMapper.deleteByUserId(userId);
}
@Override
public BaseMapper getRepository() {
return roleRefMapper;
}
@Override
public QueryWrapper getQueryWrapper(UserRoleRef userRoleRef) {
//对指定字段查询
QueryWrapper queryWrapper = new QueryWrapper<>();
if (userRoleRef != null) {
if (userRoleRef.getUserId() != null) {
queryWrapper.eq("user_id", userRoleRef.getUserId());
}
if (userRoleRef.getRoleId() != null) {
queryWrapper.eq("role_id", userRoleRef.getRoleId());
}
}
return queryWrapper;
}
}
================================================
FILE: src/main/java/com/example/sens/service/impl/UserServiceImpl.java
================================================
package com.example.sens.service.impl;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.sens.exception.MyBusinessException;
import com.example.sens.common.constant.CommonConstant;
import com.example.sens.entity.Role;
import com.example.sens.mapper.OrderMapper;
import com.example.sens.mapper.RechargeRecordMapper;
import com.example.sens.mapper.UserMapper;
import com.example.sens.entity.User;
import com.example.sens.service.RoleService;
import com.example.sens.service.UserService;
import com.example.sens.util.Md5Util;
import com.example.sens.util.RegexUtil;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
/**
* 用户业务逻辑实现类
*/
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Autowired
private RoleService roleService;
@Autowired
private OrderMapper orderMapper;
@Autowired
private RechargeRecordMapper rechargeRecordMapper;
@Override
public User findByUserName(String userName) {
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("user_name", userName);
return userMapper.selectOne(queryWrapper);
}
@Override
public User findByIdCard(String idCard) {
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("id_card", idCard);
return userMapper.selectOne(queryWrapper);
}
@Override
public void updatePassword(Long userId, String password) {
User user = new User();
user.setId(userId);
user.setUserPass(Md5Util.toMd5(password, CommonConstant.PASSWORD_SALT, 10));
userMapper.updateById(user);
}
@Override
public Page findByRoleAndCondition(String roleName, User condition, Page page) {
List users = new ArrayList<>();
if (Objects.equals(roleName, CommonConstant.NONE)) {
users = userMapper.findByCondition(condition, page);
} else {
Role role = roleService.findByRoleName(roleName);
if (role != null) {
users = userMapper.findByRoleIdAndCondition(role.getId(), condition, page);
}
}
return page.setRecords(users);
}
@Override
public BaseMapper getRepository() {
return userMapper;
}
@Override
public QueryWrapper getQueryWrapper(User user) {
//对指定字段查询
QueryWrapper queryWrapper = new QueryWrapper<>();
if (user != null) {
if (StrUtil.isNotBlank(user.getUserName())) {
queryWrapper.eq("user_name", user.getUserName());
}
if (StrUtil.isNotBlank(user.getIdCard())) {
queryWrapper.eq("id_card", user.getIdCard());
}
}
return queryWrapper;
}
@Override
public User insert(User user) {
// 1.检查长度
basicCheck(user);
// 2.验证账号和身份证号码是否存在
checkUserNameAndIdCard(user);
// 3.添加
userMapper.insert(user);
return user;
}
@Override
public User update(User user) {
// 1.检查长度
basicCheck(user);
// 2.验证账号和身份证号码是否存在
checkUserNameAndIdCard(user);
// 3.更新
userMapper.updateById(user);
return user;
}
private void checkUserNameAndIdCard(User user) {
//验证账号和身份证号码是否存在
if (user.getUserName() != null) {
User nameCheck = findByUserName(user.getUserName());
Boolean isExist = (user.getId() == null && nameCheck != null) ||
(user.getId() != null && nameCheck != null && !Objects.equals(nameCheck.getId(), user.getId()));
if (isExist) {
throw new MyBusinessException("账号已经存在");
}
}
if (user.getIdCard() != null) {
User idCardCheck = findByIdCard(user.getIdCard());
Boolean isExist = (user.getId() == null && idCardCheck != null) ||
(user.getId() != null && idCardCheck != null && !Objects.equals(idCardCheck.getId(), user.getId()));
if (isExist) {
throw new MyBusinessException("身份证号码已经存在");
}
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void delete(Long userId) {
//删除用户
User user = get(userId);
if (user != null) {
// 1.修改用户状态为已删除
userMapper.deleteById(userId);
// 2.修改用户和角色关联
roleService.deleteByUserId(userId);
// 3.删除订单
Map map = new HashMap<>();
map.put("user_id", userId);
orderMapper.deleteByMap(map);
Map map2 = new HashMap<>();
map.put("owner_user_id", userId);
orderMapper.deleteByMap(map2);
// 4.删除充值记录
rechargeRecordMapper.deleteByUserId(userId);
}
}
@Override
public User insertOrUpdate(User user) {
if (user.getId() == null) {
user.setUserAvatar("/static/images/avatar/" + RandomUtils.nextInt(1, 41) + ".jpeg");
insert(user);
} else {
update(user);
}
return user;
}
private void basicCheck(User user) {
String userName = user.getUserName();
String idCard = user.getIdCard();
String userDisplayName = user.getUserDisplayName();
// 1.身份证号码是否合法
if (StringUtils.isNotEmpty(idCard) && !RegexUtil.isIdCard(idCard)) {
throw new MyBusinessException("身份证号码不合法,请输入15或18位");
}
// 2.账号码长度是否合法
if (StringUtils.isNotEmpty(userName) && userName.length() > 20 || userName.length() < 2) {
throw new MyBusinessException("账号不合法,请输入2-20位");
}
// 3.姓名长度是否合法
if (StringUtils.isNotEmpty(userDisplayName) && userDisplayName.length() > 20 || userDisplayName.length() < 2) {
throw new MyBusinessException("姓名长度不合法,请输入2-20位");
}
}
@Override
public User get(Long id) {
User user = userMapper.selectById(id);
return user;
}
}
================================================
FILE: src/main/java/com/example/sens/util/DateUtil.java
================================================
package com.example.sens.util;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* @author 言曌
* @date 2020/4/5 4:36 下午
*/
public class DateUtil {
public static final String FORMAT = "yyyy-MM-dd";
public static final ThreadLocal THREAD_LOCAL = new ThreadLocal<>();
public static List getBetweenDates(String start, int count) {
Date startDate = null;
SimpleDateFormat sdf = THREAD_LOCAL.get();
if (sdf == null) {
sdf = new SimpleDateFormat(FORMAT);
}
try {
startDate = sdf.parse(start);
} catch (ParseException e) {
e.printStackTrace();
return Collections.emptyList();
}
Calendar c = Calendar.getInstance();
c.setTime(startDate);
c.add(Calendar.DAY_OF_MONTH, count);
Date endDate = c.getTime();
String end = sdf.format(endDate);
return getBetweenDates(start, end);
}
public static List getBetweenDates(String start, String end) {
List result = new ArrayList<>();
try {
SimpleDateFormat sdf = THREAD_LOCAL.get();
if (sdf == null) {
sdf = new SimpleDateFormat(FORMAT);
}
Date start_date = sdf.parse(start);
Date end_date = sdf.parse(end);
Calendar tempStart = Calendar.getInstance();
tempStart.setTime(start_date);
Calendar tempEnd = Calendar.getInstance();
tempEnd.setTime(end_date);
while (tempStart.before(tempEnd)) {
result.add(sdf.format(tempStart.getTime()));
tempStart.add(Calendar.DAY_OF_YEAR, 1);
}
} catch (ParseException e) {
e.printStackTrace();
}
return result;
}
public static void main(String[] args) {
System.out.println(getBetweenDates("2020-04-05", 1));
}
================================================
FILE: src/main/java/com/example/sens/util/FileUtil.java
================================================
package com.example.sens.util;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.StrBuilder;
import com.alibaba.fastjson.JSONException;
import com.example.sens.exception.MyBusinessException;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.net.URL;
import java.nio.charset.Charset;
/**
* @author 言曌
* @date 2020/3/8 5:45 下午
*/
public class FileUtil {
/**
* 上传文件返回URL
*
* @param file
* @return
*/
public static String upload(MultipartFile file) {
String path = "";
try {
//用户目录
final StrBuilder uploadPath = new StrBuilder(System.getProperties().getProperty("user.home"));
uploadPath.append("/sens/upload/" + DateUtil.thisYear()).append("/").append(DateUtil.thisMonth() + 1).append("/");
final File mediaPath = new File(uploadPath.toString());
if (!mediaPath.exists()) {
if (!mediaPath.mkdirs()) {
throw new MyBusinessException("上传失败");
}
}
//不带后缀
String nameWithOutSuffix = file.getOriginalFilename().substring(0, file.getOriginalFilename().lastIndexOf('.')).replaceAll(" ", "_").replaceAll(",", "");
//文件后缀
final String fileSuffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf('.') + 1);
//带后缀
String fileName = nameWithOutSuffix + "." + fileSuffix;
//判断文件名是否已存在
File descFile = new File(mediaPath.getAbsoluteFile(), fileName);
int i = 1;
while (descFile.exists()) {
String newNameWithOutSuffix = nameWithOutSuffix + "(" + i + ")";
descFile = new File(mediaPath.getAbsoluteFile(), newNameWithOutSuffix + "." + fileSuffix);
i++;
}
file.transferTo(descFile);
//文件原路径
final StrBuilder fullPath = new StrBuilder(mediaPath.getAbsolutePath());
fullPath.append("/");
fullPath.append(nameWithOutSuffix + "." + fileSuffix);
//压缩文件路径
final StrBuilder fullSmallPath = new StrBuilder(mediaPath.getAbsolutePath());
fullSmallPath.append("/");
fullSmallPath.append(nameWithOutSuffix);
fullSmallPath.append("_small.");
fullSmallPath.append(fileSuffix);
//映射路径
final StrBuilder filePath = new StrBuilder("/upload/");
filePath.append(DateUtil.thisYear());
filePath.append("/");
filePath.append(DateUtil.thisMonth() + 1);
filePath.append("/");
filePath.append(nameWithOutSuffix + "." + fileSuffix);
path = filePath.toString();
} catch (IOException e) {
e.printStackTrace();
}
return path;
}
public static String readStringFromUrl(String url) throws IOException, JSONException {
InputStream is = new URL(url).openStream();
try {
BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
String jsonText = readAll(rd);
return jsonText;
} finally {
is.close();
}
}
private static String readAll(Reader rd) throws IOException {
StringBuilder sb = new StringBuilder();
int cp;
while ((cp = rd.read()) != -1) {
sb.append((char) cp);
}
return sb.toString();
}
}
================================================
FILE: src/main/java/com/example/sens/util/IpInfoUtil.java
================================================
package com.example.sens.util;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
* @author example
*/
@Slf4j
public class IpInfoUtil {
/**
* 获取客户端IP地址
* @param request 请求
* @return
*/
public static String getIpAddr(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
if ("127.0.0.1".equals(ip)) {
//根据网卡取本机配置的IP
InetAddress inet = null;
try {
inet = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
ip = inet.getHostAddress();
}
}
// 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
if (ip != null && ip.length() > 15) {
if (ip.indexOf(",") > 0) {
ip = ip.substring(0, ip.indexOf(","));
}
}
if("0:0:0:0:0:0:0:1".equals(ip)){
ip = "127.0.0.1";
}
return ip;
}
}
================================================
FILE: src/main/java/com/example/sens/util/Md5Util.java
================================================
package com.example.sens.util;
import cn.hutool.core.text.StrBuilder;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
import java.security.MessageDigest;
/**
* 获取文件hash
*/
public class Md5Util {
/**
* shiro的md5加密
*
* @param pwd 密码
* @param salt 盐
* @param i 加密次数
* @return 加密后字符串
*/
public static String toMd5(String pwd, String salt, int i) {
Md5Hash toMd5 = new Md5Hash(pwd, salt, i);
return toMd5.toString();
}
/**
* 计算文件MD5编码
*
* @param file file
* @return byte
* @throws Exception Exception
*/
private static byte[] createChecksum(MultipartFile file) throws Exception {
final InputStream fis = file.getInputStream();
final byte[] buffer = new byte[1024];
final MessageDigest complete = MessageDigest.getInstance("MD5");
int numRead;
do {
numRead = fis.read(buffer);
if (numRead > 0) {
complete.update(buffer, 0, numRead);
}
} while (numRead != -1);
fis.close();
return complete.digest();
}
/**
* 生成文件hash值
*
* @param file file
* @return String
* @throws Exception Exception
*/
public static String getMD5Checksum(MultipartFile file) throws Exception {
final byte[] b = createChecksum(file);
StrBuilder result = new StrBuilder();
for (int i = 0; i < b.length; i++) {
result.append(Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1));
}
return result.toString();
}
public static void main(String args[]) {
}
}
================================================
FILE: src/main/java/com/example/sens/util/ObjectUtil.java
================================================
package com.example.sens.util;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Maps;
import com.google.gson.Gson;
import org.springframework.cglib.beans.BeanMap;
import java.util.HashMap;
import java.util.Map;
/**
* @author example
*/
public class ObjectUtil {
public static String mapToString(Map paramMap){
if (paramMap == null) {
return "";
}
Map params = new HashMap<>(16);
for (Map.Entry param : paramMap.entrySet()) {
String key = param.getKey();
String paramValue = (param.getValue() != null && param.getValue().length > 0 ? param.getValue()[0] : "");
String obj = StrUtil.endWithIgnoreCase(param.getKey(), "password") ? "密码隐藏" : paramValue;
params.put(key,obj);
}
return new Gson().toJson(params);
}
public static String mapToStringAll(Map