소스 검색

场景下载

dengsixing 4 년 전
부모
커밋
48db964216
100개의 변경된 파일13687개의 추가작업 그리고 0개의 파일을 삭제
  1. 71 0
      4dkankan-center-scene-download/pom.xml
  2. 29 0
      4dkankan-center-scene-download/src/main/java/com/fdkankan/scene/download/SceneDownloadApplication.java
  3. 29 0
      4dkankan-center-scene-download/src/main/java/com/fdkankan/scene/download/bean/DownLoadProgressBean.java
  4. 27 0
      4dkankan-center-scene-download/src/main/java/com/fdkankan/scene/download/bean/DownLoadTaskBean.java
  5. 28 0
      4dkankan-center-scene-download/src/main/java/com/fdkankan/scene/download/bean/ImageType.java
  6. 27 0
      4dkankan-center-scene-download/src/main/java/com/fdkankan/scene/download/bean/ImageTypeDetail.java
  7. 55 0
      4dkankan-center-scene-download/src/main/java/com/fdkankan/scene/download/config/TaskPoolConfig.java
  8. 80 0
      4dkankan-center-scene-download/src/main/java/com/fdkankan/scene/download/config/TestController.java
  9. 25 0
      4dkankan-center-scene-download/src/main/java/com/fdkankan/scene/download/schedule/ScheduleJob.java
  10. 15 0
      4dkankan-center-scene-download/src/main/java/com/fdkankan/scene/download/service/ISceneDownLoadService.java
  11. 51 0
      4dkankan-center-scene-download/src/main/java/com/fdkankan/scene/download/service/impl/CheckProgressRunnerImpl.java
  12. 53 0
      4dkankan-center-scene-download/src/main/java/com/fdkankan/scene/download/service/impl/SceneDownLoadServiceImpl.java
  13. 439 0
      4dkankan-center-scene-download/src/main/java/com/fdkankan/scene/download/service/impl/SceneDownloadHandlerServiceImpl.java
  14. 45 0
      4dkankan-center-scene-download/src/main/resources/bootstrap.yml
  15. 269 0
      4dkankan-center-scene-download/src/main/resources/logback-spring.xml
  16. BIN
      4dkankan-center-scene-download/src/main/resources/static/audio/01.mp3
  17. BIN
      4dkankan-center-scene-download/src/main/resources/static/audio/02.mp3
  18. BIN
      4dkankan-center-scene-download/src/main/resources/static/audio/03.mp3
  19. BIN
      4dkankan-center-scene-download/src/main/resources/static/audio/04.mp3
  20. BIN
      4dkankan-center-scene-download/src/main/resources/static/audio/05.mp3
  21. BIN
      4dkankan-center-scene-download/src/main/resources/static/audio/06.mp3
  22. BIN
      4dkankan-center-scene-download/src/main/resources/static/audio/07.mp3
  23. BIN
      4dkankan-center-scene-download/src/main/resources/static/audio/08.mp3
  24. 1 0
      4dkankan-center-scene-download/src/main/resources/static/css/chunk-3d475e12.dd51d2d0.css
  25. 1 0
      4dkankan-center-scene-download/src/main/resources/static/css/chunk-74f12a8c.3ccaf059.css
  26. 1 0
      4dkankan-center-scene-download/src/main/resources/static/css/chunk-abf2a2d8.9f49428d.css
  27. 1 0
      4dkankan-center-scene-download/src/main/resources/static/css/chunk-b8031520.64b751b4.css
  28. 3 0
      4dkankan-center-scene-download/src/main/resources/static/css/chunk-common.2afe10cf.css
  29. 1 0
      4dkankan-center-scene-download/src/main/resources/static/css/chunk-e7bdf3ce.cb9c32d3.css
  30. 1 0
      4dkankan-center-scene-download/src/main/resources/static/css/chunk-ed3be54e.29cea110.css
  31. 1 0
      4dkankan-center-scene-download/src/main/resources/static/css/chunk-vendors.a7bbc042.css
  32. 539 0
      4dkankan-center-scene-download/src/main/resources/static/css/fire-control/demo.css
  33. 6243 0
      4dkankan-center-scene-download/src/main/resources/static/css/fire-control/demo_index.html
  34. BIN
      4dkankan-center-scene-download/src/main/resources/static/css/fire-control/demo_index.html.gz
  35. 1073 0
      4dkankan-center-scene-download/src/main/resources/static/css/fire-control/iconfont.css
  36. BIN
      4dkankan-center-scene-download/src/main/resources/static/css/fire-control/iconfont.eot
  37. 1 0
      4dkankan-center-scene-download/src/main/resources/static/css/fire-control/iconfont.js
  38. BIN
      4dkankan-center-scene-download/src/main/resources/static/css/fire-control/iconfont.js.gz
  39. 1857 0
      4dkankan-center-scene-download/src/main/resources/static/css/fire-control/iconfont.json
  40. 818 0
      4dkankan-center-scene-download/src/main/resources/static/css/fire-control/iconfont.svg
  41. BIN
      4dkankan-center-scene-download/src/main/resources/static/css/fire-control/iconfont.ttf
  42. BIN
      4dkankan-center-scene-download/src/main/resources/static/css/fire-control/iconfont.woff
  43. BIN
      4dkankan-center-scene-download/src/main/resources/static/css/fire-control/iconfont.woff2
  44. 539 0
      4dkankan-center-scene-download/src/main/resources/static/css/reserve/demo.css
  45. 860 0
      4dkankan-center-scene-download/src/main/resources/static/css/reserve/demo_index.html
  46. BIN
      4dkankan-center-scene-download/src/main/resources/static/css/reserve/demo_index.html.gz
  47. 137 0
      4dkankan-center-scene-download/src/main/resources/static/css/reserve/iconfont.css
  48. BIN
      4dkankan-center-scene-download/src/main/resources/static/css/reserve/iconfont.eot
  49. 1 0
      4dkankan-center-scene-download/src/main/resources/static/css/reserve/iconfont.js
  50. BIN
      4dkankan-center-scene-download/src/main/resources/static/css/reserve/iconfont.js.gz
  51. 219 0
      4dkankan-center-scene-download/src/main/resources/static/css/reserve/iconfont.json
  52. 116 0
      4dkankan-center-scene-download/src/main/resources/static/css/reserve/iconfont.svg
  53. BIN
      4dkankan-center-scene-download/src/main/resources/static/css/reserve/iconfont.ttf
  54. BIN
      4dkankan-center-scene-download/src/main/resources/static/css/reserve/iconfont.woff
  55. BIN
      4dkankan-center-scene-download/src/main/resources/static/css/reserve/iconfont.woff2
  56. 1 0
      4dkankan-center-scene-download/src/main/resources/static/css/smobile.32ca698d.css
  57. 1 0
      4dkankan-center-scene-download/src/main/resources/static/css/spc.7b981504.css
  58. 15 0
      4dkankan-center-scene-download/src/main/resources/static/dll/vendor.smobile.84ca42ff.js
  59. BIN
      4dkankan-center-scene-download/src/main/resources/static/dll/vendor.smobile.84ca42ff.js.gz
  60. 14 0
      4dkankan-center-scene-download/src/main/resources/static/dll/vendor.spc.230960a0.js
  61. BIN
      4dkankan-center-scene-download/src/main/resources/static/dll/vendor.spc.230960a0.js.gz
  62. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/0.a1bd0fb0.png
  63. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/0.ef3ccb8f.png
  64. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/1.93501122.png
  65. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/1.d3e65825.png
  66. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/2.c9287ece.png
  67. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/End.png
  68. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/End_128.png
  69. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/End_unable.png
  70. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/End_unable_128.png
  71. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/apps/fire-control/avatar_default.png
  72. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/apps/fire-control/fire_appendix@2x.png
  73. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/apps/fire-control/fire_building.png
  74. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/apps/fire-control/fire_bus.png
  75. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/apps/fire-control/fire_cancel@2x.png
  76. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/apps/fire-control/fire_exit@2x.png
  77. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/apps/fire-control/fire_mic_off@2x.png
  78. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/apps/fire-control/fire_mic_on@2x.png
  79. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/apps/fire-control/fire_other.png
  80. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/apps/fire-control/fire_pen_off@2x.png
  81. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/apps/fire-control/fire_pen_on@2x.png
  82. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/apps/fire-control/fire_recycle.png
  83. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/apps/fire-control/fire_share@2x.png
  84. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/apps/fire-control/fire_vr@2x.png
  85. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/apps/fire-control/reserv_return.png
  86. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/apps/fire/D5aeUSngt/卫生间.jpg
  87. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/apps/fire/D5aeUSngt/厨房.jpg
  88. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/apps/fire/D5aeUSngt/大堂.jpg
  89. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/apps/fire/MEzMZYcFh/主卧.jpg
  90. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/apps/fire/MEzMZYcFh/卫生间.jpg
  91. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/apps/fire/MEzMZYcFh/客卧.jpg
  92. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/apps/fire/MEzMZYcFh/客厅.jpg
  93. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/apps/fire/MEzMZYcFh/晾衣间.jpg
  94. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/apps/fire/XXNkdefa6/大厅.jpg
  95. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/apps/fire/r1Pwypv0K/主卧.jpg
  96. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/apps/fire/r1Pwypv0K/卫生间.jpg
  97. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/apps/fire/r1Pwypv0K/厨房.jpg
  98. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/apps/fire/r1Pwypv0K/客厅.jpg
  99. BIN
      4dkankan-center-scene-download/src/main/resources/static/img/apps/fire/r1Pwypv0K/晾衣间.jpg
  100. 0 0
      4dkankan-center-scene-download/src/main/resources/static/img/apps/fire/r1Pwypv0K/晾衣间阳台.jpg

+ 71 - 0
4dkankan-center-scene-download/pom.xml

@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <parent>
+    <artifactId>4dkankan-parent</artifactId>
+    <groupId>com.fdkankan</groupId>
+    <version>2.0.0-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>4dkankan-center-scene-download</artifactId>
+
+
+  <dependencies>
+
+    <dependency>
+      <groupId>com.fdkankan</groupId>
+      <artifactId>4dkankan-common</artifactId>
+      <version>2.0.0-SNAPSHOT</version>
+    </dependency>
+
+    <dependency>
+      <groupId>com.fdkankan</groupId>
+      <artifactId>4dkankan-utils-redis</artifactId>
+      <version>2.0.0-SNAPSHOT</version>
+    </dependency>
+
+
+    <dependency>
+      <groupId>com.fdkankan</groupId>
+      <artifactId>4dkankan-utils-fyun</artifactId>
+      <version>2.0.0-SNAPSHOT</version>
+    </dependency>
+
+
+<!--    <dependency>-->
+<!--      <groupId>org.projectlombok</groupId>-->
+<!--      <artifactId>lombok</artifactId>-->
+<!--    </dependency>-->
+
+
+    <dependency>
+      <groupId>com.alibaba.csp</groupId>
+      <artifactId>sentinel-datasource-nacos</artifactId>
+      <version>1.7.2</version>
+    </dependency>
+
+
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-maven-plugin</artifactId>
+      </plugin>
+
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <testFailureIgnore>true</testFailureIgnore>
+        </configuration>
+      </plugin>
+    </plugins>
+
+  </build>
+
+
+</project>

+ 29 - 0
4dkankan-center-scene-download/src/main/java/com/fdkankan/scene/download/SceneDownloadApplication.java

@@ -0,0 +1,29 @@
+package com.fdkankan.scene.download;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/2/22
+ **/
+@SpringBootApplication
+@EnableScheduling
+@ComponentScan(basePackages = {"com.fdkankan.*"})
+@RefreshScope
+@EnableAsync
+public class SceneDownloadApplication {
+    public static void main(String[] args) {
+        SpringApplication.run(SceneDownloadApplication.class, args);
+    }
+}
+
+

+ 29 - 0
4dkankan-center-scene-download/src/main/java/com/fdkankan/scene/download/bean/DownLoadProgressBean.java

@@ -0,0 +1,29 @@
+package com.fdkankan.scene.download.bean;
+
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * <p>
+ * 场景下载进度
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/2/22
+ **/
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class DownLoadProgressBean implements Serializable {
+
+    private String url;
+
+    private Integer percent;
+
+    private Integer status;
+
+}

+ 27 - 0
4dkankan-center-scene-download/src/main/java/com/fdkankan/scene/download/bean/DownLoadTaskBean.java

@@ -0,0 +1,27 @@
+package com.fdkankan.scene.download.bean;
+
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/2/22
+ **/
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class DownLoadTaskBean implements Serializable {
+
+    private String num;
+
+    private String type;
+
+}

+ 28 - 0
4dkankan-center-scene-download/src/main/java/com/fdkankan/scene/download/bean/ImageType.java

@@ -0,0 +1,28 @@
+package com.fdkankan.scene.download.bean;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/2/24
+ **/
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class ImageType {
+
+    private String name;
+
+    private String size;
+
+    private String[] ranges;
+
+}

+ 27 - 0
4dkankan-center-scene-download/src/main/java/com/fdkankan/scene/download/bean/ImageTypeDetail.java

@@ -0,0 +1,27 @@
+package com.fdkankan.scene.download.bean;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/2/24
+ **/
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class ImageTypeDetail {
+
+    private String i;
+    private String j;
+    private String x;
+    private String y;
+
+}

+ 55 - 0
4dkankan-center-scene-download/src/main/java/com/fdkankan/scene/download/config/TaskPoolConfig.java

@@ -0,0 +1,55 @@
+package com.fdkankan.scene.download.config;
+
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorCompletionService;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.client.ClientHttpRequestFactory;
+import org.springframework.http.client.SimpleClientHttpRequestFactory;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/2/22
+ **/
+@Configuration
+public class TaskPoolConfig {
+
+    @Bean("sceneDownLoadExecutror")
+    public ThreadPoolTaskExecutor sceneDownLoadExecutror(){
+        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
+        taskExecutor.setCorePoolSize(3);
+        taskExecutor.setMaxPoolSize(3);
+        taskExecutor.setQueueCapacity(3);
+        taskExecutor.setKeepAliveSeconds(60);
+        taskExecutor.setThreadNamePrefix("sceneDownLoadThread--");
+        taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
+        taskExecutor.setAwaitTerminationSeconds(60);
+        return taskExecutor;
+    }
+
+//    @Bean
+//    public ExecutorCompletionService completionService(ThreadPoolTaskExecutor sceneDownLoadExecutror){
+//        return new ExecutorCompletionService<Integer>(sceneDownLoadExecutror);
+//    }
+
+    @Bean
+    public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
+        return new RestTemplate(factory);
+    }
+
+    @Bean
+    public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
+        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
+        factory.setReadTimeout(5000);//ms
+        factory.setConnectTimeout(15000);//ms
+        return factory;
+    }
+
+}

+ 80 - 0
4dkankan-center-scene-download/src/main/java/com/fdkankan/scene/download/config/TestController.java

@@ -0,0 +1,80 @@
+package com.fdkankan.scene.download.config;
+
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.alibaba.fastjson.JSON;
+import com.fdkankan.common.constant.ServerCode;
+import com.fdkankan.common.response.ResultData;
+import com.fdkankan.fyun.oss.UploadToOssUtil;
+import com.fdkankan.redis.util.RedisUtil;
+import com.fdkankan.scene.download.bean.DownLoadTaskBean;
+import com.fdkankan.scene.download.service.impl.SceneDownloadHandlerServiceImpl;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/2/24
+ **/
+@RestController
+@RequestMapping("/test")
+@Slf4j
+public class TestController {
+
+    @Value("${download.config.server-url}")
+    private String serverUrl;
+
+    @Autowired
+    private RestTemplate restTemplate;
+
+    @Autowired
+    UploadToOssUtil uploadToOssUtil;
+
+    @Autowired
+    SceneDownloadHandlerServiceImpl downloadHandlerService;
+    @Autowired
+    RedisUtil redisUtil;
+
+    @GetMapping("/test")
+    public String test() throws Exception{
+//        Map<String, String> param = new HashMap<>();
+//        param.put("num", "t-YhBCzQr");
+//        String getInfoStr = restTemplate.postForObject(serverUrl + "api/scene/getInfo?num=t-YhBCzQr", param, String.class);
+//
+//        ResultData resultData = JSONUtil.toBean(getInfoStr, ResultData.class);
+//        if(resultData == null || ServerCode.SUCCESS.code() != resultData.getCode()){
+//            log.error("getInfo请求失败,url:" + serverUrl + "api/scene/getInfo?num=t-YhBCzQr");
+//        }
+//
+//        JSONObject dataJson = JSONUtil.parseObj(resultData.getData());
+//        dataJson.set("sceneScheme", 3);
+//        dataJson.set("needKey", 0);
+//        dataJson.set("sceneKey","");
+
+//        List<String> strings = uploadToOssUtil.listKeysFromAli("data/datat-ieXdyGl6Md");
+//        for (String string : strings) {
+//            System.out.println(string);
+//        }
+
+        redisUtil.lLeftPush("downloads:task:v4", JSON
+            .toJSONString(DownLoadTaskBean.builder().num("t-5YwC6wb").type("local").build()));
+        downloadHandlerService.download4Ali();
+
+//        List<String> strings = uploadToOssUtil.listKeysFromAws("data/datawJ6cAq3tc");
+
+        return "123";
+    }
+
+}

+ 25 - 0
4dkankan-center-scene-download/src/main/java/com/fdkankan/scene/download/schedule/ScheduleJob.java

@@ -0,0 +1,25 @@
+package com.fdkankan.scene.download.schedule;
+
+import com.fdkankan.scene.download.service.ISceneDownLoadService;
+import com.fdkankan.redis.util.RedisUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+@Slf4j
+@Component
+public class ScheduleJob {
+
+    @Autowired
+    RedisUtil redisUtil;
+    @Autowired
+    ISceneDownLoadService sceneDownLoadService;
+
+    @Scheduled(cron = "0/5 * * * * ? ")
+    public void job4SceneDownload() throws Exception {
+        log.info("场景下载定时任务执行。。。。");
+//        sceneDownLoadService.process();
+    }
+
+}

+ 15 - 0
4dkankan-center-scene-download/src/main/java/com/fdkankan/scene/download/service/ISceneDownLoadService.java

@@ -0,0 +1,15 @@
+package com.fdkankan.scene.download.service;
+
+/**
+ * <p>
+ * 场景下载接口
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/2/22
+ **/
+public interface ISceneDownLoadService {
+
+    void process() throws Exception;
+
+}

+ 51 - 0
4dkankan-center-scene-download/src/main/java/com/fdkankan/scene/download/service/impl/CheckProgressRunnerImpl.java

@@ -0,0 +1,51 @@
+package com.fdkankan.scene.download.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import com.alibaba.fastjson.JSON;
+import com.fdkankan.redis.constant.RedisKey;
+import com.fdkankan.redis.util.RedisUtil;
+import com.fdkankan.scene.download.bean.DownLoadTaskBean;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Component;
+
+/**
+ * <p>
+ * 应用启动校验是否有下载任务正在进行,如有过就重新入队头,从新下载
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/2/22
+ **/
+@Component
+public class CheckProgressRunnerImpl implements CommandLineRunner {
+
+    @Autowired
+    RedisUtil redisUtil;
+    @Autowired
+    RedisTemplate redisTemplate;
+
+    @Override
+    public void run(String... args) throws Exception {
+
+        //查询还没下载完毕的场景
+        List<String> downLoadList = redisUtil.lGet(RedisKey.SCENE_DOWNLOAD_ING, 0, -1);
+        if(CollUtil.isEmpty(downLoadList)){
+            return;
+        }
+        List<String> taskList = downLoadList.stream().map(num -> {
+            return JSON.toJSONString(DownLoadTaskBean.builder().num(num).type("local").build());
+        }).collect(Collectors.toList());
+
+        //删除还没执行完毕的场景缓存
+        redisUtil.del(RedisKey.SCENE_DOWNLOAD_ING);
+
+        // TODO: 2022/2/22 这里上线是要改成RedisKey.DOWNLOAD_TASK
+        //从新入队
+        redisUtil.lLeftPushAll("downloads:task:v4", taskList);
+
+    }
+}

+ 53 - 0
4dkankan-center-scene-download/src/main/java/com/fdkankan/scene/download/service/impl/SceneDownLoadServiceImpl.java

@@ -0,0 +1,53 @@
+package com.fdkankan.scene.download.service.impl;
+
+import com.fdkankan.scene.download.service.ISceneDownLoadService;
+import com.fdkankan.redis.constant.RedisKey;
+import com.fdkankan.redis.util.RedisUtil;
+import java.util.concurrent.ExecutorCompletionService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/2/22
+ **/
+@Service
+public class SceneDownLoadServiceImpl implements ISceneDownLoadService {
+
+    @Value("${scene.download.threadMax:3}")
+    private Integer downloadThreadMax;
+
+    @Autowired
+    RedisUtil redisUtil;
+
+//    @Autowired
+//    ExecutorCompletionService completionService;
+
+    @Autowired
+    SceneDownloadHandlerServiceImpl handlerService;
+
+
+    @Override
+    public void process() throws Exception {
+
+        long downloadIngCnt = redisUtil.lGetSize(RedisKey.SCENE_DOWNLOAD_ING);
+        //如果正在下载的场景大于最大线程数,不往下执行
+        if(downloadIngCnt >= downloadThreadMax){
+            return;
+        }
+
+        for(int i = 0; i < downloadThreadMax - downloadIngCnt; i++){
+            handlerService.download();
+        }
+
+    }
+
+
+
+}

+ 439 - 0
4dkankan-center-scene-download/src/main/java/com/fdkankan/scene/download/service/impl/SceneDownloadHandlerServiceImpl.java

@@ -0,0 +1,439 @@
+package com.fdkankan.scene.download.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.exceptions.ExceptionUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSON;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.constant.ServerCode;
+import com.fdkankan.common.constant.UploadFilePath;
+import com.fdkankan.common.response.ResultData;
+import com.fdkankan.common.util.FileUtils;
+import com.fdkankan.fyun.constant.StorageType;
+import com.fdkankan.fyun.oss.UploadToOssUtil;
+import com.fdkankan.redis.constant.RedisKey;
+import com.fdkankan.redis.util.RedisUtil;
+import com.fdkankan.scene.download.bean.DownLoadProgressBean;
+import com.fdkankan.scene.download.bean.DownLoadTaskBean;
+import com.fdkankan.scene.download.bean.ImageType;
+import com.fdkankan.scene.download.bean.ImageTypeDetail;
+import com.google.common.collect.Lists;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import lombok.extern.slf4j.Slf4j;
+import lombok.var;
+import org.apache.tools.zip.ZipFile;
+import org.apache.tools.zip.ZipOutputStream;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/2/22
+ **/
+@Slf4j
+@Service
+public class SceneDownloadHandlerServiceImpl {
+
+    private static final String wwwroot = "wwwroot/";
+    private static final String[] prefixArr = new String[]{
+        "data/data%s/",
+        "voice/voice%s/",
+        "video/video%s/",
+        "images/images%s/"
+    };
+
+    private static final List<ImageType> imageTypes = Lists.newArrayList();
+    static{
+        imageTypes.add(ImageType.builder().name("2k_face").size("2048").ranges(new String[]{"0", "511", "1023", "1535"}).build());
+        imageTypes.add(ImageType.builder().name("1k_face").size("1024").ranges(new String[]{"0", "511"}).build());
+        imageTypes.add(ImageType.builder().name("512_face").size("512").ranges(new String[]{"0"}).build());
+    }
+
+    @Value("${upload.type:oss}")
+    private String uploadType;
+    @Value("${download.config.server-url}")
+    private String serverUrl;
+    @Value("${download.config.resource-url}")
+    private String resourceUrl;
+    @Value("${download.config.public-url}")
+    private String publicUrl;
+    @Value("${download.config.exe-name}")
+    private String exeName;
+    @Value("${download.config.exe-content}")
+    private String exeContent;
+    @Autowired
+    RestTemplate restTemplate;
+
+    @Autowired
+    RedisUtil redisUtil;
+    @Autowired
+    UploadToOssUtil uploadToOssUtil;
+
+
+
+    @Async("sceneDownLoadExecutror")
+    public void download(){
+
+            StorageType storageType = StorageType.get(uploadType);
+            switch (storageType){
+                case OSS:
+                    this.download4Ali();
+                    break;
+                case AWS:
+                    this.download4Aws();
+                    break;
+            }
+
+    }
+
+    public void download4Ali(){
+
+        //场景码
+        String num = null;
+
+        //zip包路径
+        String zipPath = null;
+
+        //代码文件路径
+        //String v3localPath = "/downloads/v3local/";
+        String v3localPath = "F:\\downloads\\v3local\\";
+
+        try {
+            Set<String> cacheKeys = new HashSet<>();
+
+            //获取任务队列中队头场景码,如果是空,标识没有场景要下载,则退出程序
+            num = this.getTaskSceneNum();
+            if(StrUtil.isEmpty(num)){
+                return;
+            }
+
+            Map<String, List<String>> allFiles = this.getAllFiles(num, v3localPath);
+            List<String> ossFilePaths = allFiles.get("ossFilePaths");
+            List<String> v3localFilePaths = allFiles.get("v3localFilePaths");
+
+            //key总个数
+            int total = ossFilePaths.size() + v3localFilePaths.size();
+            int count = 0;
+            //定义压缩包
+            //            zipPath = "/downloads/scenes/" + num + ".zip";
+            zipPath = "F:\\downloads\\scenes\\" + num + ".zip";
+            File zipFile = new File(zipPath);
+            ZipOutputStream out = new ZipOutputStream(zipFile);
+
+            JSONObject getInfoJson = this.zipGetInfoJson(out, num);
+            String resolution = "2k";
+            if(getInfoJson.getInt("sceneSource") == 3 || getInfoJson.getInt("sceneSource") == 4){
+                resolution = "4k";
+            }
+            int imagesVersion = -1;
+            if(getInfoJson.getInt("imagesVersion") != null){
+                imagesVersion = getInfoJson.getInt("imagesVersion");
+            }
+
+            //固定文件写入
+            count = this.zipLocalFiles(out, v3localFilePaths, v3localPath, num, count, total);
+
+            //oss文件写入
+            count = this.zipOssFiles(out, ossFilePaths, num, count, total, resolution, imagesVersion, cacheKeys);
+
+            //写入启动命令
+            this.zipBat(out, num);
+
+            out.close();
+
+            //上传压缩包
+            String uploadPath = "downloads/scenes/" + num + ".zip";
+            uploadToOssUtil.upload(zipPath, uploadPath);
+
+            //更新进度100
+            this.updateProgress(new BigDecimal("100"), num, 1002, this.publicUrl + uploadPath);
+
+        }catch (Exception e){
+            log.error(ExceptionUtil.stacktraceToString(e));
+            //更新进度为下载失败
+            this.updateProgress( null, num, 1003, null);
+        }finally {
+            if(StrUtil.isNotEmpty(num)){
+                //删除正在下载任务
+                redisUtil.lRemove(RedisKey.SCENE_DOWNLOAD_ING, 1, num);
+                //删除本地zip包
+                FileUtils.deleteFile(zipPath);
+            }
+        }
+    }
+
+    private int zipOssFiles(ZipOutputStream out, List<String> ossFilePaths, String num, int count, int total, String resolution, int imagesVersion, Set<String> cacheKeys) throws Exception{
+        String imageNumPath = "images" + num;
+        for (String filePath : ossFilePaths) {
+            if(filePath.contains(imageNumPath + "/panorama/panorama_edit/")){
+                //如果是编辑目录,只需要更新进度,不需要放进压缩包
+                this.updateProgress(new BigDecimal(++count).divide(new BigDecimal(total), 6, BigDecimal.ROUND_HALF_UP), num, 1000, null);
+                continue;
+            }else if((filePath.contains(imageNumPath + "/panorama/") && filePath.contains("tiles/" + resolution)) || filePath.contains(imageNumPath + "/tiles/" + resolution + "/")) {
+                this.processImage(filePath, out, resolution, imagesVersion, cacheKeys);
+            }else{
+                this.ProcessFiles(filePath, out, this.wwwroot, cacheKeys);
+            }
+
+            //更新进度
+            this.updateProgress(new BigDecimal(++count).divide(new BigDecimal(total), 6, BigDecimal.ROUND_HALF_UP),  num, 1000, null);
+        }
+        return count;
+    }
+
+    private int zipLocalFiles(ZipOutputStream out, List<String> v3localFilePaths, String v3localPath, String num, int count, int total) throws Exception{
+        for (String v3localFilePath : v3localFilePaths) {
+            try (FileInputStream in = new FileInputStream(new File(v3localFilePath));){
+                this.zipInputStream(out, v3localFilePath.replace(v3localPath, ""), in);
+            }catch (Exception e){
+                throw e;
+            }
+            //更新进度
+            this.updateProgress(
+                new BigDecimal(++count).divide(new BigDecimal(total), 6, BigDecimal.ROUND_HALF_UP),
+                num, 1000, null);
+        }
+        //写入code.txt
+        this.zipBytes(out, "code.txt", num.getBytes());
+        return count;
+    }
+
+    private void zipBat(ZipOutputStream out, String num) throws Exception{
+        String batContent = String.format(this.exeContent, num);
+        this.zipBytes(out, exeName, batContent.getBytes());
+
+        //更新进度为90%
+        this.updateProgress(new BigDecimal("90"), num, 1001, null);
+    }
+
+    private Map<String, List<String>> getAllFiles(String num, String v3localPath) throws Exception{
+        //列出oss所有文件路径
+        List<String> ossFilePaths = new ArrayList<>();
+        for (String prefix : prefixArr) {
+            prefix = String.format(prefix, num);
+            List<String> keys = uploadToOssUtil.listKeys(prefix);
+            if(CollUtil.isEmpty(keys)){
+                continue;
+            }
+            if(StorageType.AWS.code().equals(this.uploadType)){
+                keys = keys.stream().filter(key->{
+                    if(key.contains("x-oss-process")){
+                        return false;
+                    }
+                    return true;
+                }).collect(Collectors.toList());
+            }
+            ossFilePaths.addAll(keys);
+        }
+
+        //列出v3local所有文件路径
+        File file = new File(v3localPath);
+        List<String> v3localFilePaths = FileUtils.list(file);
+
+        HashMap<String, List<String>> map = new HashMap<>();
+        map.put("ossFilePaths", ossFilePaths);
+        map.put("v3localFilePaths", v3localFilePaths);
+
+        return map;
+    }
+
+    private JSONObject zipGetInfoJson(ZipOutputStream out, String num) throws Exception{
+        String url = serverUrl + " api/scene/getInfo?num=t-YhBCzQr";
+        String getInfoStr = restTemplate.getForObject(url, String.class);
+        ResultData resultData = JSONUtil.toBean(getInfoStr, ResultData.class);
+        if(resultData == null || ServerCode.SUCCESS.code() != resultData.getCode()){
+            throw new Exception("getInfo请求失败,url:" + url);
+        }
+        JSONObject getInfoJson = JSONUtil.parseObj(resultData.getData());
+        getInfoJson.set("sceneScheme", 3);
+        getInfoJson.set("needKey", 0);
+        getInfoJson.set("sceneKey","");
+        //        写入getInfo.json
+        String getInfoJsonPath = "wwwroot/data/data"+num + "/getInfo.json";
+        this.zipBytes(out, getInfoJsonPath, getInfoJson.toString().getBytes());
+        return getInfoJson;
+    }
+
+    private String getTaskSceneNum() throws Exception{
+        //redis待下载任务出队
+        String downloadTask = redisUtil.lLeftPop("downloads:task:v4");
+        if(StrUtil.isEmpty(downloadTask)){
+            return null;
+        }
+        DownLoadTaskBean downLoadTaskBean = JSONUtil.toBean(downloadTask, DownLoadTaskBean.class);
+        if(downLoadTaskBean == null || StrUtil.isEmpty(downLoadTaskBean.getNum()) || !"local".equals(downLoadTaskBean.getType())){
+            throw new Exception("下载任务数据不正确,downloadTask:" +  downloadTask);
+        }
+        String num = downLoadTaskBean.getNum();
+        //正在下载任务入队
+        redisUtil.lLeftPush(RedisKey.SCENE_DOWNLOAD_ING, num);
+        return num;
+    }
+
+    private void processImage(String key, ZipOutputStream out, String resolution, int imagesVersion, Set<String> imgKeys) throws Exception{
+
+        String fileName = key.substring(key.lastIndexOf("/")+1, key.indexOf("."));
+        String ext = key.substring(key.lastIndexOf("."));
+        String[] arr = fileName.split("_skybox");
+        String dir = arr[0];
+        String num = arr[1];
+
+        if(StrUtil.isEmpty(fileName)
+            || StrUtil.isEmpty(ext)
+            || (".jpg".equals(ext) && ".png".equals(ext))
+            ||  StrUtil.isEmpty(dir)
+            || StrUtil.isEmpty(num)){
+            throw new Exception("本地下载图片资源不符合规则,key:" + key);
+        }
+
+        for (ImageType imageType : imageTypes) {
+
+            List<ImageTypeDetail> items = Lists.newArrayList();
+            String[] ranges = imageType.getRanges();
+            for(int i = 0; i < ranges.length; i++){
+                String x = ranges[i];
+                for(int j = 0; j < ranges.length; j++){
+                    String y = ranges[j];
+                    items.add(
+                        ImageTypeDetail.builder()
+                            .i(String.valueOf(i))
+                            .j(String.valueOf(j))
+                            .x(x)
+                            .y(y)
+                            .build()
+                    );
+                }
+            }
+
+            for (ImageTypeDetail item : items) {
+                String par = "?x-oss-process=image/resize,m_lfit,w_" + imageType.getSize() + "/crop,w_512,h_512,x_" + item.getX() + ",y_" + item.getY();
+                if(StorageType.AWS.code().equals(uploadType)){
+                    par += "&imagesVersion="+ imagesVersion;
+                }
+
+                var url = this.resourceUrl + key;
+                StorageType storageType = StorageType.get(uploadType);
+                switch (storageType){
+                    case OSS:
+                        url += par;
+                        break;
+                    case AWS:
+                        url += par;
+                        break;
+                }
+                var fky = key.split("/" + resolution + "/")[0] + "/" + dir + "/" + imageType.getName() +  num + "_" + item.getI()  + "_" + item.getJ() + ext;
+                if(imgKeys.contains(fky)){
+                    continue;
+                }
+                imgKeys.add(fky);
+                byte[] bytes = FileUtils.getBytesFromUrl(url);
+                this.zipBytes(out, wwwroot + fky, bytes);
+            }
+
+        }
+
+    }
+
+    public void ProcessFiles(String key, ZipOutputStream out, String prefix, Set<String> cacheKeys) throws Exception{
+        if(cacheKeys.contains(key)){
+            return;
+        }
+        cacheKeys.add(key);
+        String url = this.resourceUrl + key + "?t=" + Calendar.getInstance().getTimeInMillis();
+        byte[] data = null;
+        if(key.contains("hot.json") || key.contains("link-scene.json")){
+            String content = FileUtils.getStringFromUrl(url);
+
+            content.replace(publicUrl, "")
+//                .replace(publicUrl+"v3/", "")
+                .replace("https://spc.html","spc.html")
+                .replace("https://smobile.html", "smobile.html");
+
+            data = content.getBytes();
+        }else{
+            data = FileUtils.getBytesFromUrl(url);
+        }
+
+        zipBytes(out, prefix + key, data);
+    }
+
+
+    public void updateProgress(BigDecimal precent, String num, Integer status, String url){
+
+        if(precent == null){
+            precent = new BigDecimal(0);
+        }
+        if(status == null || status < 1002){
+            precent = precent.multiply(new BigDecimal("0.8")).multiply(new BigDecimal("100"));
+        }
+
+        DownLoadProgressBean progress = null;
+        String key = String.format(RedisKey.PREFIX_DOWNLOAD_PROGRESS, num);
+        String progressStr = redisUtil.get(key);
+        if(StrUtil.isEmpty(progressStr)){
+            progress =  DownLoadProgressBean.builder().percent(precent.intValue()).status(status).url(url).build();
+        }else{
+            progress = JSONUtil.toBean(progressStr, DownLoadProgressBean.class);
+            //如果下载失败,进度不变
+            if(status == 1003 && progress.getPercent() != null){
+                precent = new BigDecimal(progress.getPercent());
+            }
+            progress.setPercent(precent.intValue());
+            progress.setStatus(status);
+            progress.setUrl(url);
+        }
+        redisUtil.set(key, JSONUtil.toJsonStr(progress));
+
+    }
+
+    public void zipInputStream(ZipOutputStream out, String key, FileInputStream in) throws Exception {
+        out.putNextEntry(new org.apache.tools.zip.ZipEntry(key));
+        byte[] bytes = new byte[1024];
+        while ((in.read(bytes)) != -1) {
+            out.write(bytes);
+        }
+    }
+
+    public void zipBytes(ZipOutputStream out, String key, byte[] bytes) throws Exception {
+        out.putNextEntry(new org.apache.tools.zip.ZipEntry(key));
+        out.write(bytes);
+    }
+
+
+    public void download4Aws(){
+
+
+    }
+
+
+
+
+}

+ 45 - 0
4dkankan-center-scene-download/src/main/resources/bootstrap.yml

@@ -0,0 +1,45 @@
+spring:
+  jackson:
+    serialization:
+      #关闭jackson转换 实体属性空值校验
+      FAIL_ON_EMPTY_BEANS: false
+  application:
+    name: 4dkankan-center-scene-download
+  cloud:
+    nacos:
+      config:
+        server-addr: 192.168.0.47:8848
+        file-extension: yaml
+        namespace: 4dkankan-dev
+        extension-configs:
+          - data-id: 4dkankan-center-scene-download.yaml
+            group: DEFAULT_GROUP
+            refresh: true
+        shared-configs:
+
+          - data-id: common-redis-config.yaml
+            group: DEFAULT_GROUP
+            refresh: true
+
+          - data-id: other-config.yaml
+            group: DEFAULT_GROUP
+            refresh: true
+
+          - data-id: common-upload-config.yaml
+            group: DEFAULT_GROUP
+            refresh: true
+      discovery:
+        server-addr: 192.168.0.47:8848
+        namespace: 4dkankan-dev
+
+download:
+  config:
+    server-url: https://test.4dkankan.com/
+    public-url: https://4dkk.4dage.com/
+    resource-url: https://4dkankan.oss-cn-shenzhen.aliyuncs.com/
+    exe-name: start-browser.bat
+    exe-content: taskkill /f /t /im http.exe start http://127.0.0.1:9000/spc.html?m=%shttp.exe -nc -p 9000 -r wwwroot
+
+
+
+

+ 269 - 0
4dkankan-center-scene-download/src/main/resources/logback-spring.xml

@@ -0,0 +1,269 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
+<!-- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true -->
+<!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
+<!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
+<configuration scan="true" scanPeriod="10 seconds">
+
+	<contextName>logback</contextName>
+	<!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 -->
+	<property name="log.path" value="/data/4dkankan/logs/4dkankan_center_scene_download" />
+
+	<!-- 彩色日志 -->
+	<!-- 彩色日志依赖的渲染类 -->
+	<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
+	<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
+	<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
+	<!-- 彩色日志格式 -->
+	<property name="CONSOLE_LOG_PATTERN"
+		value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}" />
+
+	<!--输出到控制台 -->
+	<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+		<!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息 -->
+		<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+			<level>info</level>
+		</filter>
+		<encoder>
+			<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
+			<!-- 设置字符集 -->
+			<charset>UTF-8</charset>
+		</encoder>
+	</appender>
+	<!--输出到文件 -->
+
+	<!-- 时间滚动输出 level为 DEBUG 日志 -->
+	<appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<!-- 正在记录的日志文件的路径及文件名 -->
+		<file>${log.path}/log_debug.log</file>
+		<!--日志文件输出格式 -->
+		<encoder>
+			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}[%L] - %msg%n</pattern>
+			<charset>UTF-8</charset> <!-- 设置字符集 -->
+		</encoder>
+		<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
+		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+			<!-- 日志归档 -->
+			<fileNamePattern>${log.path}/debug/log-debug-%d{yyyy-MM-dd}.%i.log
+			</fileNamePattern>
+			<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+				<maxFileSize>100MB</maxFileSize>
+			</timeBasedFileNamingAndTriggeringPolicy>
+			<!--日志文件保留天数 -->
+			<maxHistory>15</maxHistory>
+		</rollingPolicy>
+		<!-- 此日志文件只记录debug级别的 -->
+		<filter class="ch.qos.logback.classic.filter.LevelFilter">
+			<level>debug</level>
+			<onMatch>ACCEPT</onMatch>
+			<onMismatch>DENY</onMismatch>
+		</filter>
+	</appender>
+
+	<!-- 时间滚动输出 level为 INFO 日志 -->
+	<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<!-- 正在记录的日志文件的路径及文件名 -->
+		<file>${log.path}/log_info.log</file>
+		<!--日志文件输出格式 -->
+		<encoder>
+			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}[%L] - %msg%n</pattern>
+			<charset>UTF-8</charset>
+		</encoder>
+		<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
+		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+			<!-- 每天日志归档路径以及格式 -->
+			<fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log
+			</fileNamePattern>
+			<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+				<maxFileSize>100MB</maxFileSize>
+			</timeBasedFileNamingAndTriggeringPolicy>
+			<!--日志文件保留天数 -->
+			<maxHistory>15</maxHistory>
+		</rollingPolicy>
+		<!-- 此日志文件只记录info级别的 -->
+		<filter class="ch.qos.logback.classic.filter.LevelFilter">
+			<level>info</level>
+			<onMatch>ACCEPT</onMatch>
+			<onMismatch>DENY</onMismatch>
+		</filter>
+	</appender>
+
+	<!-- 时间滚动输出 level为 WARN 日志 -->
+	<appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<!-- 正在记录的日志文件的路径及文件名 -->
+		<file>${log.path}/log_warn.log</file>
+		<!--日志文件输出格式 -->
+		<encoder>
+			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}[%L] - %msg%n</pattern>
+			<charset>UTF-8</charset> <!-- 此处设置字符集 -->
+		</encoder>
+		<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
+		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+			<fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log
+			</fileNamePattern>
+			<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+				<maxFileSize>100MB</maxFileSize>
+			</timeBasedFileNamingAndTriggeringPolicy>
+			<!--日志文件保留天数 -->
+			<maxHistory>15</maxHistory>
+		</rollingPolicy>
+		<!-- 此日志文件只记录warn级别的 -->
+		<filter class="ch.qos.logback.classic.filter.LevelFilter">
+			<level>warn</level>
+			<onMatch>ACCEPT</onMatch>
+			<onMismatch>DENY</onMismatch>
+		</filter>
+	</appender>
+
+
+	<!-- 时间滚动输出 level为 ERROR 日志 -->
+	<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<!-- 正在记录的日志文件的路径及文件名 -->
+		<file>${log.path}/log_error.log</file>
+		<!--日志文件输出格式 -->
+		<encoder>
+			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}[%L] - %msg%n</pattern>
+			<charset>UTF-8</charset> <!-- 此处设置字符集 -->
+		</encoder>
+		<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
+		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+			<fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log
+			</fileNamePattern>
+			<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+				<maxFileSize>100MB</maxFileSize>
+			</timeBasedFileNamingAndTriggeringPolicy>
+			<!--日志文件保留天数 -->
+			<maxHistory>15</maxHistory>
+		</rollingPolicy>
+		<!-- 此日志文件只记录ERROR级别的 -->
+		<filter class="ch.qos.logback.classic.filter.LevelFilter">
+			<level>ERROR</level>
+			<onMatch>ACCEPT</onMatch>
+			<onMismatch>DENY</onMismatch>
+		</filter>
+	</appender>
+	
+	<appender name="PROGRAM_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<!-- 正在记录的日志文件的路径及文件名 -->
+		<file>${log.path}/program/log_program.log</file>
+		<!--日志文件输出格式 -->
+		<encoder>
+			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}[%L] - %msg%n</pattern>
+			<charset>UTF-8</charset> <!-- 此处设置字符集 -->
+		</encoder>
+		<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
+		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+			<fileNamePattern>${log.path}/program/log-program-%d{yyyy-MM-dd}.%i.log
+			</fileNamePattern>
+			<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+				<maxFileSize>100MB</maxFileSize>
+			</timeBasedFileNamingAndTriggeringPolicy>
+			<!--日志文件保留天数 -->
+			<maxHistory>15</maxHistory>
+		</rollingPolicy>
+		<!-- 此日志文件只记录ERROR级别的 -->
+		<filter class="ch.qos.logback.classic.filter.LevelFilter">
+			<onMatch>ACCEPT</onMatch>
+			<onMismatch>DENY</onMismatch>
+		</filter>
+	</appender>
+	<logger name="programLog" level="INFO" additivity="true">
+        <appender-ref ref="PROGRAM_FILE"/>
+    </logger>
+
+	<appender name="VISIT_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<!-- 正在记录的日志文件的路径及文件名 -->
+		<file>${log.path}/visit/log_visit.log</file>
+		<!--日志文件输出格式 -->
+		<encoder>
+			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}[%L] - %msg%n</pattern>
+			<charset>UTF-8</charset> <!-- 此处设置字符集 -->
+		</encoder>
+		<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
+		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+			<fileNamePattern>${log.path}/visit/log-visit-%d{yyyy-MM-dd}.%i.log
+			</fileNamePattern>
+
+			<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+				<maxFileSize>100MB</maxFileSize>
+			</timeBasedFileNamingAndTriggeringPolicy>
+			<!--日志文件保留天数 -->
+			<maxHistory>15</maxHistory>
+		</rollingPolicy>
+		<!-- 此日志文件只记录ERROR级别的 -->
+		<filter class="ch.qos.logback.classic.filter.LevelFilter">
+			<onMatch>ACCEPT</onMatch>
+			<onMismatch>DENY</onMismatch>
+		</filter>
+	</appender>
+	<logger name="visitLog" level="INFO" additivity="true">
+        <appender-ref ref="VISIT_FILE"/>
+    </logger>
+
+	<!-- <logger>用来设置某一个包或者具体的某一个类的日志打印级别、 以及指定<appender>。<logger>仅有一个name属性, 一个可选的level和一个可选的addtivity属性。 name:用来指定受此logger约束的某一个包或者具体的某一个类。 level:用来设置打印级别,大小写无关:TRACE,
+		DEBUG, INFO, WARN, ERROR, ALL 和 OFF, 还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。 如果未设置此属性,那么当前logger将会继承上级的级别。 addtivity:是否向上级logger传递打印信息。默认是true。 -->
+	<!--<logger name="org.springframework.web" level="info"/> -->
+	<!--<logger name="org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor" level="INFO"/> -->
+	<!-- 使用mybatis的时候,sql语句是debug下才会打印,而这里我们只配置了info,所以想要查看sql语句的话,有以下两种操作: 第一种把<root level="info">改成<root level="DEBUG">这样就会打印sql,不过这样日志那边会出现很多其他消息 第二种就是单独给dao下目录配置debug模式,代码如下,这样配置sql语句会打印,其他还是正常info级别: -->
+	<!-- root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性 level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF, 不能设置为INHERITED或者同义词NULL。默认是DEBUG 可以包含零个或多个元素,标识这个appender将会添加到这个logger。 -->
+
+			<root level="info">
+				<appender-ref ref="CONSOLE" />
+				<appender-ref ref="DEBUG_FILE" />
+				<appender-ref ref="INFO_FILE" />
+				<appender-ref ref="WARN_FILE" />
+				<appender-ref ref="ERROR_FILE" />
+			</root>
+
+<!--	<springProfile name="dev">-->
+<!--		<root level="info">-->
+<!--			<appender-ref ref="CONSOLE" />-->
+<!--			<appender-ref ref="DEBUG_FILE" />-->
+<!--			<appender-ref ref="INFO_FILE" />-->
+<!--			<appender-ref ref="WARN_FILE" />-->
+<!--			<appender-ref ref="ERROR_FILE" />-->
+<!--			<appender-ref ref="ALL_FILE" />-->
+<!--		</root>-->
+<!--		&lt;!&ndash; <logger name="com.xusanduo.demo" level="debug"/>开发环境, 指定某包日志为debug级 &ndash;&gt;-->
+<!--	</springProfile>-->
+
+<!--	<springProfile name="test">-->
+<!--		<root level="info">-->
+<!--			<appender-ref ref="CONSOLE" />-->
+<!--			<appender-ref ref="DEBUG_FILE" />-->
+<!--			<appender-ref ref="INFO_FILE" />-->
+<!--			<appender-ref ref="WARN_FILE" />-->
+<!--			<appender-ref ref="ERROR_FILE" />-->
+<!--			<appender-ref ref="ALL_FILE" />-->
+<!--		</root>-->
+<!--		&lt;!&ndash; <logger name="com.xusanduo.demo" level="info"/> 测试环境, 指定某包日志为info级 &ndash;&gt;-->
+<!--	</springProfile>-->
+
+<!--	<springProfile name="pro">-->
+<!--		<root level="error">-->
+<!--			&lt;!&ndash; 生产环境最好不配置console写文件 &ndash;&gt;-->
+<!--			<appender-ref ref="CONSOLE" />-->
+<!--			<appender-ref ref="DEBUG_FILE" />-->
+<!--			<appender-ref ref="INFO_FILE" />-->
+<!--			<appender-ref ref="WARN_FILE" />-->
+<!--			<appender-ref ref="ERROR_FILE" />-->
+<!--			<appender-ref ref="ALL_FILE" />-->
+<!--		</root>-->
+<!--		&lt;!&ndash; <logger name="com.xusanduo.demo" level="warn"/> 生产环境, 指定某包日志为warn级 &ndash;&gt;-->
+<!--		&lt;!&ndash; <logger name="com.xusanduo.demo.MyApplication" level="info"/> 特定某个类打印info日志, 比如application启动成功后的提示语 &ndash;&gt;-->
+<!--	</springProfile>-->
+
+	<!--生产环境:输出到文件 -->
+	<!--<springProfile name="pro"> -->
+	<!--<root level="info"> -->
+	<!--<appender-ref ref="CONSOLE" /> -->
+	<!--<appender-ref ref="DEBUG_FILE" /> -->
+	<!--<appender-ref ref="INFO_FILE" /> -->
+	<!--<appender-ref ref="ERROR_FILE" /> -->
+	<!--<appender-ref ref="WARN_FILE" /> -->
+	<!--</root> -->
+	<!--</springProfile> -->
+
+</configuration>
+
+

BIN
4dkankan-center-scene-download/src/main/resources/static/audio/01.mp3


BIN
4dkankan-center-scene-download/src/main/resources/static/audio/02.mp3


BIN
4dkankan-center-scene-download/src/main/resources/static/audio/03.mp3


BIN
4dkankan-center-scene-download/src/main/resources/static/audio/04.mp3


BIN
4dkankan-center-scene-download/src/main/resources/static/audio/05.mp3


BIN
4dkankan-center-scene-download/src/main/resources/static/audio/06.mp3


BIN
4dkankan-center-scene-download/src/main/resources/static/audio/07.mp3


BIN
4dkankan-center-scene-download/src/main/resources/static/audio/08.mp3


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
4dkankan-center-scene-download/src/main/resources/static/css/chunk-3d475e12.dd51d2d0.css


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
4dkankan-center-scene-download/src/main/resources/static/css/chunk-74f12a8c.3ccaf059.css


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
4dkankan-center-scene-download/src/main/resources/static/css/chunk-abf2a2d8.9f49428d.css


+ 1 - 0
4dkankan-center-scene-download/src/main/resources/static/css/chunk-b8031520.64b751b4.css

@@ -0,0 +1 @@
+ul{padding:0}

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 3 - 0
4dkankan-center-scene-download/src/main/resources/static/css/chunk-common.2afe10cf.css


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
4dkankan-center-scene-download/src/main/resources/static/css/chunk-e7bdf3ce.cb9c32d3.css


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
4dkankan-center-scene-download/src/main/resources/static/css/chunk-ed3be54e.29cea110.css


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
4dkankan-center-scene-download/src/main/resources/static/css/chunk-vendors.a7bbc042.css


+ 539 - 0
4dkankan-center-scene-download/src/main/resources/static/css/fire-control/demo.css

@@ -0,0 +1,539 @@
+/* Logo 字体 */
+@font-face {
+  font-family: "iconfont logo";
+  src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
+  src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
+}
+
+.logo {
+  font-family: "iconfont logo";
+  font-size: 160px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+/* tabs */
+.nav-tabs {
+  position: relative;
+}
+
+.nav-tabs .nav-more {
+  position: absolute;
+  right: 0;
+  bottom: 0;
+  height: 42px;
+  line-height: 42px;
+  color: #666;
+}
+
+#tabs {
+  border-bottom: 1px solid #eee;
+}
+
+#tabs li {
+  cursor: pointer;
+  width: 100px;
+  height: 40px;
+  line-height: 40px;
+  text-align: center;
+  font-size: 16px;
+  border-bottom: 2px solid transparent;
+  position: relative;
+  z-index: 1;
+  margin-bottom: -1px;
+  color: #666;
+}
+
+
+#tabs .active {
+  border-bottom-color: #f00;
+  color: #222;
+}
+
+.tab-container .content {
+  display: none;
+}
+
+/* 页面布局 */
+.main {
+  padding: 30px 100px;
+  width: 960px;
+  margin: 0 auto;
+}
+
+.main .logo {
+  color: #333;
+  text-align: left;
+  margin-bottom: 30px;
+  line-height: 1;
+  height: 110px;
+  margin-top: -50px;
+  overflow: hidden;
+  *zoom: 1;
+}
+
+.main .logo a {
+  font-size: 160px;
+  color: #333;
+}
+
+.helps {
+  margin-top: 40px;
+}
+
+.helps pre {
+  padding: 20px;
+  margin: 10px 0;
+  border: solid 1px #e7e1cd;
+  background-color: #fffdef;
+  overflow: auto;
+}
+
+.icon_lists {
+  width: 100% !important;
+  overflow: hidden;
+  *zoom: 1;
+}
+
+.icon_lists li {
+  width: 100px;
+  margin-bottom: 10px;
+  margin-right: 20px;
+  text-align: center;
+  list-style: none !important;
+  cursor: default;
+}
+
+.icon_lists li .code-name {
+  line-height: 1.2;
+}
+
+.icon_lists .icon {
+  display: block;
+  height: 100px;
+  line-height: 100px;
+  font-size: 42px;
+  margin: 10px auto;
+  color: #333;
+  -webkit-transition: font-size 0.25s linear, width 0.25s linear;
+  -moz-transition: font-size 0.25s linear, width 0.25s linear;
+  transition: font-size 0.25s linear, width 0.25s linear;
+}
+
+.icon_lists .icon:hover {
+  font-size: 100px;
+}
+
+.icon_lists .svg-icon {
+  /* 通过设置 font-size 来改变图标大小 */
+  width: 1em;
+  /* 图标和文字相邻时,垂直对齐 */
+  vertical-align: -0.15em;
+  /* 通过设置 color 来改变 SVG 的颜色/fill */
+  fill: currentColor;
+  /* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
+      normalize.css 中也包含这行 */
+  overflow: hidden;
+}
+
+.icon_lists li .name,
+.icon_lists li .code-name {
+  color: #666;
+}
+
+/* markdown 样式 */
+.markdown {
+  color: #666;
+  font-size: 14px;
+  line-height: 1.8;
+}
+
+.highlight {
+  line-height: 1.5;
+}
+
+.markdown img {
+  vertical-align: middle;
+  max-width: 100%;
+}
+
+.markdown h1 {
+  color: #404040;
+  font-weight: 500;
+  line-height: 40px;
+  margin-bottom: 24px;
+}
+
+.markdown h2,
+.markdown h3,
+.markdown h4,
+.markdown h5,
+.markdown h6 {
+  color: #404040;
+  margin: 1.6em 0 0.6em 0;
+  font-weight: 500;
+  clear: both;
+}
+
+.markdown h1 {
+  font-size: 28px;
+}
+
+.markdown h2 {
+  font-size: 22px;
+}
+
+.markdown h3 {
+  font-size: 16px;
+}
+
+.markdown h4 {
+  font-size: 14px;
+}
+
+.markdown h5 {
+  font-size: 12px;
+}
+
+.markdown h6 {
+  font-size: 12px;
+}
+
+.markdown hr {
+  height: 1px;
+  border: 0;
+  background: #e9e9e9;
+  margin: 16px 0;
+  clear: both;
+}
+
+.markdown p {
+  margin: 1em 0;
+}
+
+.markdown>p,
+.markdown>blockquote,
+.markdown>.highlight,
+.markdown>ol,
+.markdown>ul {
+  width: 80%;
+}
+
+.markdown ul>li {
+  list-style: circle;
+}
+
+.markdown>ul li,
+.markdown blockquote ul>li {
+  margin-left: 20px;
+  padding-left: 4px;
+}
+
+.markdown>ul li p,
+.markdown>ol li p {
+  margin: 0.6em 0;
+}
+
+.markdown ol>li {
+  list-style: decimal;
+}
+
+.markdown>ol li,
+.markdown blockquote ol>li {
+  margin-left: 20px;
+  padding-left: 4px;
+}
+
+.markdown code {
+  margin: 0 3px;
+  padding: 0 5px;
+  background: #eee;
+  border-radius: 3px;
+}
+
+.markdown strong,
+.markdown b {
+  font-weight: 600;
+}
+
+.markdown>table {
+  border-collapse: collapse;
+  border-spacing: 0px;
+  empty-cells: show;
+  border: 1px solid #e9e9e9;
+  width: 95%;
+  margin-bottom: 24px;
+}
+
+.markdown>table th {
+  white-space: nowrap;
+  color: #333;
+  font-weight: 600;
+}
+
+.markdown>table th,
+.markdown>table td {
+  border: 1px solid #e9e9e9;
+  padding: 8px 16px;
+  text-align: left;
+}
+
+.markdown>table th {
+  background: #F7F7F7;
+}
+
+.markdown blockquote {
+  font-size: 90%;
+  color: #999;
+  border-left: 4px solid #e9e9e9;
+  padding-left: 0.8em;
+  margin: 1em 0;
+}
+
+.markdown blockquote p {
+  margin: 0;
+}
+
+.markdown .anchor {
+  opacity: 0;
+  transition: opacity 0.3s ease;
+  margin-left: 8px;
+}
+
+.markdown .waiting {
+  color: #ccc;
+}
+
+.markdown h1:hover .anchor,
+.markdown h2:hover .anchor,
+.markdown h3:hover .anchor,
+.markdown h4:hover .anchor,
+.markdown h5:hover .anchor,
+.markdown h6:hover .anchor {
+  opacity: 1;
+  display: inline-block;
+}
+
+.markdown>br,
+.markdown>p>br {
+  clear: both;
+}
+
+
+.hljs {
+  display: block;
+  background: white;
+  padding: 0.5em;
+  color: #333333;
+  overflow-x: auto;
+}
+
+.hljs-comment,
+.hljs-meta {
+  color: #969896;
+}
+
+.hljs-string,
+.hljs-variable,
+.hljs-template-variable,
+.hljs-strong,
+.hljs-emphasis,
+.hljs-quote {
+  color: #df5000;
+}
+
+.hljs-keyword,
+.hljs-selector-tag,
+.hljs-type {
+  color: #a71d5d;
+}
+
+.hljs-literal,
+.hljs-symbol,
+.hljs-bullet,
+.hljs-attribute {
+  color: #0086b3;
+}
+
+.hljs-section,
+.hljs-name {
+  color: #63a35c;
+}
+
+.hljs-tag {
+  color: #333333;
+}
+
+.hljs-title,
+.hljs-attr,
+.hljs-selector-id,
+.hljs-selector-class,
+.hljs-selector-attr,
+.hljs-selector-pseudo {
+  color: #795da3;
+}
+
+.hljs-addition {
+  color: #55a532;
+  background-color: #eaffea;
+}
+
+.hljs-deletion {
+  color: #bd2c00;
+  background-color: #ffecec;
+}
+
+.hljs-link {
+  text-decoration: underline;
+}
+
+/* 代码高亮 */
+/* PrismJS 1.15.0
+https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
+/**
+ * prism.js default theme for JavaScript, CSS and HTML
+ * Based on dabblet (http://dabblet.com)
+ * @author Lea Verou
+ */
+code[class*="language-"],
+pre[class*="language-"] {
+  color: black;
+  background: none;
+  text-shadow: 0 1px white;
+  font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
+  text-align: left;
+  white-space: pre;
+  word-spacing: normal;
+  word-break: normal;
+  word-wrap: normal;
+  line-height: 1.5;
+
+  -moz-tab-size: 4;
+  -o-tab-size: 4;
+  tab-size: 4;
+
+  -webkit-hyphens: none;
+  -moz-hyphens: none;
+  -ms-hyphens: none;
+  hyphens: none;
+}
+
+pre[class*="language-"]::-moz-selection,
+pre[class*="language-"] ::-moz-selection,
+code[class*="language-"]::-moz-selection,
+code[class*="language-"] ::-moz-selection {
+  text-shadow: none;
+  background: #b3d4fc;
+}
+
+pre[class*="language-"]::selection,
+pre[class*="language-"] ::selection,
+code[class*="language-"]::selection,
+code[class*="language-"] ::selection {
+  text-shadow: none;
+  background: #b3d4fc;
+}
+
+@media print {
+
+  code[class*="language-"],
+  pre[class*="language-"] {
+    text-shadow: none;
+  }
+}
+
+/* Code blocks */
+pre[class*="language-"] {
+  padding: 1em;
+  margin: .5em 0;
+  overflow: auto;
+}
+
+:not(pre)>code[class*="language-"],
+pre[class*="language-"] {
+  background: #f5f2f0;
+}
+
+/* Inline code */
+:not(pre)>code[class*="language-"] {
+  padding: .1em;
+  border-radius: .3em;
+  white-space: normal;
+}
+
+.token.comment,
+.token.prolog,
+.token.doctype,
+.token.cdata {
+  color: slategray;
+}
+
+.token.punctuation {
+  color: #999;
+}
+
+.namespace {
+  opacity: .7;
+}
+
+.token.property,
+.token.tag,
+.token.boolean,
+.token.number,
+.token.constant,
+.token.symbol,
+.token.deleted {
+  color: #905;
+}
+
+.token.selector,
+.token.attr-name,
+.token.string,
+.token.char,
+.token.builtin,
+.token.inserted {
+  color: #690;
+}
+
+.token.operator,
+.token.entity,
+.token.url,
+.language-css .token.string,
+.style .token.string {
+  color: #9a6e3a;
+  background: hsla(0, 0%, 100%, .5);
+}
+
+.token.atrule,
+.token.attr-value,
+.token.keyword {
+  color: #07a;
+}
+
+.token.function,
+.token.class-name {
+  color: #DD4A68;
+}
+
+.token.regex,
+.token.important,
+.token.variable {
+  color: #e90;
+}
+
+.token.important,
+.token.bold {
+  font-weight: bold;
+}
+
+.token.italic {
+  font-style: italic;
+}
+
+.token.entity {
+  cursor: help;
+}

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 6243 - 0
4dkankan-center-scene-download/src/main/resources/static/css/fire-control/demo_index.html


BIN
4dkankan-center-scene-download/src/main/resources/static/css/fire-control/demo_index.html.gz


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1073 - 0
4dkankan-center-scene-download/src/main/resources/static/css/fire-control/iconfont.css


BIN
4dkankan-center-scene-download/src/main/resources/static/css/fire-control/iconfont.eot


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
4dkankan-center-scene-download/src/main/resources/static/css/fire-control/iconfont.js


BIN
4dkankan-center-scene-download/src/main/resources/static/css/fire-control/iconfont.js.gz


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1857 - 0
4dkankan-center-scene-download/src/main/resources/static/css/fire-control/iconfont.json


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 818 - 0
4dkankan-center-scene-download/src/main/resources/static/css/fire-control/iconfont.svg


BIN
4dkankan-center-scene-download/src/main/resources/static/css/fire-control/iconfont.ttf


BIN
4dkankan-center-scene-download/src/main/resources/static/css/fire-control/iconfont.woff


BIN
4dkankan-center-scene-download/src/main/resources/static/css/fire-control/iconfont.woff2


+ 539 - 0
4dkankan-center-scene-download/src/main/resources/static/css/reserve/demo.css

@@ -0,0 +1,539 @@
+/* Logo 字体 */
+@font-face {
+  font-family: "iconfont logo";
+  src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
+  src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
+}
+
+.logo {
+  font-family: "iconfont logo";
+  font-size: 160px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+/* tabs */
+.nav-tabs {
+  position: relative;
+}
+
+.nav-tabs .nav-more {
+  position: absolute;
+  right: 0;
+  bottom: 0;
+  height: 42px;
+  line-height: 42px;
+  color: #666;
+}
+
+#tabs {
+  border-bottom: 1px solid #eee;
+}
+
+#tabs li {
+  cursor: pointer;
+  width: 100px;
+  height: 40px;
+  line-height: 40px;
+  text-align: center;
+  font-size: 16px;
+  border-bottom: 2px solid transparent;
+  position: relative;
+  z-index: 1;
+  margin-bottom: -1px;
+  color: #666;
+}
+
+
+#tabs .active {
+  border-bottom-color: #f00;
+  color: #222;
+}
+
+.tab-container .content {
+  display: none;
+}
+
+/* 页面布局 */
+.main {
+  padding: 30px 100px;
+  width: 960px;
+  margin: 0 auto;
+}
+
+.main .logo {
+  color: #333;
+  text-align: left;
+  margin-bottom: 30px;
+  line-height: 1;
+  height: 110px;
+  margin-top: -50px;
+  overflow: hidden;
+  *zoom: 1;
+}
+
+.main .logo a {
+  font-size: 160px;
+  color: #333;
+}
+
+.helps {
+  margin-top: 40px;
+}
+
+.helps pre {
+  padding: 20px;
+  margin: 10px 0;
+  border: solid 1px #e7e1cd;
+  background-color: #fffdef;
+  overflow: auto;
+}
+
+.icon_lists {
+  width: 100% !important;
+  overflow: hidden;
+  *zoom: 1;
+}
+
+.icon_lists li {
+  width: 100px;
+  margin-bottom: 10px;
+  margin-right: 20px;
+  text-align: center;
+  list-style: none !important;
+  cursor: default;
+}
+
+.icon_lists li .code-name {
+  line-height: 1.2;
+}
+
+.icon_lists .icon {
+  display: block;
+  height: 100px;
+  line-height: 100px;
+  font-size: 42px;
+  margin: 10px auto;
+  color: #333;
+  -webkit-transition: font-size 0.25s linear, width 0.25s linear;
+  -moz-transition: font-size 0.25s linear, width 0.25s linear;
+  transition: font-size 0.25s linear, width 0.25s linear;
+}
+
+.icon_lists .icon:hover {
+  font-size: 100px;
+}
+
+.icon_lists .svg-icon {
+  /* 通过设置 font-size 来改变图标大小 */
+  width: 1em;
+  /* 图标和文字相邻时,垂直对齐 */
+  vertical-align: -0.15em;
+  /* 通过设置 color 来改变 SVG 的颜色/fill */
+  fill: currentColor;
+  /* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
+      normalize.css 中也包含这行 */
+  overflow: hidden;
+}
+
+.icon_lists li .name,
+.icon_lists li .code-name {
+  color: #666;
+}
+
+/* markdown 样式 */
+.markdown {
+  color: #666;
+  font-size: 14px;
+  line-height: 1.8;
+}
+
+.highlight {
+  line-height: 1.5;
+}
+
+.markdown img {
+  vertical-align: middle;
+  max-width: 100%;
+}
+
+.markdown h1 {
+  color: #404040;
+  font-weight: 500;
+  line-height: 40px;
+  margin-bottom: 24px;
+}
+
+.markdown h2,
+.markdown h3,
+.markdown h4,
+.markdown h5,
+.markdown h6 {
+  color: #404040;
+  margin: 1.6em 0 0.6em 0;
+  font-weight: 500;
+  clear: both;
+}
+
+.markdown h1 {
+  font-size: 28px;
+}
+
+.markdown h2 {
+  font-size: 22px;
+}
+
+.markdown h3 {
+  font-size: 16px;
+}
+
+.markdown h4 {
+  font-size: 14px;
+}
+
+.markdown h5 {
+  font-size: 12px;
+}
+
+.markdown h6 {
+  font-size: 12px;
+}
+
+.markdown hr {
+  height: 1px;
+  border: 0;
+  background: #e9e9e9;
+  margin: 16px 0;
+  clear: both;
+}
+
+.markdown p {
+  margin: 1em 0;
+}
+
+.markdown>p,
+.markdown>blockquote,
+.markdown>.highlight,
+.markdown>ol,
+.markdown>ul {
+  width: 80%;
+}
+
+.markdown ul>li {
+  list-style: circle;
+}
+
+.markdown>ul li,
+.markdown blockquote ul>li {
+  margin-left: 20px;
+  padding-left: 4px;
+}
+
+.markdown>ul li p,
+.markdown>ol li p {
+  margin: 0.6em 0;
+}
+
+.markdown ol>li {
+  list-style: decimal;
+}
+
+.markdown>ol li,
+.markdown blockquote ol>li {
+  margin-left: 20px;
+  padding-left: 4px;
+}
+
+.markdown code {
+  margin: 0 3px;
+  padding: 0 5px;
+  background: #eee;
+  border-radius: 3px;
+}
+
+.markdown strong,
+.markdown b {
+  font-weight: 600;
+}
+
+.markdown>table {
+  border-collapse: collapse;
+  border-spacing: 0px;
+  empty-cells: show;
+  border: 1px solid #e9e9e9;
+  width: 95%;
+  margin-bottom: 24px;
+}
+
+.markdown>table th {
+  white-space: nowrap;
+  color: #333;
+  font-weight: 600;
+}
+
+.markdown>table th,
+.markdown>table td {
+  border: 1px solid #e9e9e9;
+  padding: 8px 16px;
+  text-align: left;
+}
+
+.markdown>table th {
+  background: #F7F7F7;
+}
+
+.markdown blockquote {
+  font-size: 90%;
+  color: #999;
+  border-left: 4px solid #e9e9e9;
+  padding-left: 0.8em;
+  margin: 1em 0;
+}
+
+.markdown blockquote p {
+  margin: 0;
+}
+
+.markdown .anchor {
+  opacity: 0;
+  transition: opacity 0.3s ease;
+  margin-left: 8px;
+}
+
+.markdown .waiting {
+  color: #ccc;
+}
+
+.markdown h1:hover .anchor,
+.markdown h2:hover .anchor,
+.markdown h3:hover .anchor,
+.markdown h4:hover .anchor,
+.markdown h5:hover .anchor,
+.markdown h6:hover .anchor {
+  opacity: 1;
+  display: inline-block;
+}
+
+.markdown>br,
+.markdown>p>br {
+  clear: both;
+}
+
+
+.hljs {
+  display: block;
+  background: white;
+  padding: 0.5em;
+  color: #333333;
+  overflow-x: auto;
+}
+
+.hljs-comment,
+.hljs-meta {
+  color: #969896;
+}
+
+.hljs-string,
+.hljs-variable,
+.hljs-template-variable,
+.hljs-strong,
+.hljs-emphasis,
+.hljs-quote {
+  color: #df5000;
+}
+
+.hljs-keyword,
+.hljs-selector-tag,
+.hljs-type {
+  color: #a71d5d;
+}
+
+.hljs-literal,
+.hljs-symbol,
+.hljs-bullet,
+.hljs-attribute {
+  color: #0086b3;
+}
+
+.hljs-section,
+.hljs-name {
+  color: #63a35c;
+}
+
+.hljs-tag {
+  color: #333333;
+}
+
+.hljs-title,
+.hljs-attr,
+.hljs-selector-id,
+.hljs-selector-class,
+.hljs-selector-attr,
+.hljs-selector-pseudo {
+  color: #795da3;
+}
+
+.hljs-addition {
+  color: #55a532;
+  background-color: #eaffea;
+}
+
+.hljs-deletion {
+  color: #bd2c00;
+  background-color: #ffecec;
+}
+
+.hljs-link {
+  text-decoration: underline;
+}
+
+/* 代码高亮 */
+/* PrismJS 1.15.0
+https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
+/**
+ * prism.js default theme for JavaScript, CSS and HTML
+ * Based on dabblet (http://dabblet.com)
+ * @author Lea Verou
+ */
+code[class*="language-"],
+pre[class*="language-"] {
+  color: black;
+  background: none;
+  text-shadow: 0 1px white;
+  font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
+  text-align: left;
+  white-space: pre;
+  word-spacing: normal;
+  word-break: normal;
+  word-wrap: normal;
+  line-height: 1.5;
+
+  -moz-tab-size: 4;
+  -o-tab-size: 4;
+  tab-size: 4;
+
+  -webkit-hyphens: none;
+  -moz-hyphens: none;
+  -ms-hyphens: none;
+  hyphens: none;
+}
+
+pre[class*="language-"]::-moz-selection,
+pre[class*="language-"] ::-moz-selection,
+code[class*="language-"]::-moz-selection,
+code[class*="language-"] ::-moz-selection {
+  text-shadow: none;
+  background: #b3d4fc;
+}
+
+pre[class*="language-"]::selection,
+pre[class*="language-"] ::selection,
+code[class*="language-"]::selection,
+code[class*="language-"] ::selection {
+  text-shadow: none;
+  background: #b3d4fc;
+}
+
+@media print {
+
+  code[class*="language-"],
+  pre[class*="language-"] {
+    text-shadow: none;
+  }
+}
+
+/* Code blocks */
+pre[class*="language-"] {
+  padding: 1em;
+  margin: .5em 0;
+  overflow: auto;
+}
+
+:not(pre)>code[class*="language-"],
+pre[class*="language-"] {
+  background: #f5f2f0;
+}
+
+/* Inline code */
+:not(pre)>code[class*="language-"] {
+  padding: .1em;
+  border-radius: .3em;
+  white-space: normal;
+}
+
+.token.comment,
+.token.prolog,
+.token.doctype,
+.token.cdata {
+  color: slategray;
+}
+
+.token.punctuation {
+  color: #999;
+}
+
+.namespace {
+  opacity: .7;
+}
+
+.token.property,
+.token.tag,
+.token.boolean,
+.token.number,
+.token.constant,
+.token.symbol,
+.token.deleted {
+  color: #905;
+}
+
+.token.selector,
+.token.attr-name,
+.token.string,
+.token.char,
+.token.builtin,
+.token.inserted {
+  color: #690;
+}
+
+.token.operator,
+.token.entity,
+.token.url,
+.language-css .token.string,
+.style .token.string {
+  color: #9a6e3a;
+  background: hsla(0, 0%, 100%, .5);
+}
+
+.token.atrule,
+.token.attr-value,
+.token.keyword {
+  color: #07a;
+}
+
+.token.function,
+.token.class-name {
+  color: #DD4A68;
+}
+
+.token.regex,
+.token.important,
+.token.variable {
+  color: #e90;
+}
+
+.token.important,
+.token.bold {
+  font-weight: bold;
+}
+
+.token.italic {
+  font-style: italic;
+}
+
+.token.entity {
+  cursor: help;
+}

+ 860 - 0
4dkankan-center-scene-download/src/main/resources/static/css/reserve/demo_index.html

@@ -0,0 +1,860 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8"/>
+  <title>IconFont Demo</title>
+  <link rel="shortcut icon" href="https://img.alicdn.com/tps/i4/TB1_oz6GVXXXXaFXpXXJDFnIXXX-64-64.ico" type="image/x-icon"/>
+  <link rel="stylesheet" href="https://g.alicdn.com/thx/cube/1.3.2/cube.min.css">
+  <link rel="stylesheet" href="demo.css">
+  <link rel="stylesheet" href="iconfont.css">
+  <script src="iconfont.js"></script>
+  <!-- jQuery -->
+  <script src="https://a1.alicdn.com/oss/uploads/2018/12/26/7bfddb60-08e8-11e9-9b04-53e73bb6408b.js"></script>
+  <!-- 代码高亮 -->
+  <script src="https://a1.alicdn.com/oss/uploads/2018/12/26/a3f714d0-08e6-11e9-8a15-ebf944d7534c.js"></script>
+</head>
+<body>
+  <div class="main">
+    <h1 class="logo"><a href="https://www.iconfont.cn/" title="iconfont 首页" target="_blank">&#xe86b;</a></h1>
+    <div class="nav-tabs">
+      <ul id="tabs" class="dib-box">
+        <li class="dib active"><span>Unicode</span></li>
+        <li class="dib"><span>Font class</span></li>
+        <li class="dib"><span>Symbol</span></li>
+      </ul>
+      
+      <a href="https://www.iconfont.cn/manage/index?manage_type=myprojects&projectId=1646991" target="_blank" class="nav-more">查看项目</a>
+      
+    </div>
+    <div class="tab-container">
+      <div class="content unicode" style="display: block;">
+          <ul class="icon_lists dib-box">
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe66b;</span>
+                <div class="name">reserv_return</div>
+                <div class="code-name">&amp;#xe66b;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe66c;</span>
+                <div class="name">reserv_arrows</div>
+                <div class="code-name">&amp;#xe66c;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe66d;</span>
+                <div class="name">reserv_hot</div>
+                <div class="code-name">&amp;#xe66d;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe66f;</span>
+                <div class="name">reserv_phone</div>
+                <div class="code-name">&amp;#xe66f;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe67b;</span>
+                <div class="name">reserv_star</div>
+                <div class="code-name">&amp;#xe67b;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe67c;</span>
+                <div class="name">reserv_2d</div>
+                <div class="code-name">&amp;#xe67c;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe67d;</span>
+                <div class="name">reserv_room</div>
+                <div class="code-name">&amp;#xe67d;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe680;</span>
+                <div class="name">reserv_3d</div>
+                <div class="code-name">&amp;#xe680;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe6bf;</span>
+                <div class="name">classify</div>
+                <div class="code-name">&amp;#xe6bf;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe6c0;</span>
+                <div class="name">spcart</div>
+                <div class="code-name">&amp;#xe6c0;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe6c1;</span>
+                <div class="name">my</div>
+                <div class="code-name">&amp;#xe6c1;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe6c2;</span>
+                <div class="name">index</div>
+                <div class="code-name">&amp;#xe6c2;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe683;</span>
+                <div class="name">意见反馈</div>
+                <div class="code-name">&amp;#xe683;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe682;</span>
+                <div class="name">联系客服</div>
+                <div class="code-name">&amp;#xe682;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe681;</span>
+                <div class="name">已完成</div>
+                <div class="code-name">&amp;#xe681;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe67f;</span>
+                <div class="name">我的足迹</div>
+                <div class="code-name">&amp;#xe67f;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe67e;</span>
+                <div class="name">待发货</div>
+                <div class="code-name">&amp;#xe67e;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe67a;</span>
+                <div class="name">我的收藏</div>
+                <div class="code-name">&amp;#xe67a;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe679;</span>
+                <div class="name">设置</div>
+                <div class="code-name">&amp;#xe679;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe678;</span>
+                <div class="name">待收货</div>
+                <div class="code-name">&amp;#xe678;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe677;</span>
+                <div class="name">全部订单</div>
+                <div class="code-name">&amp;#xe677;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe676;</span>
+                <div class="name">待付款</div>
+                <div class="code-name">&amp;#xe676;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe675;</span>
+                <div class="name">wechat</div>
+                <div class="code-name">&amp;#xe675;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe674;</span>
+                <div class="name">播放暂停</div>
+                <div class="code-name">&amp;#xe674;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe673;</span>
+                <div class="name">播放</div>
+                <div class="code-name">&amp;#xe673;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe672;</span>
+                <div class="name">购物袋</div>
+                <div class="code-name">&amp;#xe672;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe671;</span>
+                <div class="name">wechat</div>
+                <div class="code-name">&amp;#xe671;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe66e;</span>
+                <div class="name">箭头</div>
+                <div class="code-name">&amp;#xe66e;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe670;</span>
+                <div class="name">购物车</div>
+                <div class="code-name">&amp;#xe670;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe635;</span>
+                <div class="name">fangdajing</div>
+                <div class="code-name">&amp;#xe635;</div>
+              </li>
+          
+          </ul>
+          <div class="article markdown">
+          <h2 id="unicode-">Unicode 引用</h2>
+          <hr>
+
+          <p>Unicode 是字体在网页端最原始的应用方式,特点是:</p>
+          <ul>
+            <li>兼容性最好,支持 IE6+,及所有现代浏览器。</li>
+            <li>支持按字体的方式去动态调整图标大小,颜色等等。</li>
+            <li>但是因为是字体,所以不支持多色。只能使用平台里单色的图标,就算项目里有多色图标也会自动去色。</li>
+          </ul>
+          <blockquote>
+            <p>注意:新版 iconfont 支持多色图标,这些多色图标在 Unicode 模式下将不能使用,如果有需求建议使用symbol 的引用方式</p>
+          </blockquote>
+          <p>Unicode 使用步骤如下:</p>
+          <h3 id="-font-face">第一步:拷贝项目下面生成的 <code>@font-face</code></h3>
+<pre><code class="language-css"
+>@font-face {
+  font-family: 'iconfont';
+  src: url('iconfont.eot');
+  src: url('iconfont.eot?#iefix') format('embedded-opentype'),
+      url('iconfont.woff2') format('woff2'),
+      url('iconfont.woff') format('woff'),
+      url('iconfont.ttf') format('truetype'),
+      url('iconfont.svg#iconfont') format('svg');
+}
+</code></pre>
+          <h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
+<pre><code class="language-css"
+>.iconfont {
+  font-family: "iconfont" !important;
+  font-size: 16px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+</code></pre>
+          <h3 id="-">第三步:挑选相应图标并获取字体编码,应用于页面</h3>
+<pre>
+<code class="language-html"
+>&lt;span class="iconfont"&gt;&amp;#x33;&lt;/span&gt;
+</code></pre>
+          <blockquote>
+            <p>"iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。</p>
+          </blockquote>
+          </div>
+      </div>
+      <div class="content font-class">
+        <ul class="icon_lists dib-box">
+          
+          <li class="dib">
+            <span class="icon iconfont iconreserv_return"></span>
+            <div class="name">
+              reserv_return
+            </div>
+            <div class="code-name">.iconreserv_return
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont iconreserv_arrows"></span>
+            <div class="name">
+              reserv_arrows
+            </div>
+            <div class="code-name">.iconreserv_arrows
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont iconreserv_hot"></span>
+            <div class="name">
+              reserv_hot
+            </div>
+            <div class="code-name">.iconreserv_hot
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont iconreserv_phone"></span>
+            <div class="name">
+              reserv_phone
+            </div>
+            <div class="code-name">.iconreserv_phone
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont iconreserv_star"></span>
+            <div class="name">
+              reserv_star
+            </div>
+            <div class="code-name">.iconreserv_star
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont iconreserv_2d"></span>
+            <div class="name">
+              reserv_2d
+            </div>
+            <div class="code-name">.iconreserv_2d
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont iconreserv_room"></span>
+            <div class="name">
+              reserv_room
+            </div>
+            <div class="code-name">.iconreserv_room
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont iconreserv_3d"></span>
+            <div class="name">
+              reserv_3d
+            </div>
+            <div class="code-name">.iconreserv_3d
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont iconclassify"></span>
+            <div class="name">
+              classify
+            </div>
+            <div class="code-name">.iconclassify
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont iconspcart"></span>
+            <div class="name">
+              spcart
+            </div>
+            <div class="code-name">.iconspcart
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont iconmy"></span>
+            <div class="name">
+              my
+            </div>
+            <div class="code-name">.iconmy
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont iconindex"></span>
+            <div class="name">
+              index
+            </div>
+            <div class="code-name">.iconindex
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont iconyijianfankui"></span>
+            <div class="name">
+              意见反馈
+            </div>
+            <div class="code-name">.iconyijianfankui
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont iconlianxikefu"></span>
+            <div class="name">
+              联系客服
+            </div>
+            <div class="code-name">.iconlianxikefu
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont iconyiwancheng"></span>
+            <div class="name">
+              已完成
+            </div>
+            <div class="code-name">.iconyiwancheng
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont iconwodezuji"></span>
+            <div class="name">
+              我的足迹
+            </div>
+            <div class="code-name">.iconwodezuji
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icondaifahuo"></span>
+            <div class="name">
+              待发货
+            </div>
+            <div class="code-name">.icondaifahuo
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont iconwodeshoucang"></span>
+            <div class="name">
+              我的收藏
+            </div>
+            <div class="code-name">.iconwodeshoucang
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont iconshezhi"></span>
+            <div class="name">
+              设置
+            </div>
+            <div class="code-name">.iconshezhi
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icondaishouhuo"></span>
+            <div class="name">
+              待收货
+            </div>
+            <div class="code-name">.icondaishouhuo
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont iconquanbudingdan"></span>
+            <div class="name">
+              全部订单
+            </div>
+            <div class="code-name">.iconquanbudingdan
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icondaifukuan"></span>
+            <div class="name">
+              待付款
+            </div>
+            <div class="code-name">.icondaifukuan
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont iconwechat1"></span>
+            <div class="name">
+              wechat
+            </div>
+            <div class="code-name">.iconwechat1
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont iconbofangzanting"></span>
+            <div class="name">
+              播放暂停
+            </div>
+            <div class="code-name">.iconbofangzanting
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont iconbofang"></span>
+            <div class="name">
+              播放
+            </div>
+            <div class="code-name">.iconbofang
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icongouwudai"></span>
+            <div class="name">
+              购物袋
+            </div>
+            <div class="code-name">.icongouwudai
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont iconwechat"></span>
+            <div class="name">
+              wechat
+            </div>
+            <div class="code-name">.iconwechat
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont iconjiantou"></span>
+            <div class="name">
+              箭头
+            </div>
+            <div class="code-name">.iconjiantou
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icongouwuche"></span>
+            <div class="name">
+              购物车
+            </div>
+            <div class="code-name">.icongouwuche
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont iconfangdajing"></span>
+            <div class="name">
+              fangdajing
+            </div>
+            <div class="code-name">.iconfangdajing
+            </div>
+          </li>
+          
+        </ul>
+        <div class="article markdown">
+        <h2 id="font-class-">font-class 引用</h2>
+        <hr>
+
+        <p>font-class 是 Unicode 使用方式的一种变种,主要是解决 Unicode 书写不直观,语意不明确的问题。</p>
+        <p>与 Unicode 使用方式相比,具有如下特点:</p>
+        <ul>
+          <li>兼容性良好,支持 IE8+,及所有现代浏览器。</li>
+          <li>相比于 Unicode 语意明确,书写更直观。可以很容易分辨这个 icon 是什么。</li>
+          <li>因为使用 class 来定义图标,所以当要替换图标时,只需要修改 class 里面的 Unicode 引用。</li>
+          <li>不过因为本质上还是使用的字体,所以多色图标还是不支持的。</li>
+        </ul>
+        <p>使用步骤如下:</p>
+        <h3 id="-fontclass-">第一步:引入项目下面生成的 fontclass 代码:</h3>
+<pre><code class="language-html">&lt;link rel="stylesheet" href="./iconfont.css"&gt;
+</code></pre>
+        <h3 id="-">第二步:挑选相应图标并获取类名,应用于页面:</h3>
+<pre><code class="language-html">&lt;span class="iconfont iconxxx"&gt;&lt;/span&gt;
+</code></pre>
+        <blockquote>
+          <p>"
+            iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。</p>
+        </blockquote>
+      </div>
+      </div>
+      <div class="content symbol">
+          <ul class="icon_lists dib-box">
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#iconreserv_return"></use>
+                </svg>
+                <div class="name">reserv_return</div>
+                <div class="code-name">#iconreserv_return</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#iconreserv_arrows"></use>
+                </svg>
+                <div class="name">reserv_arrows</div>
+                <div class="code-name">#iconreserv_arrows</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#iconreserv_hot"></use>
+                </svg>
+                <div class="name">reserv_hot</div>
+                <div class="code-name">#iconreserv_hot</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#iconreserv_phone"></use>
+                </svg>
+                <div class="name">reserv_phone</div>
+                <div class="code-name">#iconreserv_phone</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#iconreserv_star"></use>
+                </svg>
+                <div class="name">reserv_star</div>
+                <div class="code-name">#iconreserv_star</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#iconreserv_2d"></use>
+                </svg>
+                <div class="name">reserv_2d</div>
+                <div class="code-name">#iconreserv_2d</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#iconreserv_room"></use>
+                </svg>
+                <div class="name">reserv_room</div>
+                <div class="code-name">#iconreserv_room</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#iconreserv_3d"></use>
+                </svg>
+                <div class="name">reserv_3d</div>
+                <div class="code-name">#iconreserv_3d</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#iconclassify"></use>
+                </svg>
+                <div class="name">classify</div>
+                <div class="code-name">#iconclassify</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#iconspcart"></use>
+                </svg>
+                <div class="name">spcart</div>
+                <div class="code-name">#iconspcart</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#iconmy"></use>
+                </svg>
+                <div class="name">my</div>
+                <div class="code-name">#iconmy</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#iconindex"></use>
+                </svg>
+                <div class="name">index</div>
+                <div class="code-name">#iconindex</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#iconyijianfankui"></use>
+                </svg>
+                <div class="name">意见反馈</div>
+                <div class="code-name">#iconyijianfankui</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#iconlianxikefu"></use>
+                </svg>
+                <div class="name">联系客服</div>
+                <div class="code-name">#iconlianxikefu</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#iconyiwancheng"></use>
+                </svg>
+                <div class="name">已完成</div>
+                <div class="code-name">#iconyiwancheng</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#iconwodezuji"></use>
+                </svg>
+                <div class="name">我的足迹</div>
+                <div class="code-name">#iconwodezuji</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icondaifahuo"></use>
+                </svg>
+                <div class="name">待发货</div>
+                <div class="code-name">#icondaifahuo</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#iconwodeshoucang"></use>
+                </svg>
+                <div class="name">我的收藏</div>
+                <div class="code-name">#iconwodeshoucang</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#iconshezhi"></use>
+                </svg>
+                <div class="name">设置</div>
+                <div class="code-name">#iconshezhi</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icondaishouhuo"></use>
+                </svg>
+                <div class="name">待收货</div>
+                <div class="code-name">#icondaishouhuo</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#iconquanbudingdan"></use>
+                </svg>
+                <div class="name">全部订单</div>
+                <div class="code-name">#iconquanbudingdan</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icondaifukuan"></use>
+                </svg>
+                <div class="name">待付款</div>
+                <div class="code-name">#icondaifukuan</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#iconwechat1"></use>
+                </svg>
+                <div class="name">wechat</div>
+                <div class="code-name">#iconwechat1</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#iconbofangzanting"></use>
+                </svg>
+                <div class="name">播放暂停</div>
+                <div class="code-name">#iconbofangzanting</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#iconbofang"></use>
+                </svg>
+                <div class="name">播放</div>
+                <div class="code-name">#iconbofang</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icongouwudai"></use>
+                </svg>
+                <div class="name">购物袋</div>
+                <div class="code-name">#icongouwudai</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#iconwechat"></use>
+                </svg>
+                <div class="name">wechat</div>
+                <div class="code-name">#iconwechat</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#iconjiantou"></use>
+                </svg>
+                <div class="name">箭头</div>
+                <div class="code-name">#iconjiantou</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icongouwuche"></use>
+                </svg>
+                <div class="name">购物车</div>
+                <div class="code-name">#icongouwuche</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#iconfangdajing"></use>
+                </svg>
+                <div class="name">fangdajing</div>
+                <div class="code-name">#iconfangdajing</div>
+            </li>
+          
+          </ul>
+          <div class="article markdown">
+          <h2 id="symbol-">Symbol 引用</h2>
+          <hr>
+
+          <p>这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇<a href="">文章</a>
+            这种用法其实是做了一个 SVG 的集合,与另外两种相比具有如下特点:</p>
+          <ul>
+            <li>支持多色图标了,不再受单色限制。</li>
+            <li>通过一些技巧,支持像字体那样,通过 <code>font-size</code>, <code>color</code> 来调整样式。</li>
+            <li>兼容性较差,支持 IE9+,及现代浏览器。</li>
+            <li>浏览器渲染 SVG 的性能一般,还不如 png。</li>
+          </ul>
+          <p>使用步骤如下:</p>
+          <h3 id="-symbol-">第一步:引入项目下面生成的 symbol 代码:</h3>
+<pre><code class="language-html">&lt;script src="./iconfont.js"&gt;&lt;/script&gt;
+</code></pre>
+          <h3 id="-css-">第二步:加入通用 CSS 代码(引入一次就行):</h3>
+<pre><code class="language-html">&lt;style&gt;
+.icon {
+  width: 1em;
+  height: 1em;
+  vertical-align: -0.15em;
+  fill: currentColor;
+  overflow: hidden;
+}
+&lt;/style&gt;
+</code></pre>
+          <h3 id="-">第三步:挑选相应图标并获取类名,应用于页面:</h3>
+<pre><code class="language-html">&lt;svg class="icon" aria-hidden="true"&gt;
+  &lt;use xlink:href="#icon-xxx"&gt;&lt;/use&gt;
+&lt;/svg&gt;
+</code></pre>
+          </div>
+      </div>
+
+    </div>
+  </div>
+  <script>
+  $(document).ready(function () {
+      $('.tab-container .content:first').show()
+
+      $('#tabs li').click(function (e) {
+        var tabContent = $('.tab-container .content')
+        var index = $(this).index()
+
+        if ($(this).hasClass('active')) {
+          return
+        } else {
+          $('#tabs li').removeClass('active')
+          $(this).addClass('active')
+
+          tabContent.hide().eq(index).fadeIn()
+        }
+      })
+    })
+  </script>
+</body>
+</html>

BIN
4dkankan-center-scene-download/src/main/resources/static/css/reserve/demo_index.html.gz


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 137 - 0
4dkankan-center-scene-download/src/main/resources/static/css/reserve/iconfont.css


BIN
4dkankan-center-scene-download/src/main/resources/static/css/reserve/iconfont.eot


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
4dkankan-center-scene-download/src/main/resources/static/css/reserve/iconfont.js


BIN
4dkankan-center-scene-download/src/main/resources/static/css/reserve/iconfont.js.gz


+ 219 - 0
4dkankan-center-scene-download/src/main/resources/static/css/reserve/iconfont.json

@@ -0,0 +1,219 @@
+{
+  "id": "1646991",
+  "name": "四维电商app",
+  "font_family": "iconfont",
+  "css_prefix_text": "icon",
+  "description": "",
+  "glyphs": [
+    {
+      "icon_id": "19936555",
+      "name": "reserv_return",
+      "font_class": "reserv_return",
+      "unicode": "e66b",
+      "unicode_decimal": 58987
+    },
+    {
+      "icon_id": "19936556",
+      "name": "reserv_arrows",
+      "font_class": "reserv_arrows",
+      "unicode": "e66c",
+      "unicode_decimal": 58988
+    },
+    {
+      "icon_id": "19936557",
+      "name": "reserv_hot",
+      "font_class": "reserv_hot",
+      "unicode": "e66d",
+      "unicode_decimal": 58989
+    },
+    {
+      "icon_id": "19936558",
+      "name": "reserv_phone",
+      "font_class": "reserv_phone",
+      "unicode": "e66f",
+      "unicode_decimal": 58991
+    },
+    {
+      "icon_id": "19936559",
+      "name": "reserv_star",
+      "font_class": "reserv_star",
+      "unicode": "e67b",
+      "unicode_decimal": 59003
+    },
+    {
+      "icon_id": "19936560",
+      "name": "reserv_2d",
+      "font_class": "reserv_2d",
+      "unicode": "e67c",
+      "unicode_decimal": 59004
+    },
+    {
+      "icon_id": "19936561",
+      "name": "reserv_room",
+      "font_class": "reserv_room",
+      "unicode": "e67d",
+      "unicode_decimal": 59005
+    },
+    {
+      "icon_id": "19936562",
+      "name": "reserv_3d",
+      "font_class": "reserv_3d",
+      "unicode": "e680",
+      "unicode_decimal": 59008
+    },
+    {
+      "icon_id": "13795689",
+      "name": "classify",
+      "font_class": "classify",
+      "unicode": "e6bf",
+      "unicode_decimal": 59071
+    },
+    {
+      "icon_id": "13795690",
+      "name": "spcart",
+      "font_class": "spcart",
+      "unicode": "e6c0",
+      "unicode_decimal": 59072
+    },
+    {
+      "icon_id": "13795691",
+      "name": "my",
+      "font_class": "my",
+      "unicode": "e6c1",
+      "unicode_decimal": 59073
+    },
+    {
+      "icon_id": "13795850",
+      "name": "index",
+      "font_class": "index",
+      "unicode": "e6c2",
+      "unicode_decimal": 59074
+    },
+    {
+      "icon_id": "13445723",
+      "name": "意见反馈",
+      "font_class": "yijianfankui",
+      "unicode": "e683",
+      "unicode_decimal": 59011
+    },
+    {
+      "icon_id": "13444544",
+      "name": "联系客服",
+      "font_class": "lianxikefu",
+      "unicode": "e682",
+      "unicode_decimal": 59010
+    },
+    {
+      "icon_id": "13444243",
+      "name": "已完成",
+      "font_class": "yiwancheng",
+      "unicode": "e681",
+      "unicode_decimal": 59009
+    },
+    {
+      "icon_id": "13442797",
+      "name": "我的足迹",
+      "font_class": "wodezuji",
+      "unicode": "e67f",
+      "unicode_decimal": 59007
+    },
+    {
+      "icon_id": "13442778",
+      "name": "待发货",
+      "font_class": "daifahuo",
+      "unicode": "e67e",
+      "unicode_decimal": 59006
+    },
+    {
+      "icon_id": "13442735",
+      "name": "我的收藏",
+      "font_class": "wodeshoucang",
+      "unicode": "e67a",
+      "unicode_decimal": 59002
+    },
+    {
+      "icon_id": "13442726",
+      "name": "设置",
+      "font_class": "shezhi",
+      "unicode": "e679",
+      "unicode_decimal": 59001
+    },
+    {
+      "icon_id": "13442724",
+      "name": "待收货",
+      "font_class": "daishouhuo",
+      "unicode": "e678",
+      "unicode_decimal": 59000
+    },
+    {
+      "icon_id": "13442721",
+      "name": "全部订单",
+      "font_class": "quanbudingdan",
+      "unicode": "e677",
+      "unicode_decimal": 58999
+    },
+    {
+      "icon_id": "13442720",
+      "name": "待付款",
+      "font_class": "daifukuan",
+      "unicode": "e676",
+      "unicode_decimal": 58998
+    },
+    {
+      "icon_id": "13314459",
+      "name": "wechat",
+      "font_class": "wechat1",
+      "unicode": "e675",
+      "unicode_decimal": 58997
+    },
+    {
+      "icon_id": "13282612",
+      "name": "播放暂停",
+      "font_class": "bofangzanting",
+      "unicode": "e674",
+      "unicode_decimal": 58996
+    },
+    {
+      "icon_id": "13282453",
+      "name": "播放",
+      "font_class": "bofang",
+      "unicode": "e673",
+      "unicode_decimal": 58995
+    },
+    {
+      "icon_id": "13282033",
+      "name": "购物袋",
+      "font_class": "gouwudai",
+      "unicode": "e672",
+      "unicode_decimal": 58994
+    },
+    {
+      "icon_id": "13186903",
+      "name": "wechat",
+      "font_class": "wechat",
+      "unicode": "e671",
+      "unicode_decimal": 58993
+    },
+    {
+      "icon_id": "8145817",
+      "name": "箭头",
+      "font_class": "jiantou",
+      "unicode": "e66e",
+      "unicode_decimal": 58990
+    },
+    {
+      "icon_id": "13096105",
+      "name": "购物车",
+      "font_class": "gouwuche",
+      "unicode": "e670",
+      "unicode_decimal": 58992
+    },
+    {
+      "icon_id": "7166069",
+      "name": "fangdajing",
+      "font_class": "fangdajing",
+      "unicode": "e635",
+      "unicode_decimal": 58933
+    }
+  ]
+}

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 116 - 0
4dkankan-center-scene-download/src/main/resources/static/css/reserve/iconfont.svg


BIN
4dkankan-center-scene-download/src/main/resources/static/css/reserve/iconfont.ttf


BIN
4dkankan-center-scene-download/src/main/resources/static/css/reserve/iconfont.woff


BIN
4dkankan-center-scene-download/src/main/resources/static/css/reserve/iconfont.woff2


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
4dkankan-center-scene-download/src/main/resources/static/css/smobile.32ca698d.css


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
4dkankan-center-scene-download/src/main/resources/static/css/spc.7b981504.css


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 15 - 0
4dkankan-center-scene-download/src/main/resources/static/dll/vendor.smobile.84ca42ff.js


BIN
4dkankan-center-scene-download/src/main/resources/static/dll/vendor.smobile.84ca42ff.js.gz


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 14 - 0
4dkankan-center-scene-download/src/main/resources/static/dll/vendor.spc.230960a0.js


BIN
4dkankan-center-scene-download/src/main/resources/static/dll/vendor.spc.230960a0.js.gz


BIN
4dkankan-center-scene-download/src/main/resources/static/img/0.a1bd0fb0.png


BIN
4dkankan-center-scene-download/src/main/resources/static/img/0.ef3ccb8f.png


BIN
4dkankan-center-scene-download/src/main/resources/static/img/1.93501122.png


BIN
4dkankan-center-scene-download/src/main/resources/static/img/1.d3e65825.png


BIN
4dkankan-center-scene-download/src/main/resources/static/img/2.c9287ece.png


BIN
4dkankan-center-scene-download/src/main/resources/static/img/End.png


BIN
4dkankan-center-scene-download/src/main/resources/static/img/End_128.png


BIN
4dkankan-center-scene-download/src/main/resources/static/img/End_unable.png


BIN
4dkankan-center-scene-download/src/main/resources/static/img/End_unable_128.png


BIN
4dkankan-center-scene-download/src/main/resources/static/img/apps/fire-control/avatar_default.png


BIN
4dkankan-center-scene-download/src/main/resources/static/img/apps/fire-control/fire_appendix@2x.png


BIN
4dkankan-center-scene-download/src/main/resources/static/img/apps/fire-control/fire_building.png


BIN
4dkankan-center-scene-download/src/main/resources/static/img/apps/fire-control/fire_bus.png


BIN
4dkankan-center-scene-download/src/main/resources/static/img/apps/fire-control/fire_cancel@2x.png


BIN
4dkankan-center-scene-download/src/main/resources/static/img/apps/fire-control/fire_exit@2x.png


BIN
4dkankan-center-scene-download/src/main/resources/static/img/apps/fire-control/fire_mic_off@2x.png


BIN
4dkankan-center-scene-download/src/main/resources/static/img/apps/fire-control/fire_mic_on@2x.png


BIN
4dkankan-center-scene-download/src/main/resources/static/img/apps/fire-control/fire_other.png


BIN
4dkankan-center-scene-download/src/main/resources/static/img/apps/fire-control/fire_pen_off@2x.png


BIN
4dkankan-center-scene-download/src/main/resources/static/img/apps/fire-control/fire_pen_on@2x.png


BIN
4dkankan-center-scene-download/src/main/resources/static/img/apps/fire-control/fire_recycle.png


BIN
4dkankan-center-scene-download/src/main/resources/static/img/apps/fire-control/fire_share@2x.png


BIN
4dkankan-center-scene-download/src/main/resources/static/img/apps/fire-control/fire_vr@2x.png


BIN
4dkankan-center-scene-download/src/main/resources/static/img/apps/fire-control/reserv_return.png


BIN
4dkankan-center-scene-download/src/main/resources/static/img/apps/fire/D5aeUSngt/卫生间.jpg


BIN
4dkankan-center-scene-download/src/main/resources/static/img/apps/fire/D5aeUSngt/厨房.jpg


BIN
4dkankan-center-scene-download/src/main/resources/static/img/apps/fire/D5aeUSngt/大堂.jpg


BIN
4dkankan-center-scene-download/src/main/resources/static/img/apps/fire/MEzMZYcFh/主卧.jpg


BIN
4dkankan-center-scene-download/src/main/resources/static/img/apps/fire/MEzMZYcFh/卫生间.jpg


BIN
4dkankan-center-scene-download/src/main/resources/static/img/apps/fire/MEzMZYcFh/客卧.jpg


BIN
4dkankan-center-scene-download/src/main/resources/static/img/apps/fire/MEzMZYcFh/客厅.jpg


BIN
4dkankan-center-scene-download/src/main/resources/static/img/apps/fire/MEzMZYcFh/晾衣间.jpg


BIN
4dkankan-center-scene-download/src/main/resources/static/img/apps/fire/XXNkdefa6/大厅.jpg


BIN
4dkankan-center-scene-download/src/main/resources/static/img/apps/fire/r1Pwypv0K/主卧.jpg


BIN
4dkankan-center-scene-download/src/main/resources/static/img/apps/fire/r1Pwypv0K/卫生间.jpg


BIN
4dkankan-center-scene-download/src/main/resources/static/img/apps/fire/r1Pwypv0K/厨房.jpg


BIN
4dkankan-center-scene-download/src/main/resources/static/img/apps/fire/r1Pwypv0K/客厅.jpg


BIN
4dkankan-center-scene-download/src/main/resources/static/img/apps/fire/r1Pwypv0K/晾衣间.jpg


+ 0 - 0
4dkankan-center-scene-download/src/main/resources/static/img/apps/fire/r1Pwypv0K/晾衣间阳台.jpg


이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.