从零起步基于ElasticSearch的搜房网(前后端集成)实战(介绍与整体目录)点击即可
静态资源集成太多页面,我已经上传到博客资源链接,供下载。后期代码全部完善后,会上传到github上。
静态资源链接下载(点击)
本章实现模块如下:
第6章 房源信息管理模块实现
本章会对项目后台房源数据管理模块的开发进行详细的讲解,并手把手带领大家开发后台系统的相关功能,包括基于七牛云的图片上传、新增房源、数据浏览、编辑功能等基本增删查改的代码开发,以及基本的房源审核功能。
6-1 业务与功能分析设计_
6-2 基于七牛云的图片上传
6-3 基于七牛云的图片上传_本地上传
6-4 基于七牛云的图片上传_上云1试看
6-5 基于七牛云的图片上传_上云2试看
6-6 新增房源信息功能实现_上
6-7 新增房源信息功能实现_中
6-8 新增房源信息功能实现_下
6-9 房源浏览功能实现_基本开发
6-10 房源浏览功能实现_分页实现
6-11 房源浏览功能实现_多维度排序
6-12 编辑功能实现_上
6-13 编辑功能实现_下
6-14 审核功能实现
-
新增房源:
前端的图片上传插件使用的百度的upload。
打开网址:www.qiniu.com
注册账号:然后打开自己的秘钥:
这里的maven依赖,我在一开始就已经都贴出来了,这里只是告诉大家的依赖是什么。
<!-- 七牛依赖 -->
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
<version>[7.2.0, 7.2.99]</version>
</dependency>
现在我把几个html放进去:
admin: 前端模板已经上传:https://download.youkuaiyun.com/download/qq_41479464/11988918
cecnter.html:
common.thml:
house-add.html:
首先首先springBoot的本地上传方式:
结构如图:新建一个package:images留放上传图片,一个WebFileUploadConfig图片配置类
WebFileUploadConfig:
package liangliang.bigdata.config;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.web.MultipartProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;
import org.springframework.web.servlet.DispatcherServlet;
import javax.servlet.MultipartConfigElement;
import javax.servlet.Servlet;
/**
* 文件上传配置
*/
@Configuration
@ConditionalOnClass({Servlet.class,StandardServletMultipartResolver.class,
MultipartConfigElement.class
})
@ConditionalOnProperty(prefix="spring.http.multipart",name = "enabled", matchIfMissing = true)
//允许springBoot帮我自动配置的一些属性
@EnableConfigurationProperties(MultipartProperties.class)
public class WebFileUploadConfig {
private final MultipartProperties multipartProperties;
//注入属性配置
public WebFileUploadConfig (MultipartProperties multipartProperties){
this.multipartProperties = multipartProperties;
}
@Bean
@ConditionalOnMissingBean
public MultipartConfigElement multipartConfigElement(){
return this.multipartProperties.createMultipartConfig();
}
/**
*注册一个解析器
*/
@Bean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME)
@ConditionalOnMissingBean(MultipartResolver.class)
public StandardServletMultipartResolver multipartResolver(){
StandardServletMultipartResolver multipartResolver = new StandardServletMultipartResolver();
multipartResolver.setResolveLazily(this.multipartProperties.isResolveLazily());
return multipartResolver;
}
}
更新后的AdminController:有图片上传的路由
package liangliang.bigdata.web.controller.admin;
import liangliang.bigdata.base.ApiResponse;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
@Controller
public class AdminController {
/**
* 后台管理中心
* @return
*/
@GetMapping("/admin/center")
public String adminCenterPage() {
return "admin/center";
}
/**
* 欢迎页
* @return
*/
@GetMapping("/admin/welcome")
public String welcomePage() {
return "admin/welcome";
}
/**
* 管理员登录页
* @return
*/
@GetMapping("/admin/login")
public String adminLoginPage() {
return "admin/login";
}
/**
*添加房源
*/
@GetMapping("/admin/add/house")
public String addHousePage() {
return "admin/house-add";
}
/**
* 上传图片
*/
@PostMapping(value = "admin/upload/photo",consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@ResponseBody
public ApiResponse uploadPhoto(@RequestParam("file")MultipartFile file){
if (file.isEmpty()){
//如果为空则给出无效参数
return ApiResponse.ofStatus(ApiResponse.Status.NOT_VALID_PARAM);
}
String fileName = file.getOriginalFilename();
File target = new File("D:\\com7dayshare\\images\\"+fileName);
try {
file.transferTo(target);
} catch (IOException e) {
e.printStackTrace();
return ApiResponse.ofStatus(ApiResponse.Status.INTERNAL_SERVER_ERROR);
}
return ApiResponse.ofSuccess(null);
}
}
更新后的application-dev.properties:增加了图片路径的配置
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://39.107.77.240:3306/xunwu?useUnicode=true&characterEncoding=utf-8
spring.datasource.username=你的账号名字
spring.datasource.password=你的账号密码
#thymeleaf
#在dev的环境下我们禁止它进行自动缓存,否则修改后不能立即看到效果
spring.thymeleaf.cache=false
#multipart config
spring.http.multipart.enabled=true
#测试本地的图片路径
spring.http.multipart.location=D:\\com7dayshare\\images\\
spring.http.multipart.file-size-threshold=5MB
#最大请求的大小
spring.http.multipart.max-request-size=20MB
现在输入地址访问上传图片测试:http://127.0.0.1:8080/admin/center
点击新增,房源、
选择图片进行上传:
成功后检查刚刚的本地文件夹可有这个图片。如下图可以看到已经成功。
自己创建一个七牛云账号:实名认证,后期图片存放在这个上面。
使用七牛云上传图片:
在config的包下面的WebFileUploadConfig的类中加入七牛云的(机房配置和构建一个七牛上传工具实例以及认证信息,七牛空间管理实例):
同时上传需要一些七牛云的key:
在个人中心的秘钥管理中可以看见自己的公钥和秘钥。
bucket是自己建立的存储空间的名字。
另外还有域名:如下图所示。
更新后WebFileUploadConfig:
package liangliang.bigdata.config;
import com.google.gson.Gson;
import com.qiniu.common.Zone;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.web.MultipartProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;
import org.springframework.web.servlet.DispatcherServlet;
import javax.servlet.MultipartConfigElement;
import javax.servlet.Servlet;
/**
* 文件上传配置
*/
@Configuration
@ConditionalOnClass({Servlet.class, StandardServletMultipartResolver.class, MultipartConfigElement.class})
@ConditionalOnProperty(prefix = "spring.http.multipart", name = "enabled", matchIfMissing = true)
@EnableConfigurationProperties(MultipartProperties.class)
public class WebFileUploadConfig {
private final MultipartProperties multipartProperties;
public WebFileUploadConfig(MultipartProperties multipartProperties) {
this.multipartProperties = multipartProperties;
}
/**
* 上传配置
*/
@Bean
@ConditionalOnMissingBean
public MultipartConfigElement multipartConfigElement() {
return this.multipartProperties.createMultipartConfig();
}
/**
* 注册解析器
*/
@Bean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME)
@ConditionalOnMissingBean(MultipartResolver.class)
public StandardServletMultipartResolver multipartResolver() {
StandardServletMultipartResolver multipartResolver = new StandardServletMultipartResolver();
multipartResolver.setResolveLazily(this.multipartProperties.isResolveLazily());
return multipartResolver;
}
/**
* 华东机房
*/
@Bean
public com.qiniu.storage.Configuration qiniuConfig() {
return new com.qiniu.storage.Configuration(Zone.zone0());
}
/**
* 构建一个七牛上传工具实例
*/
@Bean
public UploadManager uploadManager() {
return new UploadManager(qiniuConfig());
}
@Value("${qiniu.AccessKey}")
private String accessKey;
@Value("${qiniu.SecretKey}")
private String secretKey;
/**
* 认证信息实例
* @return
*/
@Bean
public Auth auth() {
return Auth.create(accessKey, secretKey);
}
/**
* 构建七牛空间管理实例
*/
@Bean
public BucketManager bucketManager() {
return new BucketManager(auth(), qiniuConfig());
}
@Bean
public Gson gson() {
return new Gson();
}
}
上面对应的配置信息:放在application.properties:
application.properties
spring.profiles.active=dev
#帮助我们在开发过程中执行的时候jpa我们执行的sql的语句
spring.jpa.show-sql=true
#hibernate 执行只进行sql的验证,不会对sql做一些增删改的操作的
spring.jpa.hibernate.ddl-auto=validate
#sql打印级别设置为debug
logging.level.org.hibernate.SQL = debug
#设置session会话存储的类型
spring.session.store-type = hash_map
#关闭http基本验证
security.basic.enabled=false
#thymeleaf
spring.thymeleaf.mode=HTML
spring.thymeleaf.suffix=.html
spring.thymeleaf.prefix=classpath:/templates/
server.error.whitelabel.enabled=false
spring.devtools.restart.exclude=templates/**,static/**
#qiniu
qiniu.AccessKey=你的公钥
qiniu.SecretKey=你的秘钥
qiniu.Bucket=你的存储空间名
qiniu.cdn.prefix=你的域名
在service的文件夹中新建一个house的文件夹:建立IQiNiuService接口以及QiNiuServiceImpl的类
IQiNiuService:
package liangliang.bigdata.service.house;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import java.io.File;
import java.io.InputStream;
public interface IQiNiuService {
Response uploadFile(File file) throws QiniuException;
Response uploadFile(InputStream inputStream) throws QiniuException;
Response delete(String key) throws QiniuException;
}
QiNiuServiceImpl:
package liangliang.bigdata.service.house;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import com.qiniu.util.StringMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.io.File;
import java.io.InputStream;
@Service
public class QiNiuServiceImpl implements IQiNiuService {
@Autowired
private UploadManager uploadManager;
@Autowired
private BucketManager bucketManager;
@Autowired
private Auth auth;
@Value("${qiniu.Bucket}")
private String bucket;
private StringMap putPolicy;
@Override
public Response uploadFile(File file) throws QiniuException {
Response response = this.uploadManager.put(file, null, getUploadToken());
int retry = 0;
//上传尝试三次
while (response.needRetry() && retry < 3) {
response = this.uploadManager.put(file, null, getUploadToken());
retry++;
}
return response;
}
@Override
public Response uploadFile(InputStream inputStream) throws QiniuException {
Response response = this.uploadManager.put(inputStream, null, getUploadToken(), null, null);
int retry = 0;
while (response.needRetry() && retry < 3) {
response = this.uploadManager.put(inputStream, null, getUploadToken(), null, null);
retry++;
}
return response;
}
@Override
public Response delete(String key) throws QiniuException {
Response response = bucketManager.delete(this.bucket, key);
int retry = 0;
while (response.needRetry() && retry++ < 3) {
response = bucketManager.delete(bucket, key);
}
return response;
}
public void afterPropertiesSet() throws Exception {
this.putPolicy = new StringMap();
putPolicy.put("returnBody", "{\"key\":\"$(key)\",\"hash\":\"$(etag)\",\"bucket\":\"$(bucket)\",\"width\":$(imageInfo.width), \"height\":${imageInfo.height}}");
}
/**
* 获取上传凭证
* @return
*/
private String getUploadToken() {
return this.auth.uploadToken(bucket, null, 3600, putPolicy);
}
}
在web目录下新建一个dto文件夹:新建几个类:
HouseDetailDTO:
package liangliang.bigdata.web.dto;
/**
* Created by 瓦力.
*/
public class HouseDetailDTO {
private String description;
private String layoutDesc;
private String traffic;
private String roundService;
private int rentWay;
private Long adminId;
private String address;
private Long subwayLineId;
private Long subwayStationId;
private String subwayLineName;
private String subwayStationName;
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getLayoutDesc() {
return layoutDesc;
}
public void setLayoutDesc(String layoutDesc) {
this.layoutDesc = layoutDesc;
}
public String getTraffic() {
return traffic;
}
public void setTraffic(String traffic) {
this.traffic = traffic;
}
public String getRoundService() {
return roundService;
}
public void setRoundService(String roundService) {
this.roundService = roundService;
}
public int getRentWay() {
return rentWay;
}
public void setRentWay(int rentWay) {
this.rentWay = rentWay;
}
public Long getAdminId() {
return adminId;
}
public void setAdminId(Long adminId) {
this.adminId = adminId;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Long getSubwayLineId() {
return subwayLineId;
}
public void setSubwayLineId(Long subwayLineId) {
this.subwayLineId = subwayLineId;
}
public Long getSubwayStationId() {
return subwayStationId;
}
public void setSubwayStationId(Long subwayStationId) {
this.subwayStationId = subwayStationId;
}
public String getSubwayLineName() {
return subwayLineName;
}
public void setSubwayLineName(String subwayLineName) {
this.subwayLineName = subwayLineName;
}
public String getSubwayStationName() {
return subwayStationName;
}
public void setSubwayStationName(String subwayStationName) {
this.subwayStationName = subwayStationName;
}
}
HouseDTO:
package liangliang.bigdata.web.dto;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* Created by 瓦力.
*/
public class HouseDTO implements Serializable {
private static final long serialVersionUID = 8918735582286008182L;
private Long id;
private String title;
private int price;
private int area;
private int direction;
private int room;
private int parlour;
private int bathroom;
private int floor;
private Long adminId;
private String district;
private int totalFloor;
private int watchTimes;
private int buildYear;
private int status;
private Date createTime;
private Date lastUpdateTime;
private String cityEnName;
private String regionEnName;
private String street;
private String cover;
private int distanceToSubway;
private HouseDetailDTO houseDetail;
private List<String> tags;
private List<HousePictureDTO> pictures;
private int subscribeStatus;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public int getArea() {
return area;
}
public void setArea(int area) {
this.area = area;
}
public int getDirection() {
return direction;
}
public void setDirection(int direction) {
this.direction = direction;
}
public int getRoom() {
return room;
}
public void setRoom(int room) {
this.room = room;
}
public int getParlour() {
return parlour;
}
public void setParlour(int parlour) {
this.parlour = parlour;
}
public int getBathroom() {
return bathroom;
}
public void setBathroom(int bathroom) {
this.bathroom = bathroom;
}
public int getFloor() {
return floor;
}
public void setFloor(int floor) {
this.floor = floor;
}
public Long getAdminId() {
return adminId;
}
public void setAdminId(Long adminId) {
this.adminId = adminId;
}
public String getDistrict() {
return district;
}
public void setDistrict(String district) {
this.district = district;
}
public int getTotalFloor() {
return totalFloor;
}
public void setTotalFloor(int totalFloor) {
this.totalFloor = totalFloor;
}
public int getWatchTimes() {
return watchTimes;
}
public void setWatchTimes(int watchTimes) {
this.watchTimes = watchTimes;
}
public int getBuildYear() {
return buildYear;
}
public void setBuildYear(int buildYear) {
this.buildYear = buildYear;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public List<String> getTags() {
if (this.tags == null) {
tags = new ArrayList<>();
}
return tags;
}
public void setTags(List<String> tags) {
this.tags = tags;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getLastUpdateTime() {
return lastUpdateTime;
}
public void setLastUpdateTime(Date lastUpdateTime) {
this.lastUpdateTime = lastUpdateTime;
}
public String getCityEnName() {
return cityEnName;
}
public void setCityEnName(String cityEnName) {
this.cityEnName = cityEnName;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getCover() {
return cover;
}
public void setCover(String cover) {
this.cover = cover;
}
public int getDistanceToSubway() {
return distanceToSubway;
}
public void setDistanceToSubway(int distanceToSubway) {
this.distanceToSubway = distanceToSubway;
}
public HouseDetailDTO getHouseDetail() {
return houseDetail;
}
public void setHouseDetail(HouseDetailDTO houseDetail) {
this.houseDetail = houseDetail;
}
public String getRegionEnName() {
return regionEnName;
}
public void setRegionEnName(String regionEnName) {
this.regionEnName = regionEnName;
}
public List<HousePictureDTO> getPictures() {
return pictures;
}
public void setPictures(List<HousePictureDTO> pictures) {
this.pictures = pictures;
}
public int getSubscribeStatus() {
return subscribeStatus;
}
public void setSubscribeStatus(int subscribeStatus) {
this.subscribeStatus = subscribeStatus;
}
@Override
public String toString() {
return "HouseDTO{" +
"id=" + id +
", title='" + title + '\'' +
", price=" + price +
", area=" + area +
", floor=" + floor +
", totalFloor=" + totalFloor +
", watchTimes=" + watchTimes +
", buildYear=" + buildYear +
", status=" + status +
", createTime=" + createTime +
", lastUpdateTime=" + lastUpdateTime +
", cityEnName='" + cityEnName + '\'' +
", cover='" + cover + '\'' +
", houseDetail=" + houseDetail +
", pictures=" + pictures +
'}';
}
}
HousePictureDTO:
package liangliang.bigdata.web.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* Created by 瓦力.
*/
public class HousePictureDTO {
private Long id;
@JsonProperty(value = "house_id")
private Long houseId;
private String path;
@JsonProperty(value = "cdn_prefix")
private String cdnPrefix;
private int width;
private int height;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getHouseId() {
return houseId;
}
public void setHouseId(Long houseId) {
this.houseId = houseId;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getCdnPrefix() {
return cdnPrefix;
}
public void setCdnPrefix(String cdnPrefix) {
this.cdnPrefix = cdnPrefix;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
@Override
public String toString() {
return "HousePictureDTO{" +
"id=" + id +
", houseId=" + houseId +
", path='" + path + '\'' +
", cdnPrefix='" + cdnPrefix + '\'' +
", width=" + width +
", height=" + height +
'}';
}
}
QiNiuPutRet:用来返回图片上传的结果集
package liangliang.bigdata.web.dto;
/**
* 这个类只是用来返回我们的结果集
*/
public final class QiNiuPutRet {
public String key;
public String hash;
public String bucket;
public int width;
public int height;
@Override
public String toString() {
return "QiNiuPutRet{" +
"key='" + key + '\'' +
", hash='" + hash + '\'' +
", bucket='" + bucket + '\'' +
", width=" + width +
", height=" + height +
'}';
}
}
SubwayDTO:
package liangliang.bigdata.web.dto;
/**
*@描述 无痕奈何
*@创建人 彭亮
*/
public class SubwayDTO {
private Long id;
private String name;
private String cityEnName;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCityEnName() {
return cityEnName;
}
public void setCityEnName(String cityEnName) {
this.cityEnName = cityEnName;
}
}
SubwayStationDTO:
package liangliang.bigdata.web.dto;
/**
* Created by 瓦力.
*/
public class SubwayStationDTO {
private Long id;
private Long subwayId;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getSubwayId() {
return subwayId;
}
public void setSubwayId(Long subwayId) {
this.subwayId = subwayId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
SupportAddressDTO:
package liangliang.bigdata.web.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
public class SupportAddressDTO {
private Long id;
@JsonProperty(value = "belong_to")
private String beglongTo;
@JsonProperty(value = "en_name")
private String enName;
@JsonProperty(value = "cn_name")
private String cnName;
private String level;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getBeglongTo() {
return beglongTo;
}
public void setBeglongTo(String beglongTo) {
this.beglongTo = beglongTo;
}
public String getEnName() {
return enName;
}
public void setEnName(String enName) {
this.enName = enName;
}
public String getCnName() {
return cnName;
}
public void setCnName(String cnName) {
this.cnName = cnName;
}
public String getLevel() {
return level;
}
public void setLevel(String level) {
this.level = level;
}
}
UserDTO:
package liangliang.bigdata.web.dto;
/**
*@描述 无痕奈何
*@创建人 彭亮
*/
public class UserDTO {
private Long id;
private String name;
private String avatar;
private String phoneNumber;
private String lastLoginTime;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAvatar() {
return avatar;
}
public void setAvatar(String avatar) {
this.avatar = avatar;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getLastLoginTime() {
return lastLoginTime;
}
public void setLastLoginTime(String lastLoginTime) {
this.lastLoginTime = lastLoginTime;
}
}
web文件夹中新建一个form文件夹:
HouseForm:
package liangliang.bigdata.web.form;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.List;
/**
*@描述 无痕奈何
*@创建人 彭亮
*/
public class HouseForm {
private Long id;
@NotNull(message = "大标题不允许为空!")
@Size(min = 1, max = 30, message = "标题长度必须在1~30之间")
private String title;
@NotNull(message = "必须选中一个城市")
@Size(min = 1, message = "非法的城市")
private String cityEnName;
@NotNull(message = "必须选中一个地区")
@Size(min = 1, message = "非法的地区")
private String regionEnName;
@NotNull(message = "必须填写街道")
@Size(min = 1, message = "非法的街道")
private String street;
@NotNull(message = "必须填写小区")
private String district;
@NotNull(message = "详细地址不允许为空!")
@Size(min = 1, max = 30, message = "详细地址长度必须在1~30之间")
private String detailAddress;
@NotNull(message = "必须填写卧室数量")
@Min(value = 1, message = "非法的卧室数量")
private Integer room;
private int parlour;
@NotNull(message = "必须填写所属楼层")
private Integer floor;
@NotNull(message = "必须填写总楼层")
private Integer totalFloor;
@NotNull(message = "必须填写房屋朝向")
private Integer direction;
@NotNull(message = "必须填写建筑起始时间")
@Min(value = 1900, message = "非法的建筑起始时间")
private Integer buildYear;
@NotNull(message = "必须填写面积")
@Min(value = 1)
private Integer area;
@NotNull(message = "必须填写租赁价格")
@Min(value = 1)
private Integer price;
@NotNull(message = "必须选中一个租赁方式")
@Min(value = 0)
@Max(value = 1)
private Integer rentWay;
private Long subwayLineId;
private Long subwayStationId;
private int distanceToSubway = -1;
private String layoutDesc;
private String roundService;
private String traffic;
@Size(max = 255)
private String description;
private String cover;
private List<String> tags;
private List<PhotoForm> photos;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getCityEnName() {
return cityEnName;
}
public void setCityEnName(String cityEnName) {
this.cityEnName = cityEnName;
}
public String getRegionEnName() {
return regionEnName;
}
public void setRegionEnName(String regionEnName) {
this.regionEnName = regionEnName;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getDistrict() {
return district;
}
public void setDistrict(String district) {
this.district = district;
}
public String getDetailAddress() {
return detailAddress;
}
public void setDetailAddress(String detailAddress) {
this.detailAddress = detailAddress;
}
public Integer getRoom() {
return room;
}
public void setRoom(Integer room) {
this.room = room;
}
public int getParlour() {
return parlour;
}
public void setParlour(int parlour) {
this.parlour = parlour;
}
public Integer getFloor() {
return floor;
}
public void setFloor(Integer floor) {
this.floor = floor;
}
public Integer getTotalFloor() {
return totalFloor;
}
public void setTotalFloor(Integer totalFloor) {
this.totalFloor = totalFloor;
}
public Integer getDirection() {
return direction;
}
public void setDirection(Integer direction) {
this.direction = direction;
}
public Integer getBuildYear() {
return buildYear;
}
public void setBuildYear(Integer buildYear) {
this.buildYear = buildYear;
}
public Integer getArea() {
return area;
}
public void setArea(Integer area) {
this.area = area;
}
public Integer getPrice() {
return price;
}
public void setPrice(Integer price) {
this.price = price;
}
public Integer getRentWay() {
return rentWay;
}
public void setRentWay(Integer rentWay) {
this.rentWay = rentWay;
}
public Long getSubwayLineId() {
return subwayLineId;
}
public void setSubwayLineId(Long subwayLineId) {
this.subwayLineId = subwayLineId;
}
public Long getSubwayStationId() {
return subwayStationId;
}
public void setSubwayStationId(Long subwayStationId) {
this.subwayStationId = subwayStationId;
}
public int getDistanceToSubway() {
return distanceToSubway;
}
public void setDistanceToSubway(int distanceToSubway) {
this.distanceToSubway = distanceToSubway;
}
public String getLayoutDesc() {
return layoutDesc;
}
public void setLayoutDesc(String layoutDesc) {
this.layoutDesc = layoutDesc;
}
public String getRoundService() {
return roundService;
}
public void setRoundService(String roundService) {
this.roundService = roundService;
}
public String getTraffic() {
return traffic;
}
public void setTraffic(String traffic) {
this.traffic = traffic;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getCover() {
return cover;
}
public void setCover(String cover) {
this.cover = cover;
}
public List<String> getTags() {
return tags;
}
public void setTags(List<String> tags) {
this.tags = tags;
}
public List<PhotoForm> getPhotos() {
return photos;
}
public void setPhotos(List<PhotoForm> photos) {
this.photos = photos;
}
@Override
public String toString() {
return "HouseForm{" +
"id=" + id +
", title='" + title + '\'' +
", cityEnName='" + cityEnName + '\'' +
", regionEnName='" + regionEnName + '\'' +
", district='" + district + '\'' +
", detailAddress='" + detailAddress + '\'' +
", room=" + room +
", parlour=" + parlour +
", floor=" + floor +
", totalFloor=" + totalFloor +
", direction=" + direction +
", buildYear=" + buildYear +
", area=" + area +
", price=" + price +
", rentWay=" + rentWay +
", subwayLineId=" + subwayLineId +
", subwayStationId=" + subwayStationId +
", distanceToSubway=" + distanceToSubway +
", layoutDesc='" + layoutDesc + '\'' +
", roundService='" + roundService + '\'' +
", traffic='" + traffic + '\'' +
", description='" + description + '\'' +
", cover='" + cover + '\'' +
", photos=" + photos +
'}';
}
}
PhotoForm:
package liangliang.bigdata.web.form;
/**
*@描述 无痕奈何
*@创建人 彭亮
*/
public class PhotoForm {
private String path;
private int width;
private int height;
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
}
AdminController:
package liangliang.bigdata.web.controller.admin;
import com.google.gson.Gson;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import liangliang.bigdata.base.ApiDataTableResponse;
import liangliang.bigdata.base.ApiResponse;
import liangliang.bigdata.entity.SupportAddress;
import liangliang.bigdata.service.IUserService;
import liangliang.bigdata.service.ServiceMultiResult;
import liangliang.bigdata.service.ServiceResult;
import liangliang.bigdata.service.house.IAddressService;
import liangliang.bigdata.service.house.IHouseService;
import liangliang.bigdata.service.house.IQiNiuService;
import liangliang.bigdata.web.dto.HouseDTO;
import liangliang.bigdata.web.dto.QiNiuPutRet;
import liangliang.bigdata.web.dto.SupportAddressDTO;
import liangliang.bigdata.web.form.DatatableSearch;
import liangliang.bigdata.web.form.HouseForm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.validation.Valid;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
@Controller
public class AdminController {
@Autowired
private IQiNiuService qiNiuService;
@Autowired
private Gson gson;
/**
* 后台管理中心
* @return
*/
@GetMapping("/admin/center")
public String adminCenterPage() {
return "admin/center";
}
/**
* 欢迎页
* @return
*/
@GetMapping("/admin/welcome")
public String welcomePage() {
return "admin/welcome";
}
/**
* 管理员登录页
* @return
*/
@GetMapping("/admin/login")
public String adminLoginPage() {
return "admin/login";
}
/**
*添加房源
*/
@GetMapping("/admin/add/house")
public String addHousePage() {
return "admin/house-add";
}
/**
* 上传图片接口
* @param file
* @return
*/
@PostMapping(value = "admin/upload/photo", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@ResponseBody
public ApiResponse uploadPhoto(@RequestParam("file") MultipartFile file) {
if (file.isEmpty()) {
return ApiResponse.ofStatus(ApiResponse.Status.NOT_VALID_PARAM);
}
String fileName = file.getOriginalFilename();
try {
InputStream inputStream = file.getInputStream();
Response response = qiNiuService.uploadFile(inputStream);
if (response.isOK()) {
QiNiuPutRet ret = gson.fromJson(response.bodyString(), QiNiuPutRet.class);
return ApiResponse.ofSuccess(ret);
} else {
return ApiResponse.ofMessage(response.statusCode, response.getInfo());
}
} catch (QiniuException e) {
Response response = e.response;
try {
return ApiResponse.ofMessage(response.statusCode, response.bodyString());
} catch (QiniuException e1) {
e1.printStackTrace();
return ApiResponse.ofStatus(ApiResponse.Status.INTERNAL_SERVER_ERROR);
}
} catch (IOException e) {
return ApiResponse.ofStatus(ApiResponse.Status.INTERNAL_SERVER_ERROR);
}
}
}
然后再test中新建service中再建立一个house文件夹:
QiNiuServiceTests:
package liangliang.bigdata.service.house;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import liangliang.bigdata.ApplicationTests;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.File;
/**
*
*/
public class QiNiuServiceTests extends ApplicationTests {
@Autowired
private IQiNiuService qiNiuService;
@Test
public void testUploadFile() {
String fileName = "D:\\com7dayshare\\images\\dog.png";
File file = new File(fileName);
Assert.assertTrue(file.exists());
try {
Response response = qiNiuService.uploadFile(file);
Assert.assertTrue(response.isOK());
} catch (QiniuException e) {
e.printStackTrace();
}
}
// @Test
// public void testDelete() {
// String key = "FvyNceBAaZF6TBh6OZpcEKlhuACG";
// try {
// Response response = qiNiuService.delete(key);
// Assert.assertTrue(response.isOK());
// } catch (QiniuException e) {
// e.printStackTrace();
// }
// }
}
然后运行单测。再去七牛云空间查看就可以看到成功。
跑图片上传测试的时候出现一个问题(解决办法):https://blog.youkuaiyun.com/qq_41479464/article/details/103193998
房源信息管理(增、删、改、查):
新增房源功能开发:
在web中的controller文件夹中新建一个house文件夹,把有关房屋相关的controller,都放在这里面:
HouseController:
package liangliang.bigdata.web.controller.house;
import liangliang.bigdata.base.ApiResponse;
import liangliang.bigdata.service.IUserService;
import liangliang.bigdata.service.ServiceMultiResult;
import liangliang.bigdata.service.house.IAddressService;
import liangliang.bigdata.service.house.IHouseService;
import liangliang.bigdata.web.dto.SubwayDTO;
import liangliang.bigdata.web.dto.SubwayStationDTO;
import liangliang.bigdata.web.dto.SupportAddressDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
@Controller
public class HouseController {
@Autowired
private IAddressService addressService;
@Autowired
private IHouseService houseService;
@Autowired
private IUserService userService;
/**
* 获取支持城市列表
* @return
*/
@GetMapping("address/support/cities")
@ResponseBody
public ApiResponse getSupportCities() {
ServiceMultiResult<SupportAddressDTO> result = addressService.findAllCities();
if (result.getResultSize() == 0) {
return ApiResponse.ofStatus(ApiResponse.Status.NOT_FOUND);
}
return ApiResponse.ofSuccess(result.getResult());
}
/**
* 获取对应城市支持区域列表
* @param cityEnName
* @return
*/
@GetMapping("address/support/regions")
@ResponseBody
public ApiResponse getSupportRegions(@RequestParam(name = "city_name") String cityEnName) {
ServiceMultiResult<SupportAddressDTO> addressResult = addressService.findAllRegionsByCityName(cityEnName);
if (addressResult.getResult() == null || addressResult.getTotal() < 1) {
return ApiResponse.ofStatus(ApiResponse.Status.NOT_FOUND);
}
return ApiResponse.ofSuccess(addressResult.getResult());
}
/**
* 获取具体城市所支持的地铁线路
* @param cityEnName
* @return
*/
@GetMapping("address/support/subway/line")
@ResponseBody
public ApiResponse getSupportSubwayLine(@RequestParam(name = "city_name") String cityEnName) {
List<SubwayDTO> subways = addressService.findAllSubwayByCity(cityEnName);
if (subways.isEmpty()) {
return ApiResponse.ofStatus(ApiResponse.Status.NOT_FOUND);
}
return ApiResponse.ofSuccess(subways);
}
/**
* 获取对应地铁线路所支持的地铁站点
* @param subwayId
* @return
*/
@GetMapping("address/support/subway/station")
@ResponseBody
public ApiResponse getSupportSubwayStation(@RequestParam(name = "subway_id") Long subwayId) {
List<SubwayStationDTO> stationDTOS = addressService.findAllStationBySubway(subwayId);
if (stationDTOS.isEmpty()) {
return ApiResponse.ofStatus(ApiResponse.Status.NOT_FOUND);
}
return ApiResponse.ofSuccess(stationDTOS);
}
}
在entity中新建一个实体类:SupportAddress
SupportAddress:
package liangliang.bigdata.entity;
import javax.persistence.*;
/**
*
*/
@Entity
@Table(name = "support_address")
public class SupportAddress {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
// 上一级行政单位
@Column(name = "belong_to")
private String belongTo;
@Column(name = "en_name")
private String enName;
@Column(name = "cn_name")
private String cnName;
private String level;
@Column(name = "baidu_map_lng")
private double baiduMapLongitude;
@Column(name = "baidu_map_lat")
private double baiduMapLatitude;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getBelongTo() {
return belongTo;
}
public void setBelongTo(String belongTo) {
this.belongTo = belongTo;
}
public String getEnName() {
return enName;
}
public void setEnName(String enName) {
this.enName = enName;
}
public String getCnName() {
return cnName;
}
public void setCnName(String cnName) {
this.cnName = cnName;
}
public String getLevel() {
return level;
}
public void setLevel(String level) {
this.level = level;
}
public double getBaiduMapLongitude() {
return baiduMapLongitude;
}
public void setBaiduMapLongitude(double baiduMapLongitude) {
this.baiduMapLongitude = baiduMapLongitude;
}
public double getBaiduMapLatitude() {
return baiduMapLatitude;
}
public void setBaiduMapLatitude(double baiduMapLatitude) {
this.baiduMapLatitude = baiduMapLatitude;
}
/**
* 行政级别定义
*/
public enum Level {
CITY("city"),
REGION("region");
private String value;
Level(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public static Level of(String value) {
for (Level level : Level.values()) {
if (level.getValue().equals(value)) {
return level;
}
}
throw new IllegalArgumentException();
}
}
}
在service中的文件夹中新建一个ServiceMultiResult的类
ServiceMultiResult:
package liangliang.bigdata.service;
import java.util.List;
/**
* 通用多结果Service返回结构
* Created by 瓦力.
*/
public class ServiceMultiResult<T> {
private long total;//数据库总共有多少数据
private List<T> result;
public ServiceMultiResult(long total, List<T> result) {
this.total = total;
this.result = result;
}
public long getTotal() {
return total;
}
public void setTotal(long total) {
this.total = total;
}
public List<T> getResult() {
return result;
}
public void setResult(List<T> result) {
this.result = result;
}
//获取当前结果集
public int getResultSize() {
if (this.result == null) {
return 0;
}
return this.result.size();
}
}
在repository文件夹中新建一个SupportAddressRepository接口:
SupportAddressRepository:
package liangliang.bigdata.repository;
import liangliang.bigdata.entity.SupportAddress;
import org.springframework.data.repository.CrudRepository;
import java.util.List;
public interface SupportAddressRepository extends CrudRepository<SupportAddress,Long> {
/**
* 获取所有对应行政级别的信息
*/
List<SupportAddress> findAllByLevel(String level);
SupportAddress findByEnNameAndLevel(String enName, String level);
SupportAddress findByEnNameAndBelongTo(String enName, String belongTo);
List<SupportAddress> findAllByLevelAndBelongTo(String level, String belongTo);
}
新增功能所需的实体类:
house:
package liangliang.bigdata.entity;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* Created by 瓦力.
*/
@Entity
@Table(name = "house")
public class House {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
@Column(name = "admin_id")
private Long adminId;
private int price;
private int area;
private int room;
private int parlour;
private int bathroom;
private int floor;
@Column(name = "total_floor")
private int totalFloor;
@Column(name = "watch_times")
private int watchTimes;
@Column(name = "build_year")
private int buildYear;
private int status;
@Column(name = "create_time")
private Date createTime;
@Column(name = "last_update_time")
private Date lastUpdateTime;
@Column(name = "city_en_name")
private String cityEnName;
@Column(name = "region_en_name")
private String regionEnName;
private String street;
private String district;
private int direction;
private String cover;
@Column(name = "distance_to_subway")
private int distanceToSubway;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getAdminId() {
return adminId;
}
public void setAdminId(Long adminId) {
this.adminId = adminId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public int getArea() {
return area;
}
public void setArea(int area) {
this.area = area;
}
public int getRoom() {
return room;
}
public void setRoom(int room) {
this.room = room;
}
public int getParlour() {
return parlour;
}
public void setParlour(int parlour) {
this.parlour = parlour;
}
public int getBathroom() {
return bathroom;
}
public void setBathroom(int bathroom) {
this.bathroom = bathroom;
}
public int getFloor() {
return floor;
}
public void setFloor(int floor) {
this.floor = floor;
}
public int getTotalFloor() {
return totalFloor;
}
public void setTotalFloor(int totalFloor) {
this.totalFloor = totalFloor;
}
public int getWatchTimes() {
return watchTimes;
}
public void setWatchTimes(int watchTimes) {
this.watchTimes = watchTimes;
}
public int getBuildYear() {
return buildYear;
}
public void setBuildYear(int buildYear) {
this.buildYear = buildYear;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getLastUpdateTime() {
return lastUpdateTime;
}
public void setLastUpdateTime(Date lastUpdateTime) {
this.lastUpdateTime = lastUpdateTime;
}
public String getCityEnName() {
return cityEnName;
}
public void setCityEnName(String cityEnName) {
this.cityEnName = cityEnName;
}
public String getRegionEnName() {
return regionEnName;
}
public void setRegionEnName(String regionEnName) {
this.regionEnName = regionEnName;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getDistrict() {
return district;
}
public void setDistrict(String district) {
this.district = district;
}
public int getDirection() {
return direction;
}
public void setDirection(int direction) {
this.direction = direction;
}
public String getCover() {
return cover;
}
public void setCover(String cover) {
this.cover = cover;
}
public int getDistanceToSubway() {
return distanceToSubway;
}
public void setDistanceToSubway(int distanceToSubway) {
this.distanceToSubway = distanceToSubway;
}
}
HouseDetail:
package liangliang.bigdata.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* Created by 瓦力.
*/
@Entity
@Table(name = "house_detail")
public class HouseDetail {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "house_id")
private Long houseId;
private String description;
@Column(name = "layout_desc")
private String layoutDesc;
private String traffic;
@Column(name = "round_service")
private String roundService;
@Column(name = "rent_way")
private int rentWay;
@Column(name = "address")
private String detailAddress;
@Column(name = "subway_line_id")
private Long subwayLineId;
@Column(name = "subway_station_id")
private Long subwayStationId;
@Column(name = "subway_line_name")
private String subwayLineName;
@Column(name = "subway_station_name")
private String subwayStationName;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getHouseId() {
return houseId;
}
public void setHouseId(Long houseId) {
this.houseId = houseId;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getLayoutDesc() {
return layoutDesc;
}
public void setLayoutDesc(String layoutDesc) {
this.layoutDesc = layoutDesc;
}
public String getTraffic() {
return traffic;
}
public void setTraffic(String traffic) {
this.traffic = traffic;
}
public String getRoundService() {
return roundService;
}
public void setRoundService(String roundService) {
this.roundService = roundService;
}
public int getRentWay() {
return rentWay;
}
public void setRentWay(int rentWay) {
this.rentWay = rentWay;
}
public String getDetailAddress() {
return detailAddress;
}
public void setDetailAddress(String detailAddress) {
this.detailAddress = detailAddress;
}
public Long getSubwayLineId() {
return subwayLineId;
}
public void setSubwayLineId(Long subwayLineId) {
this.subwayLineId = subwayLineId;
}
public Long getSubwayStationId() {
return subwayStationId;
}
public void setSubwayStationId(Long subwayStationId) {
this.subwayStationId = subwayStationId;
}
public String getSubwayLineName() {
return subwayLineName;
}
public void setSubwayLineName(String subwayLineName) {
this.subwayLineName = subwayLineName;
}
public String getSubwayStationName() {
return subwayStationName;
}
public void setSubwayStationName(String subwayStationName) {
this.subwayStationName = subwayStationName;
}
}
HousePicture:
package liangliang.bigdata.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* Created by 瓦力.
*/
@Entity
@Table(name = "house_picture")
public class HousePicture {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "house_id")
private Long houseId;
private String path;
@Column(name = "cdn_prefix")
private String cdnPrefix;
private int width;
private int height;
private String location;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getHouseId() {
return houseId;
}
public void setHouseId(Long houseId) {
this.houseId = houseId;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getCdnPrefix() {
return cdnPrefix;
}
public void setCdnPrefix(String cdnPrefix) {
this.cdnPrefix = cdnPrefix;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
}
HouseTag:
package liangliang.bigdata.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* Created by 瓦力.
*/
@Entity
@Table(name = "house_tag")
public class HouseTag {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "house_id")
private Long houseId;
private String name;
public HouseTag() {
}
public HouseTag(Long houseId, String name) {
this.houseId = houseId;
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getHouseId() {
return houseId;
}
public void setHouseId(Long houseId) {
this.houseId = houseId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Role:
package liangliang.bigdata.entity;
import javax.persistence.*;
@Entity
@Table(name = "role")
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "user_id")
private Long userId;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Subway:
package liangliang.bigdata.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* Created by 瓦力.
*/
@Entity
@Table(name = "subway")
public class Subway {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@Column(name = "city_en_name")
private String cityEnName;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCityEnName() {
return cityEnName;
}
public void setCityEnName(String cityEnName) {
this.cityEnName = cityEnName;
}
}
SubwayStation:
package liangliang.bigdata.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* Created by 彭亮.
*/
@Entity
@Table(name = "subway_station")
public class SubwayStation {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "subway_id")
private Long subwayId;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getSubwayId() {
return subwayId;
}
public void setSubwayId(Long subwayId) {
this.subwayId = subwayId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
User:
package liangliang.bigdata.entity;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import javax.persistence.*;
import java.util.Collection;
import java.util.Date;
import java.util.List;
@Entity
@Table(name = "user")
public class User implements UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String password;
private String email;
@Column(name = "phone_number")
private String phoneNumber;
private int status;
@Column(name = "create_time")
private Date createTime;
@Column(name = "last_login_time")
private Date lastLoginTime;
@Column(name = "last_update_time")
private Date lastUpdateTime;
private String avatar;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Transient
private List<GrantedAuthority> authorityList;
public List<GrantedAuthority> getAuthorityList() {
return authorityList;
}
public void setAuthorityList(List<GrantedAuthority> authorityList) {
this.authorityList = authorityList;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return this.authorityList;
}
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return name;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getLastLoginTime() {
return lastLoginTime;
}
public void setLastLoginTime(Date lastLoginTime) {
this.lastLoginTime = lastLoginTime;
}
public Date getLastUpdateTime() {
return lastUpdateTime;
}
public void setLastUpdateTime(Date lastUpdateTime) {
this.lastUpdateTime = lastUpdateTime;
}
public String getAvatar() {
return avatar;
}
public void setAvatar(String avatar) {
this.avatar = avatar;
}
}
HouseDetailRepository:
package liangliang.bigdata.repository;
import liangliang.bigdata.entity.HouseDetail;
import org.springframework.data.repository.CrudRepository;
import java.util.List;
/**
*@描述 无痕奈何
*@创建人 彭亮
*/
public interface HouseDetailRepository extends CrudRepository<HouseDetail, Long>{
HouseDetail findByHouseId(Long houseId);
List<HouseDetail> findAllByHouseIdIn(List<Long> houseIds);
}
HousePictureRepository:
package liangliang.bigdata.repository;
import liangliang.bigdata.entity.HousePicture;
import org.springframework.data.repository.CrudRepository;
import java.util.List;
/**
*@描述 无痕奈何
*@创建人 彭亮
*/
public interface HousePictureRepository extends CrudRepository<HousePicture, Long> {
List<HousePicture> findAllByHouseId(Long id);
}
HouseRepository:
package liangliang.bigdata.repository;
import liangliang.bigdata.entity.House;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
/**
*@描述 无痕奈何
*@创建人 彭亮
*/
public interface HouseRepository extends PagingAndSortingRepository<House, Long>, JpaSpecificationExecutor<House> {
@Modifying
@Query("update House as house set house.cover = :cover where house.id = :id")
void updateCover(@Param(value = "id") Long id, @Param(value = "cover") String cover);
@Modifying
@Query("update House as house set house.status = :status where house.id = :id")
void updateStatus(@Param(value = "id") Long id, @Param(value = "status") int status);
@Modifying
@Query("update House as house set house.watchTimes = house.watchTimes + 1 where house.id = :id")
void updateWatchTimes(@Param(value = "id") Long houseId);
}
HouseSubscribeRespository:
package liangliang.bigdata.repository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
import liangliang.bigdata.entity.HouseSubscribe;
/**
*@描述 无痕奈何
*@创建人 彭亮
*/
public interface HouseSubscribeRespository extends PagingAndSortingRepository<HouseSubscribe, Long>{
HouseSubscribe findByHouseIdAndUserId(Long houseId, Long loginUserId);
Page<HouseSubscribe> findAllByUserIdAndStatus(Long userId, int status, Pageable pageable);
Page<HouseSubscribe> findAllByAdminIdAndStatus(Long adminId, int status, Pageable pageable);
HouseSubscribe findByHouseIdAndAdminId(Long houseId, Long adminId);
@Modifying
@Query("update HouseSubscribe as subscribe set subscribe.status = :status where subscribe.id = :id")
void updateStatus(@Param(value = "id") Long id, @Param(value = "status") int status);
}
HouseTagRepository
package liangliang.bigdata.repository;
import liangliang.bigdata.entity.HouseTag;
import org.springframework.data.repository.CrudRepository;
import java.util.List;
/**
*@描述 无痕奈何
*@创建人 彭亮
*/
public interface HouseTagRepository extends CrudRepository<HouseTag, Long> {
HouseTag findByNameAndHouseId(String name, Long houseId);
List<HouseTag> findAllByHouseId(Long id);
List<HouseTag> findAllByHouseIdIn(List<Long> houseIds);
}
RoleRepository:
package liangliang.bigdata.repository;
import liangliang.bigdata.entity.Role;
import org.springframework.data.repository.CrudRepository;
import java.util.List;
//一个对应实体类,一个对应我们的id
/**
*@描述 无痕奈何
*@创建人 彭亮
*/
public interface RoleRepository extends CrudRepository<Role,Long> {
List<Role> findRoleByUserId (Long userId);
}
SubwayRepository:
package liangliang.bigdata.repository;
import liangliang.bigdata.entity.Subway;
import org.springframework.data.repository.CrudRepository;
import java.util.List;
/**
*@描述 无痕奈何
*@创建人 彭亮
*/
public interface SubwayRepository extends CrudRepository<Subway, Long>{
List<Subway> findAllByCityEnName(String cityEnName);
}
SubwayStationRepository
package liangliang.bigdata.repository;
import liangliang.bigdata.entity.SubwayStation;
import org.springframework.data.repository.CrudRepository;
import java.util.List;
/**
*@描述 无痕奈何
*@创建人 彭亮
*/
public interface SubwayStationRepository extends CrudRepository<SubwayStation, Long> {
List<SubwayStation> findAllBySubwayId(Long subwayId);
}
SupportAddressRepository:
package liangliang.bigdata.repository;
import liangliang.bigdata.entity.SupportAddress;
import org.springframework.data.repository.CrudRepository;
import java.util.List;
/**
*@描述 无痕奈何
*@创建人 彭亮
*/
public interface SupportAddressRepository extends CrudRepository<SupportAddress,Long> {
/**
* 获取所有对应行政级别的信息
*/
List<SupportAddress> findAllByLevel(String level);
SupportAddress findByEnNameAndLevel(String enName, String level);
SupportAddress findByEnNameAndBelongTo(String enName, String belongTo);
List<SupportAddress> findAllByLevelAndBelongTo(String level, String belongTo);
}
UserRepository:
package liangliang.bigdata.repository;
import liangliang.bigdata.entity.User;
import org.springframework.data.repository.CrudRepository;
/**
*@描述 无痕奈何
*@创建人 彭亮
*/
//主键里的泛型是自己定义的User实体类,第二个是主键的类型
public interface UserRepository extends CrudRepository<User,Long> {
//JPA自动帮我们生成sql语句
User findByName(String UserName);
}
在service文件夹中新建IHouseService接口:
package liangliang.bigdata.service.house;
import liangliang.bigdata.base.HouseSubscribeStatus;
import liangliang.bigdata.service.ServiceMultiResult;
import liangliang.bigdata.service.ServiceResult;
import liangliang.bigdata.web.dto.HouseDTO;
import liangliang.bigdata.web.dto.HouseSubscribeDTO;
import liangliang.bigdata.web.form.DatatableSearch;
import liangliang.bigdata.web.form.HouseForm;
import org.springframework.data.util.Pair;
/**
*@描述 无痕奈何
*@创建人 彭亮
*/
import java.util.Date;
/**
* 房屋管理服务接口
* Created by 彭亮.
*/
public interface IHouseService {
/**
* 新增
* @param houseForm
* @return
*/
ServiceResult<HouseDTO> save(HouseForm houseForm);
ServiceMultiResult<HouseDTO> adminQuery(DatatableSearch searchBody);
/**
* 查询完整房源信息
* @param id
* @return
*/
ServiceResult<HouseDTO> findCompleteOne(Long id);
/**
* 移除图片
* @param id
* @return
*/
ServiceResult removePhoto(Long id);
/**
* 更新封面
* @param coverId
* @param targetId
* @return
*/
ServiceResult updateCover(Long coverId, Long targetId);
/**
* 新增标签
* @param houseId
* @param tag
* @return
*/
ServiceResult addTag(Long houseId, String tag);
/**
* 移除标签
* @param houseId
* @param tag
* @return
*/
ServiceResult removeTag(Long houseId, String tag);
/**
* 更新房源状态
* @param id
* @param status
* @return
*/
/**
* 加入预约清单
* @param houseId
* @return
*/
ServiceResult addSubscribeOrder(Long houseId);
/**
* 获取对应状态的预约列表
*/
ServiceMultiResult<Pair<HouseDTO, HouseSubscribeDTO>> querySubscribeList(HouseSubscribeStatus status, int start, int size);
/**
* 预约看房时间
* @param houseId
* @param orderTime
* @param telephone
* @param desc
* @return
*/
ServiceResult subscribe(Long houseId, Date orderTime, String telephone, String desc);
/**
* 取消预约
* @param houseId
* @return
*/
ServiceResult cancelSubscribe(Long houseId);
/**
* 管理员查询预约信息接口
* @param start
* @param size
*/
ServiceMultiResult<Pair<HouseDTO, HouseSubscribeDTO>> findSubscribeList(int start, int size);
/**
* 完成预约
*/
ServiceResult finishSubscribe(Long houseId);
}
接着建立HouseServiceImpl类来实现里面的方法:
package liangliang.bigdata.service.house;
import com.google.common.collect.Maps;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import liangliang.bigdata.base.HouseSort;
import liangliang.bigdata.base.HouseStatus;
import liangliang.bigdata.base.HouseSubscribeStatus;
import liangliang.bigdata.base.LoginUserUtil;
import liangliang.bigdata.entity.*;
import liangliang.bigdata.repository.*;
import liangliang.bigdata.service.ServiceMultiResult;
import liangliang.bigdata.service.ServiceResult;
import liangliang.bigdata.web.dto.HouseDTO;
import liangliang.bigdata.web.dto.HouseDetailDTO;
import liangliang.bigdata.web.dto.HousePictureDTO;
import liangliang.bigdata.web.dto.HouseSubscribeDTO;
import liangliang.bigdata.web.form.DatatableSearch;
import liangliang.bigdata.web.form.HouseForm;
import liangliang.bigdata.web.form.PhotoForm;
import liangliang.bigdata.web.form.RentSearch;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.util.Pair;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.criteria.Predicate;
import java.util.*;
/**
*@描述 无痕奈何
*@创建人 彭亮
*/
@Service
public class HouseServiceImpl implements IHouseService {
@Autowired
private ModelMapper modelMapper;
@Autowired
private HouseRepository houseRepository;
@Autowired
private HouseDetailRepository houseDetailRepository;
@Autowired
private HousePictureRepository housePictureRepository;
@Autowired
private HouseTagRepository houseTagRepository;
@Autowired
private SubwayRepository subwayRepository;
@Autowired
private SubwayStationRepository subwayStationRepository;
@Autowired
private HouseSubscribeRespository subscribeRespository;
@Autowired
private IQiNiuService qiNiuService;
@Value("${qiniu.cdn.prefix}")
private String cdnPrefix;
@Override
public ServiceResult<HouseDTO> save(HouseForm houseForm) {
HouseDetail detail = new HouseDetail();
ServiceResult<HouseDTO> subwayValidtionResult = wrapperDetailInfo(detail, houseForm);
if (subwayValidtionResult != null) {
return subwayValidtionResult;
}
House house = new House();
modelMapper.map(houseForm, house);
Date now = new Date();
house.setCreateTime(now);
house.setLastUpdateTime(now);
house.setAdminId(LoginUserUtil.getLoginUserId());
house = houseRepository.save(house);
detail.setHouseId(house.getId());
detail = houseDetailRepository.save(detail);
List<HousePicture> pictures = generatePictures(houseForm, house.getId());
Iterable<HousePicture> housePictures = housePictureRepository.save(pictures);
HouseDTO houseDTO = modelMapper.map(house, HouseDTO.class);
HouseDetailDTO houseDetailDTO = modelMapper.map(detail, HouseDetailDTO.class);
houseDTO.setHouseDetail(houseDetailDTO);
List<HousePictureDTO> pictureDTOS = new ArrayList<>();
housePictures.forEach(housePicture -> pictureDTOS.add(modelMapper.map(housePicture, HousePictureDTO.class)));
houseDTO.setPictures(pictureDTOS);
houseDTO.setCover(this.cdnPrefix + houseDTO.getCover());
List<String> tags = houseForm.getTags();
if (tags != null && !tags.isEmpty()) {
List<HouseTag> houseTags = new ArrayList<>();
for (String tag : tags) {
houseTags.add(new HouseTag(house.getId(), tag));
}
houseTagRepository.save(houseTags);
houseDTO.setTags(tags);
}
return new ServiceResult<HouseDTO>(true, null, houseDTO);
}
@Override
public ServiceMultiResult<HouseDTO> adminQuery(DatatableSearch searchBody) {
List<HouseDTO> houseDTOS = new ArrayList<>();
Sort sort = new Sort(Sort.Direction.fromString(searchBody.getDirection()), searchBody.getOrderBy());
int page = searchBody.getStart() / searchBody.getLength();
Pageable pageable = new PageRequest(page, searchBody.getLength(), sort);
Specification<House> specification = (root, query, cb) -> {
Predicate predicate = cb.equal(root.get("adminId"), LoginUserUtil.getLoginUserId());
predicate = cb.and(predicate, cb.notEqual(root.get("status"), HouseStatus.DELETED.getValue()));
if (searchBody.getCity() != null) {
predicate = cb.and(predicate, cb.equal(root.get("cityEnName"), searchBody.getCity()));
}
if (searchBody.getStatus() != null) {
predicate = cb.and(predicate, cb.equal(root.get("status"), searchBody.getStatus()));
}
if (searchBody.getCreateTimeMin() != null) {
predicate = cb.and(predicate, cb.greaterThanOrEqualTo(root.get("createTime"), searchBody.getCreateTimeMin()));
}
if (searchBody.getCreateTimeMax() != null) {
predicate = cb.and(predicate, cb.lessThanOrEqualTo(root.get("createTime"), searchBody.getCreateTimeMax()));
}
if (searchBody.getTitle() != null) {
predicate = cb.and(predicate, cb.like(root.get("title"), "%" + searchBody.getTitle() + "%"));
}
return predicate;
};
Page<House> houses = houseRepository.findAll(specification, pageable);
houses.forEach(house -> {
HouseDTO houseDTO = modelMapper.map(house, HouseDTO.class);
houseDTO.setCover(this.cdnPrefix + house.getCover());
houseDTOS.add(houseDTO);
});
return new ServiceMultiResult<>(houses.getTotalElements(), houseDTOS);
}
@Override
public ServiceResult<HouseDTO> findCompleteOne(Long id) {
House house = houseRepository.findOne(id);
if (house == null) {
return ServiceResult.notFound();
}
HouseDetail detail = houseDetailRepository.findByHouseId(id);
List<HousePicture> pictures = housePictureRepository.findAllByHouseId(id);
HouseDetailDTO detailDTO = modelMapper.map(detail, HouseDetailDTO.class);
List<HousePictureDTO> pictureDTOS = new ArrayList<>();
for (HousePicture picture : pictures) {
HousePictureDTO pictureDTO = modelMapper.map(picture, HousePictureDTO.class);
pictureDTOS.add(pictureDTO);
}
List<HouseTag> tags = houseTagRepository.findAllByHouseId(id);
List<String> tagList = new ArrayList<>();
for (HouseTag tag : tags) {
tagList.add(tag.getName());
}
HouseDTO result = modelMapper.map(house, HouseDTO.class);
result.setHouseDetail(detailDTO);
result.setPictures(pictureDTOS);
result.setTags(tagList);
if (LoginUserUtil.getLoginUserId() > 0) { // 已登录用户
HouseSubscribe subscribe = subscribeRespository.findByHouseIdAndUserId(house.getId(), LoginUserUtil.getLoginUserId());
if (subscribe != null) {
result.setSubscribeStatus(subscribe.getStatus());
}
}
return ServiceResult.of(result);
}
@Override
public ServiceResult removePhoto(Long id) {
HousePicture picture = housePictureRepository.findOne(id);
if (picture == null) {
return ServiceResult.notFound();
}
try {
Response response = this.qiNiuService.delete(picture.getPath());
if (response.isOK()) {
housePictureRepository.delete(id);
return ServiceResult.success();
} else {
return new ServiceResult(false, response.error);
}
} catch (QiniuException e) {
e.printStackTrace();
return new ServiceResult(false, e.getMessage());
}
}
@Override
@Transactional
public ServiceResult updateCover(Long coverId, Long targetId) {
HousePicture cover = housePictureRepository.findOne(coverId);
if (cover == null) {
return ServiceResult.notFound();
}
houseRepository.updateCover(targetId, cover.getPath());
return ServiceResult.success();
}
@Override
@Transactional
public ServiceResult addTag(Long houseId, String tag) {
House house = houseRepository.findOne(houseId);
if (house == null) {
return ServiceResult.notFound();
}
HouseTag houseTag = houseTagRepository.findByNameAndHouseId(tag, houseId);
if (houseTag != null) {
return new ServiceResult(false, "标签已存在");
}
houseTagRepository.save(new HouseTag(houseId, tag));
return ServiceResult.success();
}
@Override
@Transactional
public ServiceResult removeTag(Long houseId, String tag) {
House house = houseRepository.findOne(houseId);
if (house == null) {
return ServiceResult.notFound();
}
HouseTag houseTag = houseTagRepository.findByNameAndHouseId(tag, houseId);
if (houseTag == null) {
return new ServiceResult(false, "标签不存在");
}
houseTagRepository.delete(houseTag.getId());
return ServiceResult.success();
}
private List<HouseDTO> wrapperHouseResult(List<Long> houseIds) {
List<HouseDTO> result = new ArrayList<>();
Map<Long, HouseDTO> idToHouseMap = new HashMap<>();
Iterable<House> houses = houseRepository.findAll(houseIds);
houses.forEach(house -> {
HouseDTO houseDTO = modelMapper.map(house, HouseDTO.class);
houseDTO.setCover(this.cdnPrefix + house.getCover());
idToHouseMap.put(house.getId(), houseDTO);
});
wrapperHouseList(houseIds, idToHouseMap);
// 矫正顺序
for (Long houseId : houseIds) {
result.add(idToHouseMap.get(houseId));
}
return result;
}
@Override
@Transactional
public ServiceResult addSubscribeOrder(Long houseId) {
Long userId = LoginUserUtil.getLoginUserId();
HouseSubscribe subscribe = subscribeRespository.findByHouseIdAndUserId(houseId, userId);
if (subscribe != null) {
return new ServiceResult(false, "已加入预约");
}
House house = houseRepository.findOne(houseId);
if (house == null) {
return new ServiceResult(false, "查无此房");
}
subscribe = new HouseSubscribe();
Date now = new Date();
subscribe.setCreateTime(now);
subscribe.setLastUpdateTime(now);
subscribe.setUserId(userId);
subscribe.setHouseId(houseId);
subscribe.setStatus(HouseSubscribeStatus.IN_ORDER_LIST.getValue());
subscribe.setAdminId(house.getAdminId());
subscribeRespository.save(subscribe);
return ServiceResult.success();
}
@Override
public ServiceMultiResult<Pair<HouseDTO, HouseSubscribeDTO>> querySubscribeList(
HouseSubscribeStatus status,
int start,
int size) {
Long userId = LoginUserUtil.getLoginUserId();
Pageable pageable = new PageRequest(start / size, size, new Sort(Sort.Direction.DESC, "createTime"));
Page<HouseSubscribe> page = subscribeRespository.findAllByUserIdAndStatus(userId, status.getValue(), pageable);
return wrapper(page);
}
@Override
@Transactional
public ServiceResult subscribe(Long houseId, Date orderTime, String telephone, String desc) {
Long userId = LoginUserUtil.getLoginUserId();
HouseSubscribe subscribe = subscribeRespository.findByHouseIdAndUserId(houseId, userId);
if (subscribe == null) {
return new ServiceResult(false, "无预约记录");
}
if (subscribe.getStatus() != HouseSubscribeStatus.IN_ORDER_LIST.getValue()) {
return new ServiceResult(false, "无法预约");
}
subscribe.setStatus(HouseSubscribeStatus.IN_ORDER_TIME.getValue());
subscribe.setLastUpdateTime(new Date());
subscribe.setTelephone(telephone);
subscribe.setDesc(desc);
subscribe.setOrderTime(orderTime);
subscribeRespository.save(subscribe);
return ServiceResult.success();
}
@Override
@Transactional
public ServiceResult cancelSubscribe(Long houseId) {
Long userId = LoginUserUtil.getLoginUserId();
HouseSubscribe subscribe = subscribeRespository.findByHouseIdAndUserId(houseId, userId);
if (subscribe == null) {
return new ServiceResult(false, "无预约记录");
}
subscribeRespository.delete(subscribe.getId());
return ServiceResult.success();
}
@Override
public ServiceMultiResult<Pair<HouseDTO, HouseSubscribeDTO>> findSubscribeList(int start, int size) {
Long userId = LoginUserUtil.getLoginUserId();
Pageable pageable = new PageRequest(start / size, size, new Sort(Sort.Direction.DESC, "orderTime"));
Page<HouseSubscribe> page = subscribeRespository.findAllByAdminIdAndStatus(userId, HouseSubscribeStatus.IN_ORDER_TIME.getValue(), pageable);
return wrapper(page);
}
@Override
@Transactional
public ServiceResult finishSubscribe(Long houseId) {
Long adminId = LoginUserUtil.getLoginUserId();
HouseSubscribe subscribe = subscribeRespository.findByHouseIdAndAdminId(houseId, adminId);
if (subscribe == null) {
return new ServiceResult(false, "无预约记录");
}
subscribeRespository.updateStatus(subscribe.getId(), HouseSubscribeStatus.FINISH.getValue());
houseRepository.updateWatchTimes(houseId);
return ServiceResult.success();
}
private ServiceMultiResult<Pair<HouseDTO, HouseSubscribeDTO>> wrapper(Page<HouseSubscribe> page) {
List<Pair<HouseDTO, HouseSubscribeDTO>> result = new ArrayList<>();
if (page.getSize() < 1) {
return new ServiceMultiResult<>(page.getTotalElements(), result);
}
List<HouseSubscribeDTO> subscribeDTOS = new ArrayList<>();
List<Long> houseIds = new ArrayList<>();
page.forEach(houseSubscribe -> {
subscribeDTOS.add(modelMapper.map(houseSubscribe, HouseSubscribeDTO.class));
houseIds.add(houseSubscribe.getHouseId());
});
Map<Long, HouseDTO> idToHouseMap = new HashMap<>();
Iterable<House> houses = houseRepository.findAll(houseIds);
houses.forEach(house -> {
idToHouseMap.put(house.getId(), modelMapper.map(house, HouseDTO.class));
});
for (HouseSubscribeDTO subscribeDTO : subscribeDTOS) {
Pair<HouseDTO, HouseSubscribeDTO> pair = Pair.of(idToHouseMap.get(subscribeDTO.getHouseId()), subscribeDTO);
result.add(pair);
}
return new ServiceMultiResult<>(page.getTotalElements(), result);
}
private ServiceMultiResult<HouseDTO> simpleQuery(RentSearch rentSearch) {
Sort sort = HouseSort.generateSort(rentSearch.getOrderBy(), rentSearch.getOrderDirection());
int page = rentSearch.getStart() / rentSearch.getSize();
Pageable pageable = new PageRequest(page, rentSearch.getSize(), sort);
Specification<House> specification = (root, criteriaQuery, criteriaBuilder) -> {
Predicate predicate = criteriaBuilder.equal(root.get("status"), HouseStatus.PASSES.getValue());
predicate = criteriaBuilder.and(predicate, criteriaBuilder.equal(root.get("cityEnName"), rentSearch.getCityEnName()));
if (HouseSort.DISTANCE_TO_SUBWAY_KEY.equals(rentSearch.getOrderBy())) {
predicate = criteriaBuilder.and(predicate, criteriaBuilder.gt(root.get(HouseSort.DISTANCE_TO_SUBWAY_KEY), -1));
}
return predicate;
};
Page<House> houses = houseRepository.findAll(specification, pageable);
List<HouseDTO> houseDTOS = new ArrayList<>();
List<Long> houseIds = new ArrayList<>();
Map<Long, HouseDTO> idToHouseMap = Maps.newHashMap();
houses.forEach(house -> {
HouseDTO houseDTO = modelMapper.map(house, HouseDTO.class);
houseDTO.setCover(this.cdnPrefix + house.getCover());
houseDTOS.add(houseDTO);
houseIds.add(house.getId());
idToHouseMap.put(house.getId(), houseDTO);
});
wrapperHouseList(houseIds, idToHouseMap);
return new ServiceMultiResult<>(houses.getTotalElements(), houseDTOS);
}
/**
* 渲染详细信息 及 标签
* @param houseIds
* @param idToHouseMap
*/
private void wrapperHouseList(List<Long> houseIds, Map<Long, HouseDTO> idToHouseMap) {
List<HouseDetail> details = houseDetailRepository.findAllByHouseIdIn(houseIds);
details.forEach(houseDetail -> {
HouseDTO houseDTO = idToHouseMap.get(houseDetail.getHouseId());
HouseDetailDTO detailDTO = modelMapper.map(houseDetail, HouseDetailDTO.class);
houseDTO.setHouseDetail(detailDTO);
});
List<HouseTag> houseTags = houseTagRepository.findAllByHouseIdIn(houseIds);
houseTags.forEach(houseTag -> {
HouseDTO house = idToHouseMap.get(houseTag.getHouseId());
house.getTags().add(houseTag.getName());
});
}
/**
* 图片对象列表信息填充
* @param form
* @param houseId
* @return
*/
private List<HousePicture> generatePictures(HouseForm form, Long houseId) {
List<HousePicture> pictures = new ArrayList<>();
if (form.getPhotos() == null || form.getPhotos().isEmpty()) {
return pictures;
}
for (PhotoForm photoForm : form.getPhotos()) {
HousePicture picture = new HousePicture();
picture.setHouseId(houseId);
picture.setCdnPrefix(cdnPrefix);
picture.setPath(photoForm.getPath());
picture.setWidth(photoForm.getWidth());
picture.setHeight(photoForm.getHeight());
pictures.add(picture);
}
return pictures;
}
/**
* 房源详细信息对象填充
* @param houseDetail
* @param houseForm
* @return
*/
private ServiceResult<HouseDTO> wrapperDetailInfo(HouseDetail houseDetail, HouseForm houseForm) {
Subway subway = subwayRepository.findOne(houseForm.getSubwayLineId());
if (subway == null) {
return new ServiceResult<>(false, "Not valid subway line!");
}
SubwayStation subwayStation = subwayStationRepository.findOne(houseForm.getSubwayStationId());
if (subwayStation == null || subway.getId() != subwayStation.getSubwayId()) {
return new ServiceResult<>(false, "Not valid subway station!");
}
houseDetail.setSubwayLineId(subway.getId());
houseDetail.setSubwayLineName(subway.getName());
houseDetail.setSubwayStationId(subwayStation.getId());
houseDetail.setSubwayStationName(subwayStation.getName());
houseDetail.setDescription(houseForm.getDescription());
houseDetail.setDetailAddress(houseForm.getDetailAddress());
houseDetail.setLayoutDesc(houseForm.getLayoutDesc());
houseDetail.setRentWay(houseForm.getRentWay());
houseDetail.setRoundService(houseForm.getRoundService());
houseDetail.setTraffic(houseForm.getTraffic());
return null;
}
}
里面需要设置一下redi的session会话:
我用的是本地的redis:
在config:中新建一个类:
RedisSessionConfig:
package liangliang.bigdata.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
/**
* 利用redis保存session会话
*/
@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 86400)
public class RedisSessionConfig {
@Bean
public RedisTemplate<String,String>redisTemplate(RedisConnectionFactory connectionFactory){
return new StringRedisTemplate(connectionFactory);
}
}
并且application.properties中需要设置redis:
这里面使用redis出了版本问题:
直接更换redis为3.0以上就可以!
以上给出的所有东西都是为了新增房源功能的开发需要:避免太多,这篇博客只有新增房源。
输入路由:登录后台中心添加房源:
上篇博客:BAT大牛亲授基于ElasticSearch的搜房网实战(第五章后台管理模块开发)
下篇博客:BAT大牛亲授基于ElasticSearch的搜房网实战(第六章 房源信息管理模块实现下)