|
@@ -6,7 +6,10 @@ import com.alibaba.fastjson.JSONObject;
|
|
|
import com.fdkanfang.common.constant.ConstantFilePath;
|
|
|
import com.fdkanfang.common.constant.MsgCode;
|
|
|
import com.fdkanfang.common.constant.TypeCode;
|
|
|
+import com.fdkanfang.common.enums.ImageResolutionRate;
|
|
|
+import com.fdkanfang.common.enums.ResultCodeEnum;
|
|
|
import com.fdkanfang.common.exception.BaseRuntimeException;
|
|
|
+import com.fdkanfang.common.exception.CommonBaseException;
|
|
|
import com.fdkanfang.common.model.PageDto;
|
|
|
import com.fdkanfang.common.util.*;
|
|
|
import com.fdkanfang.domain.backend.*;
|
|
@@ -26,15 +29,15 @@ import io.swagger.annotations.ApiImplicitParams;
|
|
|
import io.swagger.annotations.ApiOperation;
|
|
|
import lombok.extern.log4j.Log4j2;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
-import org.apache.commons.lang3.builder.ToStringExclude;
|
|
|
import org.apache.shiro.authz.annotation.Logical;
|
|
|
+import org.apache.shiro.authz.annotation.RequiresPermissions;
|
|
|
import org.apache.shiro.authz.annotation.RequiresRoles;
|
|
|
-import org.junit.Test;
|
|
|
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
|
|
import org.springframework.beans.BeanUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
+import org.springframework.util.CollectionUtils;
|
|
|
import org.springframework.web.bind.annotation.*;
|
|
|
import org.springframework.web.multipart.MultipartFile;
|
|
|
import tk.mybatis.mapper.entity.Condition;
|
|
@@ -138,64 +141,36 @@ public class HouseController extends BaseController {
|
|
|
@RequiresRoles(value = {"admin", "edit", "upload"}, logical = Logical.OR)
|
|
|
@ApiOperation("新增或修改房源信息 + 垂直校验")
|
|
|
@PostMapping(value = "save", consumes = {"multipart/form-data"})
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
public R save(HouseDto param){
|
|
|
|
|
|
if(StringUtils.isBlank(param.getDistrictName())){
|
|
|
log.error("小区名称不能为空");
|
|
|
return new R(MsgCode.e_COMMON_3001, "小区名称不能为空");
|
|
|
}
|
|
|
-
|
|
|
-// if(StringUtils.isBlank(param.getAddress())){
|
|
|
-// log.error("地址不能为空");
|
|
|
-// return new R(MsgCode.e_COMMON_3001, "地址不能为空");
|
|
|
-// }
|
|
|
-
|
|
|
- if(StringUtils.isBlank(param.getUnitType())){
|
|
|
- log.error("户型不能为空");
|
|
|
- return new R(MsgCode.e_COMMON_3001, "户型不能为空");
|
|
|
- }
|
|
|
-
|
|
|
- if(StringUtils.isBlank(param.getArea())){
|
|
|
- log.error("面积不能为空");
|
|
|
- return new R(MsgCode.e_COMMON_3001, "面积不能为空");
|
|
|
- }
|
|
|
-
|
|
|
- if(StringUtils.isBlank(param.getOrientation())){
|
|
|
- log.error("朝向不能为空");
|
|
|
- return new R(MsgCode.e_COMMON_3001, "朝向不能为空");
|
|
|
- }
|
|
|
-
|
|
|
- if (param.getFloor() == null) {
|
|
|
- log.error("楼层不能为空");
|
|
|
- return new R(MsgCode.e_COMMON_3001, "楼层不能为空");
|
|
|
+ if(null == param.getFloor() || !StringUtils.isNoneBlank(param.getUnitType() , param.getArea() , param.getOrientation())){
|
|
|
+ return new R(MsgCode.e_COMMON_3001, "楼层/户型/面积/朝向不能为空");
|
|
|
}
|
|
|
|
|
|
- boolean flag = false;
|
|
|
+ boolean isNewAdd = false;
|
|
|
HouseEntity house = null;
|
|
|
if (param.getId() == null) {
|
|
|
house = new HouseEntity();
|
|
|
house.setUserId(JWTUtil.getUserId(getToken()));
|
|
|
param.setId(null);
|
|
|
BeanUtils.copyProperties(param, house);
|
|
|
-
|
|
|
Integer byMaxNum = houseService2.findByMaxNum();
|
|
|
-
|
|
|
-
|
|
|
// 用于第一条数据
|
|
|
byMaxNum = (byMaxNum == null)? 10000:byMaxNum;
|
|
|
-
|
|
|
String sceneCode = getSceneCode();
|
|
|
house.setNum(byMaxNum + 1);
|
|
|
house.setSceneCode(sceneCode);
|
|
|
house.setWebSite(domain+"?m="+sceneCode);
|
|
|
house.setFilePath(OUTPATH + sceneCode);
|
|
|
-
|
|
|
houseService2.save(house);
|
|
|
-
|
|
|
SceneProEntity sceneProEntity = new SceneProEntity();
|
|
|
sceneProEntity.setNum(house.getSceneCode());
|
|
|
sceneProService.save(sceneProEntity);
|
|
|
-
|
|
|
SceneProEditEntity sceneProEditEntity = new SceneProEditEntity();
|
|
|
sceneProEditEntity.setProId(sceneProEntity.getId());
|
|
|
// 默认是1
|
|
@@ -204,7 +179,7 @@ public class HouseController extends BaseController {
|
|
|
sceneProEditEntity.setM3dVisi(1);
|
|
|
sceneProEditEntity.setMeasureVisi(1);
|
|
|
sceneProEditService.save(sceneProEditEntity);
|
|
|
- flag = true;
|
|
|
+ isNewAdd = true;
|
|
|
} else {
|
|
|
house = houseService2.findById(param.getId());
|
|
|
if (house == null) {
|
|
@@ -213,10 +188,8 @@ public class HouseController extends BaseController {
|
|
|
}
|
|
|
BeanUtils.copyProperties(param, house);
|
|
|
house.setUpdateTime(new Date());
|
|
|
-
|
|
|
houseService2.update(house);
|
|
|
}
|
|
|
-
|
|
|
// 处理上传图片
|
|
|
MultipartFile[] files = param.getFiles();
|
|
|
if (files == null || files.length <= 0) {
|
|
@@ -224,31 +197,32 @@ public class HouseController extends BaseController {
|
|
|
return new R(MsgCode.e_COMMON_3100, MsgCode.msg_COMMON_3100);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
// 只有新增是才保存图片,修改时另外处理
|
|
|
- if (flag) {
|
|
|
-
|
|
|
+ if (isNewAdd) {
|
|
|
//场景码
|
|
|
String sceneCode = house.getSceneCode();
|
|
|
-
|
|
|
- boolean flagQ = false;
|
|
|
-
|
|
|
+ boolean needSendMqMsg = false;
|
|
|
String directoryName = OUTPATH + sceneCode + File.separator + "input_img"+ File.separator;
|
|
|
FileUtil.mkdir(directoryName);
|
|
|
-
|
|
|
-
|
|
|
HashMap<String, String> ossVerticalImageHighMap = new HashMap<>();
|
|
|
HashMap<String, String> ossVerticalImageLowMap = new HashMap<>();
|
|
|
-
|
|
|
-
|
|
|
String imageHighPath = null;
|
|
|
String imageLowPath = null;
|
|
|
-
|
|
|
+ //照片分辨率,以最高的为准
|
|
|
+ ImageResolutionRate maxResolutionRate = null;
|
|
|
+ int imageResolutionRateSort = 0;
|
|
|
for (MultipartFile file : files) {
|
|
|
ImageEntity image = new ImageEntity();
|
|
|
String filename = file.getOriginalFilename();
|
|
|
- assert filename != null;
|
|
|
+ if(StringUtils.isBlank(filename)){
|
|
|
+ throw new CommonBaseException(ResultCodeEnum.D100 , "文件名不能为空");
|
|
|
+ }
|
|
|
+ if(filename.contains(".JPG")){
|
|
|
+ int index = filename.lastIndexOf(".");
|
|
|
+ String fileNameWithoutPostfix = filename.substring(0 , index);
|
|
|
+ filename = fileNameWithoutPostfix + ".jpg";
|
|
|
+ log.info("照片的格式写成了大写,需要转成小写:{}" , filename);
|
|
|
+ }
|
|
|
// 检查一下,测试时,可能会没有"_"
|
|
|
if (!filename.contains("_")) {
|
|
|
log.error("filename: {}", filename);
|
|
@@ -262,55 +236,50 @@ public class HouseController extends BaseController {
|
|
|
// 获取图片房间类型
|
|
|
String imageType = StringUtils.substringBefore(filename, "_");
|
|
|
|
|
|
- // 本地图片保存位置
|
|
|
- String filePath = directoryName + filename;
|
|
|
+ // 本地图片保存位置: /root/data/kanfang/场景码/input_img/xxxx.jpg
|
|
|
+ String fileFullPath = directoryName + filename;
|
|
|
|
|
|
imageHighPath = OUTPATH + sceneCode + "/output_img/" + filename;
|
|
|
imageLowPath = OUTPATH + sceneCode + "/output_img_low/" + filename;
|
|
|
-
|
|
|
- image.setFileName(filename);
|
|
|
-
|
|
|
- // 这个参数给前端用,只要有文件名就可以了
|
|
|
- image.setPath(filePath);
|
|
|
-
|
|
|
- image.setLocalPath(filePath);
|
|
|
- image.setHouseId(house.getId());
|
|
|
// 提前把算法的图片路径存到数据库,但不代表算法运行成功,最后好是要看house的状态;
|
|
|
String ossVerticalHighPath = ConstantFilePath.OSS_IMAGE_PATH+ sceneCode+"/pan/high/"+ filename;
|
|
|
String ossVerticalLowPath = ConstantFilePath.OSS_IMAGE_PATH+ sceneCode+"/pan/low/"+ filename;
|
|
|
-
|
|
|
image.setVerticalPath(ossVerticalHighPath);
|
|
|
-
|
|
|
+ image.setFileName(filename);
|
|
|
+ // 这个参数给前端用,只要有文件名就可以了
|
|
|
+ image.setPath(fileFullPath);
|
|
|
+ image.setLocalPath(fileFullPath);
|
|
|
+ image.setHouseId(house.getId());
|
|
|
// 默认所有图片都是一楼
|
|
|
image.setFloor(1);
|
|
|
image.setType(imageType);
|
|
|
-
|
|
|
-
|
|
|
try {
|
|
|
- FileUtils.bigFileWrite(file.getInputStream(), filePath);
|
|
|
+ //将图片保存到本地指定目录filePath eg: /root/data/kanfang/d_9iRDUgn3l/input_img/xxx.jpg
|
|
|
+ int resolutionRate = FileUtils.downloanAndGetResolutionRate(file.getInputStream(), fileFullPath , false);
|
|
|
+ maxResolutionRate = ImageResolutionRate.getResolutionRateByRate(resolutionRate);
|
|
|
+ image.setResolutionRate(null != maxResolutionRate ? maxResolutionRate.name() : "TWO_K");
|
|
|
imageService2.save(image);
|
|
|
-
|
|
|
// 封装垂直校验后的图片到信息到oss
|
|
|
ossVerticalImageHighMap.put(imageHighPath, ossVerticalHighPath);
|
|
|
ossVerticalImageLowMap.put(imageLowPath, ossVerticalLowPath);
|
|
|
- flagQ = true;
|
|
|
-
|
|
|
+ needSendMqMsg = true;
|
|
|
} catch (IOException e) {
|
|
|
- flagQ = false;
|
|
|
- e.printStackTrace();
|
|
|
+ needSendMqMsg = false;
|
|
|
+ log.error("保存照片到本地和持久化image对象出现异常:{}" , e);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (flagQ) {
|
|
|
-
|
|
|
+ if (needSendMqMsg) {
|
|
|
HashMap<Object, Object> mqMap = new HashMap<>();
|
|
|
-
|
|
|
mqMap.put("ossImageHigh", ossVerticalImageHighMap);
|
|
|
mqMap.put("ossImageLow", ossVerticalImageLowMap);
|
|
|
mqMap.put("id", house.getId());
|
|
|
mqMap.put("basePath", OUTPATH);
|
|
|
- log.info("houseId: {}", house.getId());
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+ mqMap.put("dataDescribe", "");
|
|
|
+ log.info("houseId: {}", house.getId());
|
|
|
//发消息到mq
|
|
|
rabbitTemplate.convertAndSend(RabbitConfig.VERTICAL_EXCHANGE, RabbitConfig.VERTICAL_QUEUE_ROUTING, mqMap);
|
|
|
}
|
|
@@ -363,10 +332,12 @@ public class HouseController extends BaseController {
|
|
|
}
|
|
|
|
|
|
|
|
|
- if ("upload".equals(roleKey) && houseEntity.getStatus() != 0) {
|
|
|
- log.error("只有upload, 房源id!=0,审批中的房源不能删除");
|
|
|
- return new R(MsgCode.e_COMMON_3002,"没有权限删除房源,存在审批中的房源");
|
|
|
|
|
|
+ if ("upload".equals(roleKey)) {
|
|
|
+ if(null != houseEntity.getAuditResult() && houseEntity.getAuditResult().compareTo(1) == 0){
|
|
|
+ log.error("只有upload, 房源id!=0,审批通过的房源不能删除");
|
|
|
+ return new R(MsgCode.e_COMMON_3002,"审批通过的房源不能删除");
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
if ("edit".equals(roleKey)) {
|
|
@@ -510,6 +481,7 @@ public class HouseController extends BaseController {
|
|
|
@RequiresRoles(value = {"admin", "edit"}, logical = Logical.OR)
|
|
|
@ApiOperation("生成模型")
|
|
|
@PostMapping("rsa/pano")
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
public R rsaPano(@Valid @RequestBody PanoDto param) throws Exception {
|
|
|
log.info("run rsaPano");
|
|
|
|
|
@@ -517,20 +489,15 @@ public class HouseController extends BaseController {
|
|
|
log.error("参数为空");
|
|
|
return new R(50001, "error");
|
|
|
}
|
|
|
-
|
|
|
HouseEntity house = houseService2.findById(param.getHouseId());
|
|
|
if (house == null) {
|
|
|
log.error("房源不存在: {}", param.getHouseId());
|
|
|
return new R(MsgCode.e_COMMON_3002, MsgCode.msg_COMMON_3002);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
String sceneCode = house.getSceneCode();
|
|
|
|
|
|
-
|
|
|
boolean flagQ = false;
|
|
|
-
|
|
|
// data/kanfang/10001/pano
|
|
|
String savePath = OUTPATH + sceneCode + "/" + TypeCode.SCENE_PANO;
|
|
|
// 检查场景码对应的pano文件夹是否存在,存在则删除里面的内容(用户从新编辑场景)
|
|
@@ -539,25 +506,45 @@ public class HouseController extends BaseController {
|
|
|
log.info("删除旧目录重新计算: {}", sceneCode);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
log.warn("savePath: {}", savePath);
|
|
|
String sourcePath = savePath + "/extras/";
|
|
|
try {
|
|
|
|
|
|
-
|
|
|
-
|
|
|
FileUtils.createDir(sourcePath);
|
|
|
-
|
|
|
- // 目前data.json 是空的,算法要使用, 放到场景目录外面
|
|
|
- String resource = FileUtils.getResource();
|
|
|
- // pano.json:算法提供
|
|
|
- resource = resource + "static/pano.json";
|
|
|
- String content = FileUtils.readFile(resource);
|
|
|
- FileUtils.fileWriter(content, savePath + "/data.json");
|
|
|
- log.warn("dataPath: {}", savePath + "/data.json");
|
|
|
-
|
|
|
-
|
|
|
+/*
|
|
|
+ /***
|
|
|
+ * 以下字段为给算法部传递的参数(data.json),用于生成模型和
|
|
|
+ * 照片,提供前端使用,完整的参数如下:
|
|
|
+ * {
|
|
|
+ * "split_type": "SPLIT_V5",
|
|
|
+ * "skybox_type": "SKYBOX_V5",
|
|
|
+ * "extras": {
|
|
|
+ * "has_vision_txt": true,
|
|
|
+ * "has_floorplan_json": true,
|
|
|
+ * "has_source_images": true
|
|
|
+ * }
|
|
|
+ * }
|
|
|
+ * */
|
|
|
+ String content = "";
|
|
|
+ //生成data.json供算法部使用
|
|
|
+ JSONObject dataJson = new JSONObject();
|
|
|
+ dataJson.put("split_type", "SPLIT_V5");
|
|
|
+ String imageResolution = checkImageResolutionRate(house);
|
|
|
+ if(ImageResolutionRate.TWO_K.name().equals(imageResolution)){
|
|
|
+ //2 K 照片
|
|
|
+ dataJson.put("skybox_type", "SKYBOX_V7");
|
|
|
+ }else{
|
|
|
+ //4 k照片
|
|
|
+ dataJson.put("skybox_type", "SKYBOX_V6");
|
|
|
+ }
|
|
|
+ dataJson.put("extras", null);
|
|
|
+ JSONObject extrasJson = new JSONObject();
|
|
|
+ extrasJson.put("has_vision_txt" , true);
|
|
|
+ extrasJson.put("has_floorplan_json" , true);
|
|
|
+ extrasJson.put("has_source_images" , true);
|
|
|
+ dataJson.put("extras" , extrasJson);
|
|
|
+ FileUtils.fileWriter(dataJson.toJSONString(), savePath + "/data.json");
|
|
|
+ log.warn("dataJson的生成路径: {}", savePath + "/data.json");
|
|
|
|
|
|
// 解析json
|
|
|
JSONObject original = JSON.parseObject(param.getContent());
|
|
@@ -581,6 +568,7 @@ public class HouseController extends BaseController {
|
|
|
FileUtils.fileWriter(vision, sourcePath + "vision.txt");
|
|
|
|
|
|
|
|
|
+
|
|
|
log.info("floorplan.json生成完成");
|
|
|
log.info("vision.txt生成完成");
|
|
|
|
|
@@ -651,6 +639,34 @@ public class HouseController extends BaseController {
|
|
|
return new R(MsgCode.SUCCESS_CODE, house);
|
|
|
}
|
|
|
|
|
|
+ private String checkImageResolutionRate(HouseEntity houseEntity){
|
|
|
+ if(null == houseEntity || null == houseEntity.getId()){
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ List<ImageEntity> imageEntities = imageService2.findByHouseId(houseEntity.getId());
|
|
|
+ if(CollectionUtils.isEmpty(imageEntities)){
|
|
|
+ log.error("房源[{}]下面无照片,默认返回2k的分辨率");
|
|
|
+ return ImageResolutionRate.TWO_K.name();
|
|
|
+ }
|
|
|
+ int sort = 0;
|
|
|
+ ImageResolutionRate maxResolution = null;
|
|
|
+ for (ImageEntity imageEntity : imageEntities){
|
|
|
+ if(StringUtils.isBlank(imageEntity.getResolutionRate())){
|
|
|
+ log.warn("房源[{}]的照片[{}]没有设置照片分辨率,跳过" , houseEntity.getId() , imageEntity.getId());
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ ImageResolutionRate curResolution = ImageResolutionRate.getResolutionByName(imageEntity.getResolutionRate());
|
|
|
+ if(null != curResolution){
|
|
|
+ if(curResolution.getOrder() > sort){
|
|
|
+ sort = curResolution.getOrder();
|
|
|
+ maxResolution = curResolution;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ log.info("房源[{}]的照片最大的分辨率为:{}" , houseEntity.getId() , null != maxResolution ? maxResolution.name() :"空值");
|
|
|
+ return null != maxResolution ? maxResolution.name() : ImageResolutionRate.TWO_K.name();
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
/***
|
|
|
* 获取唯一场景码
|
|
@@ -674,12 +690,6 @@ public class HouseController extends BaseController {
|
|
|
}
|
|
|
|
|
|
|
|
|
- public static void main(String[] args) {
|
|
|
- String path = "C:\\Users\\Administrator\\Desktop\\test\\d_9iRDUgn3l\\pano";
|
|
|
- boolean file = FileUtil.isDirectory(path);
|
|
|
- System.out.println(file);
|
|
|
- FileUtil.del(path);
|
|
|
- }
|
|
|
|
|
|
|
|
|
}
|