dengsixing пре 10 месеци
родитељ
комит
97e9e57b15
24 измењених фајлова са 1376 додато и 33 уклоњено
  1. 27 0
      src/main/java/com/fdkankan/modeldemo/bean/TagBean.java
  2. 5 0
      src/main/java/com/fdkankan/modeldemo/constant/Constant.java
  3. 232 0
      src/main/java/com/fdkankan/modeldemo/constant/RedisKey.java
  4. 6 0
      src/main/java/com/fdkankan/modeldemo/entity/Scene.java
  5. 171 0
      src/main/java/com/fdkankan/modeldemo/entity/SceneEditControls.java
  6. 201 0
      src/main/java/com/fdkankan/modeldemo/entity/SceneEditInfo.java
  7. 159 0
      src/main/java/com/fdkankan/modeldemo/entity/SceneEditInfoExt.java
  8. 3 0
      src/main/java/com/fdkankan/modeldemo/entity/SceneFileMapping.java
  9. 18 0
      src/main/java/com/fdkankan/modeldemo/mapper/SceneEditControlsMapper.java
  10. 18 0
      src/main/java/com/fdkankan/modeldemo/mapper/SceneEditInfoExtMapper.java
  11. 18 0
      src/main/java/com/fdkankan/modeldemo/mapper/SceneEditInfoMapper.java
  12. 31 6
      src/main/java/com/fdkankan/modeldemo/mq/ConvertListener.java
  13. 17 0
      src/main/java/com/fdkankan/modeldemo/service/FYunFileService.java
  14. 17 0
      src/main/java/com/fdkankan/modeldemo/service/SceneEditControlsService.java
  15. 15 0
      src/main/java/com/fdkankan/modeldemo/service/SceneEditInfoExtService.java
  16. 16 0
      src/main/java/com/fdkankan/modeldemo/service/SceneEditInfoService.java
  17. 8 0
      src/main/java/com/fdkankan/modeldemo/service/SceneFileMappingService.java
  18. 104 0
      src/main/java/com/fdkankan/modeldemo/service/impl/FYunFileServiceImpl.java
  19. 20 0
      src/main/java/com/fdkankan/modeldemo/service/impl/SceneEditControlsServiceImpl.java
  20. 19 0
      src/main/java/com/fdkankan/modeldemo/service/impl/SceneEditInfoExtServiceImpl.java
  21. 20 0
      src/main/java/com/fdkankan/modeldemo/service/impl/SceneEditInfoServiceImpl.java
  22. 23 0
      src/main/java/com/fdkankan/modeldemo/service/impl/SceneFileMappingServiceImpl.java
  23. 171 24
      src/main/java/com/fdkankan/modeldemo/utils/ConvertUtil.java
  24. 57 3
      src/main/java/com/fdkankan/redis/RedisClient.java

+ 27 - 0
src/main/java/com/fdkankan/modeldemo/bean/TagBean.java

@@ -0,0 +1,27 @@
+package com.fdkankan.modeldemo.bean;
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/3/24
+ **/
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class TagBean {
+
+    private Long createTime;
+
+    private JSONObject tag;
+
+}

+ 5 - 0
src/main/java/com/fdkankan/modeldemo/constant/Constant.java

@@ -10,6 +10,11 @@ public class Constant {
      */
     public static final String IMG_VIEW_PATH =  "scene_view_data/%s/images/";
 
+    /**
+     * 用户目录
+     */
+    public static final String USER_VIEW_PATH =  "scene_view_data/%s/user/";
+
     public static final String REDIS_SCENE_CONVERT_ING = "scene:converting:%s";
 
 

+ 232 - 0
src/main/java/com/fdkankan/modeldemo/constant/RedisKey.java

@@ -0,0 +1,232 @@
+package com.fdkankan.modeldemo.constant;
+
+public class RedisKey {
+    /**
+     * 过期时间:1分钟
+     */
+    public static final int EXPIRE_TIME_1_MINUTE = 60;
+
+    /**
+     * 过期时间:5分钟
+     */
+    public static final int EXPIRE_TIME_5_MINUTE = 5*60;
+
+    /**
+     * 过期时间:10分钟
+     */
+    public static final int EXPIRE_TIME_10_MINUTE = 10*60;
+
+    /**
+     * 过期时间:30分钟
+     */
+    public static final int EXPIRE_TIME_30_MINUTE = 30*60;
+
+    /**
+     * 过期时间:2小时
+     */
+    public static final int EXPIRE_TIME_2_HOUR = 2*60*60;
+
+    /**
+     * 用户过期时间
+     */
+    public static final int USER_EXPIRE_TIME = 6*60*60;
+
+    /**
+     * 相机登陆7天有效期
+     */
+    public static final int CAMERA_EXPIRE_7_TIME = 7*24*60*60;
+
+    public static final String SYSTEM_PREFIX = "4dkankan";
+
+    /**
+     * 登录token
+     */
+    public static String TOKEN_USER = "token:type:%s:name:%s";
+
+    /**
+     * ssouser key
+     */
+    public static String SSO_USER = "sso_user:name:%s";
+    /**
+     * 开发者信息
+     */
+    public static String TM_DEVELOPER = "developer:appid:%s";
+
+    /**
+     * 场景浏览量
+     */
+    public static String SCENE_VISIT_CNT = "scene:visit:cnt";
+
+
+    /**
+     * 场景码池
+     */
+    public static String FDKANKAN_SCENE_NUMS = "4dkankan:scene:nums";
+
+
+    public static final String SCENE_BUILDING = SYSTEM_PREFIX+":scene:building:%s";
+
+    /**
+     * 场景下载进度
+     */
+    // TODO: 2022/3/29  这个是V3版本使用的key,V4版本稳定后,这个要删除
+    public static final String PREFIX_DOWNLOAD_PROGRESS="downloads:progress:%s";
+
+    /**
+     * 场景下载进度
+     */
+    public static final String PREFIX_DOWNLOAD_PROGRESS_V4="downloads:progress:v4:%s";
+
+    /**
+     * 即将要下载场景的场景码列表
+     */
+    public static final String DOWNLOAD_TASK="downloads:task";
+
+    /**
+     * 正在下载的场景码列表
+     */
+    public static final String SCENE_DOWNLOAD_ING="scene:downloads:ing";
+
+    /**
+     * 正在下载的场景码列表
+     */
+    public static final String SCENE_V3_DOWNLOAD_ING="scene:v3:downloads:ing";
+
+    /**
+     * scenejson缓存
+     */
+    public static final String SCENE_JSON = "scenejson:num:%s";
+
+    /**
+     * 场景热点hash列表
+     */
+    public static final String SCENE_HOT_DATA = "scene:hotdata:num:%s";
+
+    /**
+     * 热点icons数据列表
+     */
+    public static final String SCENE_HOT_ICONS = "scene:hoticons:num:%s";
+
+    /**
+     * 场景关联数据列表
+     */
+    public static final String SCENE_LINKPAN_DATA = "scene:LinkPan:num:%s";
+
+    /**
+     * 场景关联styles数据列表
+     */
+    public static final String SCENE_LINKPAN_STYLES = "scene:LinkPanStyles:num:%s";
+
+    /**
+     * 场景关联styles数据列表
+     */
+    public static final String SCENE_BILLBOARDS_STYLES = "scene:billboardsStyles:num:%s";
+
+    /**
+     * 场景指示牌数据列表
+     */
+    public static final String SCENE_BILLBOARDS = "scene:billboards:num:%s";
+
+    public static final String SCENE_CUT_MODEL = "scene:cutmodel:num:%s";
+
+    /**
+     * 场景下载任务列表
+     */
+    public static final String SCENE_DOWNLOADS_TASK_V4 = "scene:downloads:task:v4";
+
+    /**
+     * 场景升级进度
+     */
+    public static final String scene_upgrade_progress_num = "scene:upgrade:progress:num:%s";
+
+    /**
+     * v3版本user类型token
+     */
+    public static final String TOKEN_V3 = "token#%s";
+
+    /**
+     * user类型token
+     */
+    public static final String USER_TOKEN_KEY = "token#%s";
+
+    /**
+     * 场景协作管理
+     */
+    public static final String SCENE_COOPERATION_NUM_USERID = "scene:cooperation:num:userId";
+
+
+    /**
+     * 管理后台key
+     */
+    public static final String  MANAGE_MENU ="manage_menu";
+    public static final String  MANAGE_PERM_USER ="manage_perm_user:%s";
+    public static final String  MANAGE_ROLE_USER ="manage_role_user:%s";
+
+    /**
+     * 马赛克列表
+     */
+    public static final String SCENE_MOSAIC_DATA = "scene:mosaic:num:%s";
+
+    /**
+     * 滤镜列表
+     */
+    public static final String SCENE_filter_DATA = "scene:filter:num:%s";
+
+    /**
+     * 场景资源清理,查询场景limit下标
+     */
+    public static final String SCENE_CLEAN_INDEX = "scene:clean:index";
+
+    /**
+     * 上传matterprodata状态
+     */
+    public static final String SCENE_UPLOAD_MATTERPRO_NUM= "scene:upload:matterpro:num";
+
+    /**
+     * 人体抠图任务id
+     */
+    public static final String SCENE_BODY_SEGMENT= "scene:body:segment:uuid:%s";
+
+    /**
+     * 场景oss原始资源目录删除
+     */
+    public static final String SCENE_OSS_HOME_DIR_DELETE= "scene:oss:home:dir:delete:unicode:%s";
+
+    /**
+     * 场景oss原始资源目录上传
+     */
+    public static final String SCENE_OSS_HOME_DIR_UPLOAD= "scene:oss:home:dir:upload:unicode:%s";
+
+    /**
+     * 场景oss原始资源目录上传
+     */
+    public static final String SCENE_BUILD_EXPECT_TOTAL_TIME_NUM= "scene:build:expect:total:time:num:%s";
+
+    /**
+     * 场景oss原始资源目录上传
+     */
+    public static final String SCENE_BUILD_FINISH_NUM = "scene:build:finish:num:%s";
+
+    /**
+     * 场景oss原始资源目录上传
+     */
+    public static final String SINGLE_MODELING_SERVER_BUSY = "singleModelingServerBusy";
+
+    /**
+     * 打点系统应用id缓存
+     */
+    public static final String TRACK_APPID = "track:appid";
+
+    public static final String SCENE_DRAW = "scene:draw:num:%s";
+
+    public static String getNumStr(String num, Integer subgroup, String upTime, Integer cacheKeyHasTime){
+        if(cacheKeyHasTime == 0){
+            return num + "-" + subgroup;
+        }
+        return num + "-" + subgroup + "-" + upTime;
+    }
+
+
+
+
+}

+ 6 - 0
src/main/java/com/fdkankan/modeldemo/entity/Scene.java

@@ -76,6 +76,12 @@ public class Scene extends Model<Scene> {
     @TableField("EXTINGUISHER")
     private Integer extinguisher;
 
+    @TableField("UP_TIME_KEY")
+    private String upTimeKey;
+
+    @TableField("CACHE_KEY_HAS_TIME")
+    private Integer cacheKeyHasTime;
+
 
 //    @Override
 //    protected Serializable pkVal() {

+ 171 - 0
src/main/java/com/fdkankan/modeldemo/entity/SceneEditControls.java

@@ -0,0 +1,171 @@
+package com.fdkankan.modeldemo.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * <p>
+ *
+ * </p>
+ *
+ * @author
+ * @since 2024-10-09
+ */
+@Getter
+@Setter
+@TableName("t_scene_edit_controls")
+public class SceneEditControls implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * t_scene_edit_info表id
+     */
+    @TableField("edit_info_id")
+    private Long editInfoId;
+
+    /**
+     * 是否展示小地图(0-不展示,1-展示)
+     */
+    @TableField("show_map")
+    private Integer showMap;
+
+    /**
+     * 是否需要密码(0-不需要,1-需要)
+     */
+    @TableField("show_lock")
+    private Integer showLock;
+
+    /**
+     * 是否展示标题(0-不需要,1-需要)
+     */
+    @TableField(value = "show_title")
+    private Integer showTitle;
+
+    /**
+     * 是否展示漫游按钮(0-不需要,1-需要)
+     */
+    @TableField("show_panorama")
+    private Integer showPanorama;
+
+    /**
+     * 是否展示3D按钮(0-不需要,1-需要)
+     */
+    @TableField("show_dollhouse")
+    private Integer showDollhouse;
+
+    /**
+     * 是否展示2D按钮(0-不需要,1-需要)
+     */
+    @TableField("show_floorplan")
+    private Integer showFloorplan;
+
+    /**
+     * 是否展示VR(0-不需要,1-需要)
+     */
+    @TableField("show_vr")
+    private Integer showVr;
+
+    /**
+     * 是否展示自动导览(0-不需要,1-需要)
+     */
+    @TableField("show_tour")
+    private Integer showTour;
+
+    /**
+     * 是否展示测量线(0-不需要,1-需要)
+     */
+    @TableField("show_rule")
+    private Integer showRule;
+
+    /**
+     * 是否展示标尺(0-不需要,1-需要)
+     */
+    @TableField("show_scale")
+    private Integer showScale;
+
+    /**
+     * 是否展示分享场景(0-不需要,1-需要)
+     */
+    @TableField("show_share")
+    private Integer showShare;
+
+    /**
+     * 是否展示分享热点(0-不需要,1-需要)
+     */
+    @TableField("show_tagshare")
+    private Integer showTagshare;
+
+    /**
+     * 是否显示合照开关(0-不需要,1-需要)
+     */
+    @TableField("show_capture")
+    private Integer showCapture;
+
+    /**
+     * 是否显示多媒体标签标题(0-否,1-是)
+     */
+    @TableField("show_tag_title")
+    private Integer showTagTitle;
+
+    /**
+     * 是否显示指示牌标签标题(0-否,1-是)
+     */
+    @TableField("show_billboard_title")
+    private Integer showBillboardTitle;
+
+    /**
+     * 是否显示视频监控标签标题(0-否,1-是)
+     */
+    @TableField("show_camera_title")
+    private Integer showCameraTitle;
+
+    /**
+     * 是否显示场景关联标签标题(0-否,1-是)
+     */
+    @TableField("show_link_title")
+    private Integer showLinkTitle;
+
+    /**
+     * 是否显示空间绘制标题
+     */
+    @TableField("show_draw_title")
+    private Integer showDrawTitle;
+
+    /**
+     * 是否显示全部模型
+     */
+    @TableField("show_all_model")
+    private Integer showAllModel;
+
+    /**
+     * 创建时间
+     */
+    @TableField("create_time")
+    private Date createTime;
+
+    /**
+     * 更新时间
+     */
+    @TableField("update_time")
+    private Date updateTime;
+
+    /**
+     * A-有效,I-无效
+     */
+    @TableField("rec_status")
+    @TableLogic(value = "A", delval = "I")
+    private String recStatus;
+
+
+}

+ 201 - 0
src/main/java/com/fdkankan/modeldemo/entity/SceneEditInfo.java

@@ -0,0 +1,201 @@
+package com.fdkankan.modeldemo.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * <p>
+ *
+ * </p>
+ *
+ * @author
+ * @since 2024-10-09
+ */
+@Getter
+@Setter
+@TableName("t_scene_edit_info")
+public class SceneEditInfo implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    @TableField("scene_pro_id")
+    private Long sceneProId;
+
+    @TableField("scene_plus_id")
+    private Long scenePlusId;
+
+    /**
+     * 地面logo名称
+     */
+    @TableField("floor_logo")
+    private String floorLogo;
+
+    /**
+     * 地面logo大小
+     */
+    @TableField(value = "floor_logo_size")
+    private Integer floorLogoSize;
+
+    /**
+     * 地面logo文件名称
+     */
+    @TableField("floor_logo_file")
+    private String floorLogoFile;
+
+    /**
+     * 背景音乐名称
+     */
+    @TableField("music")
+    private String music;
+
+    /**
+     * 背景音乐文件名称
+     */
+    @TableField("music_file")
+    private String musicFile;
+
+    /**
+     * 浏览密码
+     */
+    @TableField("scene_password")
+    private String scenePassword;
+
+    /**
+     * 场景标题
+     */
+    @TableField("title")
+    private String title;
+
+    /**
+     * 场景描述
+     */
+    @TableField("description")
+    private String description;
+
+    /**
+     * 用户是否上传户型图(0-否,1-是)
+     */
+    @TableField("floor_plan_user")
+    private Integer floorPlanUser;
+
+    /**
+     * 是否有热点数据(0-否,1-是)
+     */
+    @TableField("tags")
+    private Integer tags;
+
+    /**
+     * 版本
+     */
+    @TableField("version")
+    private Integer version;
+
+    /**
+     * 图片版本
+     */
+    @TableField("img_version")
+    private Integer imgVersion;
+
+    /**
+     * 场景关联版本
+     */
+    @TableField("link_version")
+    private Integer linkVersion;
+
+    /**
+     * 是否上传模型
+     */
+    @TableField("is_upload_obj")
+    private Integer isUploadObj;
+
+    /**
+     * 重新建模的版本
+     */
+    @TableField("floor_edit_ver")
+    private Integer floorEditVer;
+
+    /**
+     * 正式发布重新建模的版本
+     */
+    @TableField("floor_publish_ver")
+    private Integer floorPublishVer;
+
+    /**
+     * 空间视频数据
+     */
+    @TableField("box_videos")
+    private String boxVideos;
+
+    /**
+     * 空间贴图数据
+     */
+    @TableField("box_photos")
+    private String boxPhotos;
+
+    /**
+     * 空间模型数据
+     */
+    @TableField("box_models")
+    private String boxModels;
+
+    /**
+     * 是否需要处理球幕视频
+     */
+    @TableField("build_video_status")
+    private Integer buildVideoStatus;
+
+    /**
+     * 初始点信息
+     */
+    @TableField("entry")
+    private String entry;
+
+    /**
+     * 加载logo名
+     */
+    @TableField("loading_logo")
+    private String loadingLogo;
+
+    /**
+     * 加载logo文件名
+     */
+    @TableField("loading_logo_file")
+    private String loadingLogoFile;
+
+    /**
+     * 用户上传自定义平面图数据
+     */
+    @TableField("floor_plan_upload")
+    private String floorPlanUpload;
+
+    /**
+     * 创建时间
+     */
+    @TableField("create_time")
+    private Date createTime;
+
+    /**
+     * 修改时间
+     */
+    @TableField("update_time")
+    private Date updateTime;
+
+    /**
+     * A-有效,I-无效
+     */
+    @TableField("rec_status")
+    @TableLogic(value = "A", delval = "I")
+    private String recStatus;
+
+
+}

+ 159 - 0
src/main/java/com/fdkankan/modeldemo/entity/SceneEditInfoExt.java

@@ -0,0 +1,159 @@
+package com.fdkankan.modeldemo.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * <p>
+ *
+ * </p>
+ *
+ * @author
+ * @since 2024-10-09
+ */
+@Getter
+@Setter
+@TableName("t_scene_edit_info_ext")
+public class SceneEditInfoExt implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    @TableField("scene_pro_id")
+    private Long sceneProId;
+
+    @TableField("scene_plus_id")
+    private Long scenePlusId;
+
+    @TableField("edit_info_id")
+    private Long editInfoId;
+
+    /**
+     * 户型角度
+     */
+    @TableField(value = "floor_plan_angle")
+    private Float floorPlanAngle;
+
+    /**
+     * 指南针角度
+     */
+    @TableField("floor_plan_compass")
+    private Float floorPlanCompass;
+
+    /**
+     * 大场景序号(随心装场景码)  原pro_edit表中的字段
+     */
+    @TableField("vr_num")
+    private String vrNum;
+
+    /**
+     * 是否有保存导览(0-否,1-是)
+     */
+    @TableField("tours")
+    private Integer tours;
+
+    /**
+     * 马赛克数据
+     */
+    @TableField("mosaics")
+    private String mosaics;
+
+    /**
+     * 是否有马赛克
+     */
+    @TableField("mosaic")
+    private Integer mosaic;
+
+    /**
+     * 水印文件名
+     */
+    @TableField("water_mark")
+    private String waterMark;
+
+    /**
+     * 是否有场景关联(0-否,1-是)
+     */
+    @TableField("links")
+    private Integer links;
+
+    /**
+     * 是否有滤镜(0-否,1-是)
+     */
+    @TableField("filters")
+    private Integer filters;
+
+    /**
+     * 风格滤镜数据
+     */
+    @TableField("roi_filter")
+    private String roiFilter;
+
+    /**
+     * 是否有监控摄像头(0-否,1-是)
+     */
+    @TableField("surveillances")
+    private Integer surveillances;
+
+    /**
+     * 二维码logo路径(oss相对路径)
+     */
+    @TableField("share_logo_img")
+    private String shareLogoImg;
+
+    /**
+     * 是否有指示牌(0-否,1-是)
+     */
+    @TableField("billboards")
+    private Integer billboards;
+
+    /**
+     * 是否有裁剪模型(0-否,1-是)
+     */
+    @TableField("cut_model")
+    private Integer cutModel;
+
+    /**
+     * 分享配置
+     */
+    @TableField("sns_info")
+    private String snsInfo;
+
+    /**
+     * 启动页信息
+     */
+    @TableField("started")
+    private String started;
+
+    /**
+     * 是否有空间绘制
+     */
+    @TableField("scene_draw")
+    private Integer sceneDraw;
+
+    /**
+     * 创建时间
+     */
+    @TableField("create_time")
+    private Date createTime;
+
+    /**
+     * 修改时间
+     */
+    @TableField("update_time")
+    private Date updateTime;
+
+    /**
+     * A-有效,I-无效
+     */
+    @TableField("rec_status")
+    @TableLogic(value = "A", delval = "I")
+    private String recStatus;
+
+
+}

+ 3 - 0
src/main/java/com/fdkankan/modeldemo/entity/SceneFileMapping.java

@@ -44,6 +44,9 @@ public class SceneFileMapping extends Model<SceneFileMapping> {
     @TableField("SUBGROUP")
     private Integer subgroup;
 
+    @TableField("UP_TIME")
+    private String upTime;
+
 
 //    @Override
 //    protected Serializable pkVal() {

+ 18 - 0
src/main/java/com/fdkankan/modeldemo/mapper/SceneEditControlsMapper.java

@@ -0,0 +1,18 @@
+package com.fdkankan.modeldemo.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fdkankan.modeldemo.entity.SceneEditControls;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author
+ * @since 2024-10-09
+ */
+@Mapper
+public interface SceneEditControlsMapper extends BaseMapper<SceneEditControls> {
+
+}

+ 18 - 0
src/main/java/com/fdkankan/modeldemo/mapper/SceneEditInfoExtMapper.java

@@ -0,0 +1,18 @@
+package com.fdkankan.modeldemo.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fdkankan.modeldemo.entity.SceneEditInfoExt;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author
+ * @since 2024-10-09
+ */
+@Mapper
+public interface SceneEditInfoExtMapper extends BaseMapper<SceneEditInfoExt> {
+
+}

+ 18 - 0
src/main/java/com/fdkankan/modeldemo/mapper/SceneEditInfoMapper.java

@@ -0,0 +1,18 @@
+package com.fdkankan.modeldemo.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fdkankan.modeldemo.entity.SceneEditInfo;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author
+ * @since 2024-10-09
+ */
+@Mapper
+public interface SceneEditInfoMapper extends BaseMapper<SceneEditInfo> {
+
+}

+ 31 - 6
src/main/java/com/fdkankan/modeldemo/mq/ConvertListener.java

@@ -140,16 +140,22 @@ public class ConvertListener{
         String dataSource = null;
         String convertIngKey = null;
         String convertType = null;
+        String upTimeStr = null;
+        String upTimeKey = null;
         try {
             String msg = new String(message.getBody(), StandardCharsets.UTF_8);
             log.info("msg:{}", msg);
             JSONObject jsonObject = JSON.parseObject(msg);
             stationCode = jsonObject.getString("stationCode");
             entityId = jsonObject.getString("entityId");
-            String upTimeStr = jsonObject.getString("upTime");
+            upTimeStr = jsonObject.getString("upTime");
             convertType = jsonObject.getString("convertType");
+            if(StrUtil.isEmpty(convertType)){
+                convertType = "standar";
+            }
             if(StrUtil.isNotEmpty(upTimeStr)){
                 upTime = DateUtil.parse(upTimeStr, DatePattern.NORM_DATETIME_PATTERN);
+                upTimeKey = upTimeStr.replaceAll("-", "").replace(" ", "").replaceAll(":", "");
             }
             fileList = jsonObject.getJSONArray("fileList");
             convertIngKey = String.format(Constant.REDIS_SCENE_CONVERT_ING, messageId);
@@ -168,11 +174,30 @@ public class ConvertListener{
             sceneConvertLog.setConverttype(convertType);
 
             if(convertType.equals("upTime")){//只更新上传时间
-                List<Scene> list = sceneService.list(new LambdaQueryWrapper<Scene>().eq(Scene::getNum, entityId).eq(Scene::getStationcode, stationCode).isNull(Scene::getUpTime));
+                List<Scene> list = sceneService.list(new LambdaQueryWrapper<Scene>().eq(Scene::getNum, entityId).eq(Scene::getStationcode, stationCode));
                 if(CollUtil.isNotEmpty(list)){
                     Date finalUpTime = upTime;
-                    list.stream().forEach(v->v.setUpTime(finalUpTime));
+                    String finalUpTimeKey = upTimeKey;
+                    list.stream().forEach(v->{
+                        v.setUpTime(finalUpTime);
+                        v.setUpTimeKey(finalUpTimeKey);
+                    });
                     sceneService.updateBatchById(list);
+
+                    List<SceneFileMapping> visionTxt = sceneFileMappingService.getByNumAndKey(list.get(0).getNum(), -1, "scene_view_data/" + list.get(0).getNum() + "/images/vision.txt");
+                    if(CollUtil.isNotEmpty(visionTxt)){
+                        visionTxt.stream().forEach(v -> v.setUpTime(finalUpTimeKey));
+                        sceneFileMappingService.updateBatchById(visionTxt);
+                    }
+
+                    for (Scene scene : list) {
+                        List<SceneFileMapping> sceneFileMappingList = sceneFileMappingService.getByNumAndSubgroup(scene.getNum(), scene.getSubgroup());
+                        if(CollUtil.isEmpty(sceneFileMappingList)){
+                            continue;
+                        }
+                        sceneFileMappingList.stream().forEach(v -> v.setUpTime(scene.getUpTimeKey()));
+                        sceneFileMappingService.updateBatchById(sceneFileMappingList);
+                    }
                 }
             }else{
                 //校验文件是否齐全
@@ -192,7 +217,7 @@ public class ConvertListener{
                 });
 
 
-                dataSource = baseZipPath + stationCode + "_" + entityId + "/";
+                dataSource = baseZipPath + stationCode + "_" + entityId + "_" + DateUtil.format(upTime, DatePattern.PURE_DATETIME_PATTERN) + "/";
                 String imagePath = dataSource + "images/";
                 String dataPath = dataSource + "data/";
                 String meshPath = dataPath + "mesh/";
@@ -240,7 +265,7 @@ public class ConvertListener{
                 });
 
                 //转换并上传文件
-                convertUtil.convert(dataSource, entityId, stationCode, upTime);
+                convertUtil.convert(dataSource, entityId, stationCode, upTime, convertType, upTimeKey);
             }
 
             sceneConvertLog.setStatus("1");
@@ -248,7 +273,7 @@ public class ConvertListener{
             sceneConvertLogService.save(sceneConvertLog);
 
         }catch (Exception e){
-            log.error("convert fail, stationCode:{}, roomId:{}", stationCode, entityId, e);
+            log.error("convert fail, stationCode:{}, roomId:{}, upTimeKey:{}", stationCode, entityId, upTimeKey, e);
             sceneConvertLog.setStatus("0");
             sceneConvertLog.setRemark(ExceptionUtil.stacktraceToString(e, 4000));
             sceneConvertLog.setTimeConsuming(String.valueOf(timeInterval.intervalSecond()));

+ 17 - 0
src/main/java/com/fdkankan/modeldemo/service/FYunFileService.java

@@ -0,0 +1,17 @@
+package com.fdkankan.modeldemo.service;
+
+import java.io.IOException;
+
+public interface FYunFileService {
+
+//    String getFileContent(String key, Integer subgroup, String upTime) throws IOException;
+
+    void uploadFile(String num, Integer subgroup, String upTime, byte[] data, String key);
+
+    void uploadFile(String num, Integer subgroup, String upTime, String path, String key);
+
+//    void deleteFile(String num, Integer subgroup, String upTime, String key);
+
+//    String downloadFile(String num, Integer subgroup, String upTime, String key, String dir, String fileName);
+
+}

+ 17 - 0
src/main/java/com/fdkankan/modeldemo/service/SceneEditControlsService.java

@@ -0,0 +1,17 @@
+package com.fdkankan.modeldemo.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fdkankan.modeldemo.entity.SceneEditControls;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author
+ * @since 2024-10-09
+ */
+public interface SceneEditControlsService extends IService<SceneEditControls> {
+
+
+}

+ 15 - 0
src/main/java/com/fdkankan/modeldemo/service/SceneEditInfoExtService.java

@@ -0,0 +1,15 @@
+package com.fdkankan.modeldemo.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fdkankan.modeldemo.entity.SceneEditInfoExt;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author
+ * @since 2024-10-09
+ */
+public interface SceneEditInfoExtService extends IService<SceneEditInfoExt> {
+}

+ 16 - 0
src/main/java/com/fdkankan/modeldemo/service/SceneEditInfoService.java

@@ -0,0 +1,16 @@
+package com.fdkankan.modeldemo.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fdkankan.modeldemo.entity.SceneEditInfo;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author
+ * @since 2024-10-09
+ */
+public interface SceneEditInfoService extends IService<SceneEditInfo> {
+
+}

+ 8 - 0
src/main/java/com/fdkankan/modeldemo/service/SceneFileMappingService.java

@@ -17,4 +17,12 @@ public interface SceneFileMappingService extends IService<SceneFileMapping> {
 
     List<SceneFileMapping> getByNumAndKey(String num, Integer subgroup, String key);
 
+    List<SceneFileMapping> getByNumAndSubgroup(String num, Integer subgroup);
+
+    List<SceneFileMapping> getByScene(String num, Integer subgroup, String upTimeKey, String key);
+
+    List<SceneFileMapping> getBySceneBatch(String num, Integer subgroup, String upTimeKey, List<String> keyList);
+
+    SceneFileMapping getByKey(String key, Integer subgroup, String upTime);
+
 }

+ 104 - 0
src/main/java/com/fdkankan/modeldemo/service/impl/FYunFileServiceImpl.java

@@ -0,0 +1,104 @@
+package com.fdkankan.modeldemo.service.impl;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.lang.UUID;
+import com.fdkankan.modeldemo.entity.SceneFileMapping;
+import com.fdkankan.modeldemo.httpclient.HttpClient;
+import com.fdkankan.modeldemo.service.FYunFileService;
+import com.fdkankan.modeldemo.service.SceneFileMappingService;
+import com.fdkankan.modeldemo.utils.FdfsUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.io.File;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import java.util.Objects;
+
+@Service
+public class FYunFileServiceImpl implements FYunFileService {
+
+    @Autowired
+    private SceneFileMappingService sceneFileMappingService;
+    @Resource
+    private HttpClient customHttpClient;
+
+    @Resource
+    private FdfsUtil fdfsUtil;
+
+
+//    @Override
+//    public String getFileContent(String key, Integer subgroup, String upTime) throws IOException {
+//        SceneFileMapping sceneFileMapping = sceneFileMappingService.getByKey(key, subgroup, upTime);
+//        if(Objects.isNull(sceneFileMapping)){
+//            return null;
+//        }
+//        String content = null;
+//        try (InputStream inputStream = customHttpClient.downloadFileToInputStream(sceneFileMapping.getUrl())){
+//            content =  IoUtil.read(inputStream, StandardCharsets.UTF_8);
+//        }
+//        return content;
+//    }
+
+    @Override
+    public void uploadFile(String num, Integer subgroup, String upTime, byte[] data, String key) {
+        String suffix = "." + FileUtil.getSuffix(key);
+        File tempFile = FileUtil.createTempFile(UUID.fastUUID().toString(), suffix, new File("/temp"), true);
+        FileUtil.writeBytes(data, tempFile);
+        Map<String, String> mapping = fdfsUtil.uploadFile(tempFile.getAbsolutePath());
+        //添加记录
+        SceneFileMapping sceneFileMapping =  sceneFileMappingService.getByKey(key, subgroup, upTime);
+        if(Objects.isNull(sceneFileMapping)){
+            sceneFileMapping = new SceneFileMapping();
+        }
+        sceneFileMapping.setNum(num);
+        sceneFileMapping.setFileid(mapping.get("file_id"));
+        sceneFileMapping.setUrl(mapping.get("http_url"));
+        sceneFileMapping.setKey(key);
+        sceneFileMapping.setSubgroup(subgroup);
+        sceneFileMapping.setUpTime(upTime);
+        sceneFileMappingService.saveOrUpdate(sceneFileMapping);
+    }
+
+    @Override
+    public void uploadFile(String num, Integer subgroup, String upTime, String path, String key) {
+        Map<String, String> mapping = fdfsUtil.uploadFile(path);
+        //添加记录
+        SceneFileMapping sceneFileMapping =  sceneFileMappingService.getByKey(key,subgroup,upTime);
+        if(Objects.isNull(sceneFileMapping)){
+            sceneFileMapping = new SceneFileMapping();
+        }
+        sceneFileMapping.setNum(num);
+        sceneFileMapping.setFileid(mapping.get("file_id"));
+        sceneFileMapping.setUrl(mapping.get("http_url"));
+        sceneFileMapping.setKey(key);
+        sceneFileMapping.setSubgroup(subgroup);
+        sceneFileMapping.setUpTime(upTime);
+        sceneFileMappingService.saveOrUpdate(sceneFileMapping);
+    }
+
+//    @Override
+//    public void deleteFile(String num, Integer subgroup, String upTime, String key) {
+//        sceneFileMappingService.delByNumAndKey(num, subgroup, upTime, key);
+//    }
+
+    public static void main(String[] args) {
+        String suffix = "." + FileUtil.getSuffix("/sxx/ttt/adf.json");
+        File tempFile = FileUtil.createTempFile(UUID.fastUUID().toString(), suffix, new File("D:\\test2"), true);
+        FileUtil.writeBytes("nihsd灌灌灌灌".getBytes(StandardCharsets.UTF_8), tempFile);
+    }
+
+//    @Override
+//    public String downloadFile(String num, Integer subgroup, String upTime, String key, String dir, String fileName) {
+//        SceneFileMapping sceneFileMapping = sceneFileMappingService.getByKey(key, subgroup,upTime);
+//        if(Objects.isNull(sceneFileMapping)){
+//            return null;
+//        }
+//        customHttpClient.downloadFile(sceneFileMapping.getUrl(), dir, fileName);
+//        if(dir.endsWith("/")){
+//            dir += "/";
+//        }
+//         return dir + fileName;
+//    }
+}

+ 20 - 0
src/main/java/com/fdkankan/modeldemo/service/impl/SceneEditControlsServiceImpl.java

@@ -0,0 +1,20 @@
+package com.fdkankan.modeldemo.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fdkankan.modeldemo.entity.SceneEditControls;
+import com.fdkankan.modeldemo.mapper.SceneEditControlsMapper;
+import com.fdkankan.modeldemo.service.SceneEditControlsService;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author
+ * @since 2024-10-09
+ */
+@Service
+public class SceneEditControlsServiceImpl extends ServiceImpl<SceneEditControlsMapper, SceneEditControls> implements SceneEditControlsService {
+
+}

+ 19 - 0
src/main/java/com/fdkankan/modeldemo/service/impl/SceneEditInfoExtServiceImpl.java

@@ -0,0 +1,19 @@
+package com.fdkankan.modeldemo.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fdkankan.modeldemo.entity.SceneEditInfoExt;
+import com.fdkankan.modeldemo.mapper.SceneEditInfoExtMapper;
+import com.fdkankan.modeldemo.service.SceneEditInfoExtService;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author
+ * @since 2024-10-09
+ */
+@Service
+public class SceneEditInfoExtServiceImpl extends ServiceImpl<SceneEditInfoExtMapper, SceneEditInfoExt> implements SceneEditInfoExtService {
+}

+ 20 - 0
src/main/java/com/fdkankan/modeldemo/service/impl/SceneEditInfoServiceImpl.java

@@ -0,0 +1,20 @@
+package com.fdkankan.modeldemo.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fdkankan.modeldemo.entity.SceneEditInfo;
+import com.fdkankan.modeldemo.mapper.SceneEditInfoMapper;
+import com.fdkankan.modeldemo.service.SceneEditInfoService;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author
+ * @since 2024-10-09
+ */
+@Service
+public class SceneEditInfoServiceImpl extends ServiceImpl<SceneEditInfoMapper, SceneEditInfo> implements SceneEditInfoService {
+
+}

+ 23 - 0
src/main/java/com/fdkankan/modeldemo/service/impl/SceneFileMappingServiceImpl.java

@@ -24,4 +24,27 @@ public class SceneFileMappingServiceImpl extends ServiceImpl<SceneFileMappingMap
     public List<SceneFileMapping> getByNumAndKey(String num, Integer subgroup, String key) {
         return this.list(new LambdaQueryWrapper<SceneFileMapping>().eq(SceneFileMapping::getNum, num).eq(SceneFileMapping::getKey, key).eq(SceneFileMapping::getSubgroup, subgroup));
     }
+
+    @Override
+    public List<SceneFileMapping> getByNumAndSubgroup(String num, Integer subgroup) {
+        return this.list(new LambdaQueryWrapper<SceneFileMapping>().eq(SceneFileMapping::getNum, num).eq(SceneFileMapping::getSubgroup, subgroup));
+    }
+
+    @Override
+    public List<SceneFileMapping> getByScene(String num, Integer subgroup, String upTimeKey, String key) {
+        return this.list(new LambdaQueryWrapper<SceneFileMapping>().eq(SceneFileMapping::getNum, num).eq(SceneFileMapping::getKey, key).eq(SceneFileMapping::getSubgroup, subgroup).eq(SceneFileMapping::getUpTime, upTimeKey));
+    }
+
+    @Override
+    public List<SceneFileMapping> getBySceneBatch(String num, Integer subgroup, String upTimeKey, List<String> keyList) {
+        return this.list(new LambdaQueryWrapper<SceneFileMapping>().eq(SceneFileMapping::getNum, num).in(SceneFileMapping::getKey, keyList).eq(SceneFileMapping::getSubgroup, subgroup).eq(SceneFileMapping::getUpTime, upTimeKey));
+    }
+
+    @Override
+    public SceneFileMapping getByKey(String key, Integer subgroup, String upTime) {
+        return this.getOne(new LambdaQueryWrapper<SceneFileMapping>()
+                .eq(SceneFileMapping::getKey, key)
+                .eq(SceneFileMapping::getSubgroup, subgroup)
+                .eq(SceneFileMapping::getUpTime, upTime));
+    }
 }

+ 171 - 24
src/main/java/com/fdkankan/modeldemo/utils/ConvertUtil.java

@@ -11,18 +11,21 @@ import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.fdkankan.modeldemo.bean.SceneEditControlsBean;
 import com.fdkankan.modeldemo.bean.SceneJsonBean;
+import com.fdkankan.modeldemo.bean.TagBean;
 import com.fdkankan.modeldemo.constant.Constant;
-import com.fdkankan.modeldemo.entity.Scene;
-import com.fdkankan.modeldemo.entity.SceneFileMapping;
-import com.fdkankan.modeldemo.service.SceneFileMappingService;
-import com.fdkankan.modeldemo.service.SceneService;
+import com.fdkankan.modeldemo.constant.RedisKey;
+import com.fdkankan.modeldemo.entity.*;
+import com.fdkankan.modeldemo.service.*;
+import com.fdkankan.redis.RedisClient;
 import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
 import java.io.File;
+import java.nio.charset.StandardCharsets;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -37,6 +40,16 @@ public class ConvertUtil {
     private SceneFileMappingService sceneFileMappingService;
     @Resource
     private FdfsUtil fdfsUtil;
+    @Resource
+    private RedisClient redisClient;
+    @Autowired
+    private SceneEditInfoService sceneEditInfoService;
+    @Autowired
+    private SceneEditInfoExtService sceneEditInfoExtService;
+    @Autowired
+    private SceneEditControlsService sceneEditControlsService;
+    @Resource
+    private FYunFileService fYunFileService;
 
     private static String[] convertVisableHandler(JSONArray visibles, Map<Integer, String> uuidMap){
         int size = visibles.size();
@@ -69,7 +82,7 @@ public class ConvertUtil {
         }
     }
 
-    public Map<String, String> convert(String sourcePath, String num, String stationCode, Date upTime) throws Exception {
+    public Map<String, String> convert(String sourcePath, String num, String stationCode, Date upTime, String convertType, String upTimeKey) throws Exception {
 
         Map<String, String> map = new HashMap<>();
         String dataViewPath = String.format(Constant.DATA_VIEW_PATH, num);
@@ -201,7 +214,7 @@ public class ConvertUtil {
         }
 //            FileUtil.copy(sourcePath + "images/vision.txt", targetImagePath + "/vision.txt", true);
         //单独上传一份全的vision.txt
-        this.uploadVisionTxt(num, sourcePath + "images/vision.txt");
+        this.uploadVisionTxt(num, upTimeKey, sourcePath + "images/vision.txt");
 
         //生成vison.modeldata
         String visionStr = FileUtil.readUtf8String(sourcePath + "images/vision.txt");
@@ -273,7 +286,7 @@ public class ConvertUtil {
 
             String finalRoomId = num;
             map.keySet().stream().forEach(key->{
-                List<SceneFileMapping> sceneFileMappingList = sceneFileMappingService.getByNumAndKey(finalRoomId, subgroup, key);
+                List<SceneFileMapping> sceneFileMappingList = sceneFileMappingService.getByScene(finalRoomId, subgroup, upTimeKey, key);
                 if(CollUtil.isNotEmpty(sceneFileMappingList)){
                     List<String> deleteIds = sceneFileMappingList.stream().map(v -> v.getId()).collect(Collectors.toList());
                     sceneFileMappingService.removeByIds(deleteIds);
@@ -285,23 +298,25 @@ public class ConvertUtil {
                 sceneFileMapping.setUrl(mapping.get("http_url"));
                 sceneFileMapping.setKey(key);
                 sceneFileMapping.setSubgroup(subgroup);
+                sceneFileMapping.setUpTime(upTimeKey);
                 sceneFileMappingService.save(sceneFileMapping);
             });
 
 
-            List<Scene> list = sceneService.list(new LambdaQueryWrapper<Scene>().eq(Scene::getNum, num).eq(Scene::getSubgroup, subgroup));
-            Scene scene = null;
-            if(CollUtil.isEmpty(list)){
-                scene = new Scene();
-            }else{
-                if(list.size() > 1){
-                    sceneService.remove(new LambdaQueryWrapper<Scene>().eq(Scene::getNum, num));
-                    scene = new Scene();
-                }else{
-                    scene = list.get(0);
-                }
-            }
-
+//            List<Scene> list = sceneService.list(new LambdaQueryWrapper<Scene>().eq(Scene::getNum, num).eq(Scene::getSubgroup, subgroup).eq(Scene::getUpTimeKey, upTimeKey));
+//            Scene scene = null;
+//            if(CollUtil.isEmpty(list)){
+//                scene = new Scene();
+//            }else{
+//                if(list.size() > 1){
+//                    sceneService.remove(new LambdaQueryWrapper<Scene>().eq(Scene::getNum, num));
+//                    scene = new Scene();
+//                }else{
+//                    scene = list.get(0);
+//                }
+//            }
+
+            Scene scene = new Scene();
             scene.setTitle(sceneBashInfo.getString("title"));
             scene.setNum(num);
             scene.setFloorlogosize(100);
@@ -316,19 +331,150 @@ public class ConvertUtil {
             scene.setUpTime(upTime);
             scene.setAlgorithmTime(new Date());
             scene.setExtinguisher(extinguisher);
+            scene.setUpTimeKey(upTimeKey);
+            scene.setCacheKeyHasTime(1);
             sceneService.saveOrUpdate(scene);
+
+            SceneEditInfo sceneEditInfo = new SceneEditInfo();
+            sceneEditInfo.setScenePlusId(scene.getId());
+            sceneEditInfo.setTitle(scene.getTitle());
+            sceneEditInfo.setDescription(scene.getDescription());
+            sceneEditInfoService.save(sceneEditInfo);
+
+            SceneEditInfoExt sceneEditInfoExt = new SceneEditInfoExt();
+            sceneEditInfoExt.setScenePlusId(scene.getId());
+            sceneEditInfoExt.setEditInfoId(sceneEditInfo.getId());
+            sceneEditInfoExtService.save(sceneEditInfoExt);
+
+            SceneEditControls sceneEditControls = new SceneEditControls();
+            sceneEditControls.setEditInfoId(sceneEditInfo.getId());
+            sceneEditControlsService.save(sceneEditControls);
+
+            //同步热点
+            this.keepHot(scene, sceneEditInfo);
         }
 
+        return map;
+    }
+
+    private void keepHot(Scene scene, SceneEditInfo sceneEditInfo){
 
-//        map.put(imgViewPath + "vision.modeldata", sourcePath + "images/visionmodeldata.txt");
+        String num = scene.getNum();
+        String upTimeKey = scene.getUpTimeKey();
+        Integer subgroup = scene.getSubgroup();
 
+        //查询最新的历史场景
+        Scene preScene = sceneService.getOne(new LambdaQueryWrapper<Scene>()
+                .eq(Scene::getNum, num)
+                .eq(Scene::getSubgroup, subgroup)
+                .lt(Scene::getUpTimeKey, upTimeKey)
+                .orderByDesc(Scene::getUpTimeKey).last("limit 1"));
+        if(Objects.isNull(preScene)){
+            return;
+        }
 
+        //查询是否有热点
+        String key = String.format(RedisKey.SCENE_HOT_DATA, RedisKey.getNumStr(num, subgroup, preScene.getUpTimeKey(), preScene.getCacheKeyHasTime()));
+        Map<String, String> allTagsMap = redisClient.hmget("scene", key);
+        if(CollUtil.isEmpty(allTagsMap)){
+            return;
+        }
 
+        //如果有热点,复制redis和涉及的图片
+        String newKey = String.format(RedisKey.SCENE_HOT_DATA, RedisKey.getNumStr(num, subgroup, upTimeKey, scene.getCacheKeyHasTime()));
+        redisClient.hmset("scene", newKey, allTagsMap);
 
+        sceneEditInfo.setTags(1);
+        sceneEditInfoService.updateById(sceneEditInfo);
 
-        return map;
+        //组装热点数据
+        for (String sid : allTagsMap.keySet()) {
+            String hot = allTagsMap.get(sid);
+            JSONObject jsonObject = JSON.parseObject(hot);
+            String type = jsonObject.getString("type");
+            if(!"image".equals(type) && !"video".equals(type) && !"audio".equals(type)){
+                continue;
+            }
+            JSONObject media = jsonObject.getJSONObject("media");
+            JSONArray mediaDetail = media.getJSONArray(type);
+            List<String> keyList = mediaDetail.stream().map(v -> {
+                JSONObject content = (JSONObject) v;
+                String src = content.getString("src");
+                return String.format(Constant.USER_VIEW_PATH, num) + src;
+            }).collect(Collectors.toList());
+
+            if(CollUtil.isNotEmpty(keyList)){
+                List<SceneFileMapping> fileMappingList = sceneFileMappingService.getBySceneBatch(num, subgroup, preScene.getUpTimeKey(), keyList);
+                if(CollUtil.isNotEmpty(fileMappingList)){
+                    fileMappingList.stream().forEach(v->{
+                        v.setId(null);
+                        v.setUpTime(upTimeKey);
+                    });
+                    sceneFileMappingService.saveBatch(fileMappingList);
+                }
+            }
+        }
+
+        //发布热点
+        this.publicHotData(scene);
+
+        //复制icon
+        //查询缓存是否包含icons
+        String iconKey = String.format(RedisKey.SCENE_HOT_ICONS, RedisKey.getNumStr(num, subgroup, preScene.getUpTimeKey() ,preScene.getCacheKeyHasTime()));
+        Set<String> icons = redisClient.sGet("scene", iconKey);
+        if(CollUtil.isNotEmpty(icons)){
+
+            String newIconKey = String.format(RedisKey.SCENE_HOT_ICONS, RedisKey.getNumStr(num, subgroup, scene.getUpTimeKey() ,scene.getCacheKeyHasTime()));
+            redisClient.sSet("scene", newIconKey, icons);
+
+            List<String> iconFileList = icons.stream().map(i -> {
+                return String.format(Constant.USER_VIEW_PATH, num) + i;
+            }).collect(Collectors.toList());
+
+            if(CollUtil.isNotEmpty(iconFileList)){
+                List<SceneFileMapping> fileMappingList = sceneFileMappingService.getBySceneBatch(num, subgroup, preScene.getUpTimeKey(), iconFileList);
+                if(CollUtil.isNotEmpty(fileMappingList)){
+                    fileMappingList.stream().forEach(v->{
+                        v.setId(null);
+                        v.setUpTime(scene.getUpTimeKey());
+                    });
+                    sceneFileMappingService.saveBatch(fileMappingList);
+                }
+            }
+        }
+    }
+
+    private void publicHotData(Scene scene) {
+        String sceneNum = scene.getNum();
+        Integer subgroup = scene.getSubgroup();
+        String upTime  = scene.getUpTimeKey();
+        Integer cacheKeyHasTime = scene.getCacheKeyHasTime();
+
+        String hotDataKey = String.format(RedisKey.SCENE_HOT_DATA, RedisKey.getNumStr(sceneNum, subgroup,upTime,cacheKeyHasTime));
+        Map<String, String> hotMap = redisClient.hmget("scene", hotDataKey);
+
+        JSONArray tags = new JSONArray();
+        if(CollUtil.isNotEmpty(hotMap)){
+            List<TagBean> tagBeanList = hotMap.entrySet().stream().map(entry -> {
+                JSONObject jsonObject = JSON.parseObject(entry.getValue());
+                return TagBean.builder()
+                        .createTime(jsonObject.getLong("createTime"))
+                        .tag(jsonObject).build();
+            }).collect(Collectors.toList());
+            //按创建时间倒叙排序
+            tagBeanList.sort(Comparator.comparingLong(TagBean::getCreateTime).reversed());
+
+            //移除createTime字段
+            tagBeanList.stream().forEach(tagBean -> {
+                tags.add(tagBean.getTag());
+            });
+        }
+
+        String hotJsonPath = String.format(Constant.USER_VIEW_PATH, sceneNum) + "hot.json";
+        fYunFileService.uploadFile(sceneNum, subgroup, upTime, tags.toString().getBytes(StandardCharsets.UTF_8), hotJsonPath);
     }
 
+
     private Integer getExtinguisher(String num, String sourcePath, Map<String, String> map){
         int extinguisher = 0;
         try {
@@ -367,9 +513,9 @@ public class ConvertUtil {
         return extinguisher;
     }
 
-    private void uploadVisionTxt(String num, String localVisionTxtPath){
+    private void uploadVisionTxt(String num, String upTime, String localVisionTxtPath){
         String key = String.format(Constant.IMG_VIEW_PATH, num) + "vision.txt";
-        List<SceneFileMapping> sceneFileMappingList =  sceneFileMappingService.list(new LambdaQueryWrapper<SceneFileMapping>().eq(SceneFileMapping::getKey, key).eq(SceneFileMapping::getNum, num).eq(SceneFileMapping::getSubgroup, -1));
+        List<SceneFileMapping> sceneFileMappingList = sceneFileMappingService.getByScene(num, -1, upTime, key);
         if(CollUtil.isNotEmpty(sceneFileMappingList)){
             List<String> deleteIds = sceneFileMappingList.stream().map(v -> v.getId()).collect(Collectors.toList());
             sceneFileMappingService.removeByIds(deleteIds);
@@ -381,6 +527,7 @@ public class ConvertUtil {
         sceneFileMapping.setUrl(mapping.get("http_url"));
         sceneFileMapping.setKey(key);
         sceneFileMapping.setSubgroup(-1);
+        sceneFileMapping.setUpTime(upTime);
         sceneFileMappingService.save(sceneFileMapping);
     }
 

+ 57 - 3
src/main/java/com/fdkankan/redis/RedisClient.java

@@ -6,9 +6,7 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
+import java.util.*;
 
 @Component
 public class RedisClient {
@@ -19,6 +17,15 @@ public class RedisClient {
 
     public final static String url_str_del = "/redis/string/delete";
 
+    public final static String url_hash_hscan = "/redis/hash/hscan";
+
+    public final static String url_hash_add = "/redis/hash/add";
+
+    public final static String url_set_getall = "/redis/set/getall";
+
+    public final static String url_set_add = "/redis/set/add";
+
+
     @Value("${redis.host}")
     private String host;
 
@@ -68,8 +75,55 @@ public class RedisClient {
         return jsonObject.getString("data");
     }
 
+    public Map<String, String> hmget(String serverName,  String key){
+        String url = host + url_hash_hscan;
+        Map<String, Object> params = new HashMap<>();
+        params.put("key", this.genKey(serverName, key));
+        JSONObject jsonObject = httpClient.postJson(url, params);
+
+        JSONObject data = jsonObject.getJSONObject("data");
+        // 转换为Map<String, String>
+        Map<String, String> map = new HashMap<>();
+        for (String k : data.keySet()) {
+            map.put(k, data.getString(k));
+        }
+        return map;
+    }
+
+    public void hmset(String serverName, String key, Map<String, String> values){
+        String url = host + url_hash_add;
+        Map<String, Object> params = new HashMap<>();
+        params.put("key", this.genKey(serverName, key));
+        params.put("values", values);
+        JSONObject jsonObject = httpClient.postJson(url, params);
+    }
+
+    public Set<String> sGet(String serverName, String key){
+        String url = host + url_set_getall;
+        Map<String, Object> params = new HashMap<>();
+        params.put("key", this.genKey(serverName, key));
+        JSONObject jsonObject = httpClient.postJson(url, params);
+        List<String> data = jsonObject.getJSONArray("data").toJavaList(String.class);
+        return new HashSet<>(data);
+    }
+
+    public void sSet(String serverName, String key, Set<String> values){
+        String url = host + url_set_add;
+        Map<String, Object> params = new HashMap<>();
+        params.put("key", this.genKey(serverName, key));
+        params.put("values", values);
+        JSONObject jsonObject = httpClient.postJson(url, params);
+//        if(Objects.isNull(jsonObject) || !"0".equals(jsonObject.getString("status"))){
+//            throw new RuntimeException("redis add set error");
+//        }
+    }
+
     private String genKey(String key){
          return sysCode + "_" + serverName + "_" + key;
     }
+
+    private String genKey(String serverName, String key){
+        return sysCode + "_" + serverName + "_" + key;
+    }
 }