tujidelv 3 jaren geleden
commit
4fd3436f4c
58 gewijzigde bestanden met toevoegingen van 11452 en 0 verwijderingen
  1. 31 0
      .gitignore
  2. 103 0
      pom.xml
  3. 15 0
      src/main/java/top/lvzhiqiang/App.java
  4. 24 0
      src/main/java/top/lvzhiqiang/config/GlobalExceptionHandler.java
  5. 33 0
      src/main/java/top/lvzhiqiang/config/InitRunner.java
  6. 61 0
      src/main/java/top/lvzhiqiang/config/WebAppConfig.java
  7. 49 0
      src/main/java/top/lvzhiqiang/config/WebLogAspect.java
  8. 57 0
      src/main/java/top/lvzhiqiang/controller/IndexController.java
  9. 43 0
      src/main/java/top/lvzhiqiang/controller/VideoInfoController.java
  10. 27 0
      src/main/java/top/lvzhiqiang/dto/JavAllInfo.java
  11. 44 0
      src/main/java/top/lvzhiqiang/dto/VideoInfoQuery.java
  12. 59 0
      src/main/java/top/lvzhiqiang/entity/DicCode.java
  13. 59 0
      src/main/java/top/lvzhiqiang/entity/VideoCast.java
  14. 89 0
      src/main/java/top/lvzhiqiang/entity/VideoCastDetail.java
  15. 54 0
      src/main/java/top/lvzhiqiang/entity/VideoGenres.java
  16. 100 0
      src/main/java/top/lvzhiqiang/entity/VideoInfo.java
  17. 43 0
      src/main/java/top/lvzhiqiang/entity/VideoInfoCast.java
  18. 43 0
      src/main/java/top/lvzhiqiang/entity/VideoInfoGenres.java
  19. 44 0
      src/main/java/top/lvzhiqiang/mapper/DicCodeMapper.java
  20. 54 0
      src/main/java/top/lvzhiqiang/mapper/VideoCastMapper.java
  21. 54 0
      src/main/java/top/lvzhiqiang/mapper/VideoGenresMapper.java
  22. 45 0
      src/main/java/top/lvzhiqiang/mapper/VideoInfoCastMapper.java
  23. 46 0
      src/main/java/top/lvzhiqiang/mapper/VideoInfoGenresMapper.java
  24. 62 0
      src/main/java/top/lvzhiqiang/mapper/VideoInfoMapper.java
  25. 11 0
      src/main/java/top/lvzhiqiang/service/BaseService.java
  26. 29 0
      src/main/java/top/lvzhiqiang/service/VideoCastService.java
  27. 29 0
      src/main/java/top/lvzhiqiang/service/VideoGenresService.java
  28. 43 0
      src/main/java/top/lvzhiqiang/service/VideoInfoService.java
  29. 115 0
      src/main/java/top/lvzhiqiang/service/impl/BaseServiceImpl.java
  30. 47 0
      src/main/java/top/lvzhiqiang/service/impl/VideoCastServiceImpl.java
  31. 47 0
      src/main/java/top/lvzhiqiang/service/impl/VideoGenresServiceImpl.java
  32. 257 0
      src/main/java/top/lvzhiqiang/service/impl/VideoInfoServiceImpl.java
  33. 338 0
      src/main/java/top/lvzhiqiang/util/DateUtils.java
  34. 57 0
      src/main/java/top/lvzhiqiang/util/StringUtils.java
  35. 79 0
      src/main/resources/application.yml
  36. 28 0
      src/main/resources/log4j.properties
  37. 23 0
      src/main/resources/mapper/VideoInfoMapper.xml
  38. BIN
      src/main/resources/static/cover/favicon.ico
  39. BIN
      src/main/resources/static/cover/load.png
  40. BIN
      src/main/resources/static/cover/loading.gif
  41. BIN
      src/main/resources/static/cover/no.png
  42. BIN
      src/main/resources/static/cover/play.png
  43. 94 0
      src/main/resources/static/css/my.css
  44. 131 0
      src/main/resources/static/css/mytheme-color3.css
  45. 2926 0
      src/main/resources/static/css/mytheme-font.css
  46. 692 0
      src/main/resources/static/css/mytheme-site.css
  47. 2929 0
      src/main/resources/static/css/mytheme-ui.css
  48. BIN
      src/main/resources/static/font/fontawesome-webfont.eot
  49. BIN
      src/main/resources/static/font/fontawesome-webfont.ttf
  50. BIN
      src/main/resources/static/font/fontawesome-webfont.woff
  51. BIN
      src/main/resources/static/font/fontawesome-webfont.woff2
  52. 98 0
      src/main/resources/static/index.html
  53. 1 0
      src/main/resources/static/js/jquery-3.6.0.min.js
  54. 215 0
      src/main/resources/static/js/my.js
  55. 1775 0
      src/main/resources/static/js/mytheme-site.js
  56. 95 0
      src/main/resources/static/js/pagination.js
  57. 109 0
      src/main/resources/templates/ftlIndex.ftl
  58. 45 0
      src/test/java/Test.java

+ 31 - 0
.gitignore

@@ -0,0 +1,31 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**
+!**/src/test/**
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+
+### VS Code ###
+.vscode/

+ 103 - 0
pom.xml

@@ -0,0 +1,103 @@
+<?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">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>top.lvzhiqiang</groupId>
+    <artifactId>l1024v-jav</artifactId>
+    <version>1.0.0</version>
+
+    <!-- 项目的名称和描述 -->
+    <name>l1024v-jav-server</name>
+    <description>jav服务</description>
+
+    <properties>
+        <maven.compiler.source>8</maven.compiler.source>
+        <maven.compiler.target>8</maven.compiler.target>
+        <maven.deploy.skip>true</maven.deploy.skip>
+    </properties>
+
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.1.9.RELEASE</version>
+    </parent>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-aop</artifactId>
+        </dependency>
+        <!-- 引入Web功能 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <!-- Freemarker -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-freemarker</artifactId>
+        </dependency>
+        <!--log4j2-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter</artifactId>
+            <exclusions>
+                <!-- 排除自带的logback依赖 -->
+                <exclusion>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-logging</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-log4j</artifactId>
+            <version>1.3.8.RELEASE</version>
+        </dependency>
+        <!--mybatis-->
+        <dependency>
+            <groupId>org.mybatis.spring.boot</groupId>
+            <artifactId>mybatis-spring-boot-starter</artifactId>
+            <version>2.1.0</version>
+        </dependency>
+        <dependency>
+            <groupId>com.github.pagehelper</groupId>
+            <artifactId>pagehelper-spring-boot-starter</artifactId>
+            <version>1.2.12</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+            <version>3.7</version>
+        </dependency>
+        <!-- mysql的驱动 -->
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <!--lombok-->
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>1.16.20</version>
+        </dependency>
+        <!--fastjson-->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.54</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <finalName>jav</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 15 - 0
src/main/java/top/lvzhiqiang/App.java

@@ -0,0 +1,15 @@
+package top.lvzhiqiang;
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableAsync;
+
+@MapperScan(basePackages = "top.lvzhiqiang.mapper")
+@SpringBootApplication
+@EnableAsync
+public class App {
+    public static void main(String[] args) {
+        SpringApplication.run(App.class, args);
+    }
+}

+ 24 - 0
src/main/java/top/lvzhiqiang/config/GlobalExceptionHandler.java

@@ -0,0 +1,24 @@
+package top.lvzhiqiang.config;
+
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 全局捕获异常
+ */
+@ControllerAdvice(basePackages = "top.lvzhiqiang.controller")
+public class GlobalExceptionHandler {
+
+    @ExceptionHandler(RuntimeException.class)
+    @ResponseBody
+    public Map<String, Object> exceptionHandler() {
+        Map<String, Object> map = new HashMap<>();
+        map.put("errorCode", "101");
+        map.put("errorMsg", "系統错误!");
+        return map;
+    }
+}

+ 33 - 0
src/main/java/top/lvzhiqiang/config/InitRunner.java

@@ -0,0 +1,33 @@
+package top.lvzhiqiang.config;
+
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import top.lvzhiqiang.entity.DicCode;
+import top.lvzhiqiang.mapper.DicCodeMapper;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 初始化Runner
+ *
+ * @author lvzhiqiang
+ * 2020/7/2 10:55
+ */
+@Component
+@Order(value = 1)
+public class InitRunner implements ApplicationRunner {
+
+    public static List<DicCode> dicCodeList = new ArrayList<>();
+
+    @Resource
+    private DicCodeMapper dicCodeMapper;
+
+    @Override
+    public void run(ApplicationArguments args) {
+
+    }
+}

+ 61 - 0
src/main/java/top/lvzhiqiang/config/WebAppConfig.java

@@ -0,0 +1,61 @@
+package top.lvzhiqiang.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.StringHttpMessageConverter;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+import top.lvzhiqiang.entity.DicCode;
+import top.lvzhiqiang.mapper.DicCodeMapper;
+
+import javax.annotation.Resource;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 静态资源过滤配置器
+ *
+ * @author lvzhiqiang
+ * 2022/4/5 12:00
+ */
+@Configuration
+public class WebAppConfig implements WebMvcConfigurer {
+
+    private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
+            "classpath:/META-INF/resources/", "classpath:/resources/",
+            "classpath:/static/", "classpath:/public/"};
+
+    public static List<DicCode> dicCodeList = new ArrayList<>();
+
+    @Resource
+    private DicCodeMapper dicCodeMapper;
+
+    @Override
+    public void addResourceHandlers(ResourceHandlerRegistry registry) {
+        if (!registry.hasMappingForPattern("/webjars/**")) {
+            registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
+        }
+        //if (!registry.hasMappingForPattern("/**")) {
+        //    registry.addResourceHandler("/**").addResourceLocations(CLASSPATH_RESOURCE_LOCATIONS);
+        //}
+
+        // 初始化字典码表
+        dicCodeList = dicCodeMapper.findAll();
+        DicCode dicCode = dicCodeList.stream().filter(x -> 1 == x.getType() && "pic_path".equals(x.getCodeKey())).findFirst().get();
+        String picPath = "F:/1/0/2/4/视频/电影/A级(成人级)/骑兵/";
+        if (dicCode != null) {
+            picPath = dicCode.getCodeValue();
+        }
+        registry.addResourceHandler("/image/**").addResourceLocations("file:" + picPath);
+    }
+
+    @Bean
+    public HttpMessageConverter responseBodyConverter() {
+        //解决返回值中文乱码
+        StringHttpMessageConverter converter = new StringHttpMessageConverter(StandardCharsets.UTF_8);
+        return converter;
+    }
+}

+ 49 - 0
src/main/java/top/lvzhiqiang/config/WebLogAspect.java

@@ -0,0 +1,49 @@
+package top.lvzhiqiang.config;
+
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.AfterReturning;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.aspectj.lang.annotation.Pointcut;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Enumeration;
+
+/**
+ * 使用AOP统一处理Web请求日志
+ */
+@Aspect
+@Component
+public class WebLogAspect {
+
+    private static final Logger logger = LoggerFactory.getLogger(WebLogAspect.class);
+
+    @Pointcut("execution(public * top.lvzhiqiang.controller.*.*(..))")
+    public void webLog() {
+    }
+
+    @Before("webLog()")
+    public void doBefore(JoinPoint joinPoint) throws Throwable {
+        // 接收到请求,记录请求内容
+        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        HttpServletRequest request = attributes.getRequest();
+        // 记录下请求内容
+        logger.info("REQUEST : URL={},HTTP_METHOD={},IP={}", request.getRequestURL().toString(), request.getMethod(), request.getRemoteAddr());
+        Enumeration<String> enu = request.getParameterNames();
+        while (enu.hasMoreElements()) {
+            String name = enu.nextElement();
+            logger.info("name:{},value:{}", name, request.getParameter(name));
+        }
+    }
+
+    @AfterReturning(returning = "ret", pointcut = "webLog()")
+    public void doAfterReturning(Object ret) throws Throwable {
+        // 处理完请求,返回内容
+        logger.info("RESPONSE : " + ret);
+    }
+}

+ 57 - 0
src/main/java/top/lvzhiqiang/controller/IndexController.java

@@ -0,0 +1,57 @@
+package top.lvzhiqiang.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.github.pagehelper.PageInfo;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+import top.lvzhiqiang.entity.VideoCast;
+import top.lvzhiqiang.entity.VideoGenres;
+import top.lvzhiqiang.entity.VideoInfo;
+import top.lvzhiqiang.service.VideoCastService;
+import top.lvzhiqiang.service.VideoInfoService;
+import top.lvzhiqiang.service.VideoGenresService;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * INDEX Controller
+ *
+ * @author lvzhiqiang
+ * 2022/4/4 15:28
+ */
+@Controller
+public class IndexController {
+
+    @Resource
+    private VideoCastService videoCastService;
+
+    @Resource
+    private VideoInfoService videoInfoService;
+
+    @Resource
+    private VideoGenresService videoGenresService;
+
+    @RequestMapping("/getIndexInfo")
+    @ResponseBody
+    public JSONObject getIndexInfo(int pageNo, int pageSize) {
+        JSONObject result = new JSONObject();
+        List<VideoCast> videoCastList = videoCastService.findAll();
+        List<VideoGenres> videoGenresList = videoGenresService.findAll();
+        PageInfo<VideoInfo> videoInfoPage = videoInfoService.findAll(pageNo, pageSize);
+
+        result.put("videoCastList", videoCastList);
+        result.put("videoGenresList", videoGenresList);
+        result.put("videoInfoPage", videoInfoPage);
+        return result;
+    }
+
+    @RequestMapping("/initData")
+    @ResponseBody
+    public String initData() {
+        videoInfoService.initData();
+
+        return "success";
+    }
+}

+ 43 - 0
src/main/java/top/lvzhiqiang/controller/VideoInfoController.java

@@ -0,0 +1,43 @@
+package top.lvzhiqiang.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.github.pagehelper.PageInfo;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import top.lvzhiqiang.dto.VideoInfoQuery;
+import top.lvzhiqiang.entity.VideoInfo;
+import top.lvzhiqiang.service.VideoInfoService;
+
+import javax.annotation.Resource;
+import java.util.HashMap;
+
+/**
+ * 电影信息 Controller
+ *
+ * @author lvzhiqiang
+ * 2022/4/9 11:02
+ */
+@RestController
+@RequestMapping("/videoInfo")
+public class VideoInfoController {
+
+    @Resource
+    private VideoInfoService videoInfoService;
+
+    /**
+     * 影片列表分页
+     *
+     * @param videoInfoQuery
+     * @return com.github.pagehelper.PageInfo<top.lvzhiqiang.entity.VideoInfo>
+     * @author lvzhiqiang
+     * 2022/4/9 11:02
+     */
+    @PostMapping("/getVideoInfoPage")
+    public PageInfo<VideoInfo> getVideoInfoPage(@RequestBody VideoInfoQuery videoInfoQuery) {
+
+        return videoInfoService.getVideoInfoPage(JSON.parseObject(JSON.toJSONString(videoInfoQuery), HashMap.class));
+    }
+}

+ 27 - 0
src/main/java/top/lvzhiqiang/dto/JavAllInfo.java

@@ -0,0 +1,27 @@
+package top.lvzhiqiang.dto;
+
+import lombok.Data;
+import top.lvzhiqiang.entity.VideoInfo;
+import top.lvzhiqiang.entity.VideoInfoCast;
+import top.lvzhiqiang.entity.VideoInfoGenres;
+
+import java.io.Serializable;
+import java.util.*;
+
+@Data
+public class JavAllInfo implements Serializable {
+
+    // 类别
+    private Set<String> videoGenresSet = new HashSet<>();
+
+    // 演员
+    private Map<String, String> videoCastMap = new HashMap<>();
+
+    // 影片信息
+    private List<VideoInfo> videoInfoList = new ArrayList<>();
+
+    // 电影信息类别关联表
+    Set<VideoInfoGenres> videoInfoGenresSet = new TreeSet<>(Comparator.comparing(o -> (o.getIdentificationCode().concat(o.getName()))));
+    // 电影信息演员关联表
+    Set<VideoInfoCast> videoInfoCastSet = new TreeSet<>(Comparator.comparing(o -> (o.getIdentificationCode().concat(o.getName()))));
+}

+ 44 - 0
src/main/java/top/lvzhiqiang/dto/VideoInfoQuery.java

@@ -0,0 +1,44 @@
+package top.lvzhiqiang.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class VideoInfoQuery implements Serializable {
+
+    /**
+     * 关键词
+     */
+    private String keyword;
+
+    /**
+     * 类别
+     */
+    private String genres;
+
+    /**
+     * 演员
+     */
+    private String cast;
+
+    /**
+     * 排序{desc|asc}
+     */
+    private String order;
+
+    /**
+     * 排序字段
+     */
+    private String orderField;
+
+    /**
+     * 页号
+     */
+    private Integer pageNo;
+
+    /**
+     * 页大小
+     */
+    private Integer pageSize;
+}

+ 59 - 0
src/main/java/top/lvzhiqiang/entity/DicCode.java

@@ -0,0 +1,59 @@
+package top.lvzhiqiang.entity;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 字典码
+ *
+ * @author lvzhiqiang
+ * 2022/4/4 15:28
+ */
+@Data
+public class DicCode implements Serializable {
+
+    /**
+     * 主键
+     */
+    private Long id;
+
+    /**
+     * key
+     */
+    private String codeKey;
+
+    /**
+     * value
+     */
+    private String codeValue;
+
+    /**
+     * desc
+     */
+    private String codeDesc;
+
+    /**
+     * 类型
+     */
+    private Integer type;
+
+    /**
+     * 删除标志{1:正常,2:已删除}
+     */
+    private Integer deleteFlag;
+
+    /**
+     * 创建时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime createTime;
+
+    /**
+     * 最后修改时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime modifyTime;
+}

+ 59 - 0
src/main/java/top/lvzhiqiang/entity/VideoCast.java

@@ -0,0 +1,59 @@
+package top.lvzhiqiang.entity;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 电影演员
+ *
+ * @author lvzhiqiang
+ * 2022/4/4 15:28
+ */
+@Data
+public class VideoCast implements Serializable {
+
+    /**
+     * 主键
+     */
+    private Long id;
+
+    /**
+     * 名称
+     */
+    private String name;
+
+    /**
+     * 内部编码
+     */
+    private String code;
+
+    /**
+     * 类型{1:男,2:女}
+     */
+    private Integer type;
+
+    /**
+     * 排序
+     */
+    private Integer sort;
+
+    /**
+     * 删除标志{1:正常,2:已删除}
+     */
+    private Integer deleteFlag;
+
+    /**
+     * 创建时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime createTime;
+
+    /**
+     * 最后修改时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime modifyTime;
+}

+ 89 - 0
src/main/java/top/lvzhiqiang/entity/VideoCastDetail.java

@@ -0,0 +1,89 @@
+package top.lvzhiqiang.entity;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 电影演员详细
+ *
+ * @author lvzhiqiang
+ * 2022/4/4 15:28
+ */
+@Data
+public class VideoCastDetail implements Serializable {
+
+    /**
+     * 主键
+     */
+    private Long id;
+
+    /**
+     * cast_id
+     */
+    private Long castId;
+
+    /**
+     * 头像
+     */
+    private byte[] headImg;
+
+    /**
+     * 生日
+     */
+    private String birthday;
+
+    /**
+     * 年齡
+     */
+    private Integer age;
+
+    /**
+     * 身高
+     */
+    private String height;
+
+    /**
+     * 罩杯
+     */
+    private String cup;
+
+    /**
+     * 胸圍
+     */
+    private String bust;
+
+    /**
+     * 腰圍
+     */
+    private String waist;
+
+    /**
+     * 臀圍
+     */
+    private String hip;
+
+    /**
+     * 愛好
+     */
+    private String hobby;
+
+    /**
+     * 删除标志{1:正常,2:已删除}
+     */
+    private Integer deleteFlag;
+
+    /**
+     * 创建时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime createTime;
+
+    /**
+     * 最后修改时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime modifyTime;
+}

+ 54 - 0
src/main/java/top/lvzhiqiang/entity/VideoGenres.java

@@ -0,0 +1,54 @@
+package top.lvzhiqiang.entity;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 电影类别
+ *
+ * @author lvzhiqiang
+ * 2022/4/4 15:28
+ */
+@Data
+public class VideoGenres implements Serializable {
+
+    /**
+     * 主键
+     */
+    private Long id;
+
+    /**
+     * 名称
+     */
+    private String name;
+
+    /**
+     * 内部编码
+     */
+    private String code;
+
+    /**
+     * 排序
+     */
+    private Integer sort;
+
+    /**
+     * 删除标志{1:正常,2:已删除}
+     */
+    private Integer deleteFlag;
+
+    /**
+     * 创建时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime createTime;
+
+    /**
+     * 最后修改时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime modifyTime;
+}

+ 100 - 0
src/main/java/top/lvzhiqiang/entity/VideoInfo.java

@@ -0,0 +1,100 @@
+package top.lvzhiqiang.entity;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import top.lvzhiqiang.util.DateUtils;
+
+import java.io.Serializable;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.*;
+
+/**
+ * 电影信息
+ *
+ * @author lvzhiqiang
+ * 2022/4/4 15:28
+ */
+@Data
+public class VideoInfo implements Serializable {
+
+    /**
+     * 主键
+     */
+    private Long id;
+
+    /**
+     * 名称
+     */
+    private String name;
+
+    /**
+     * 识别码
+     */
+    private String identificationCode;
+
+    /**
+     * 发行日期
+     */
+    @JsonFormat(pattern = DateUtils.PATTERN_TO_DAYS)
+    private LocalDate issueDate;
+
+    /**
+     * 长度
+     */
+    private String length;
+
+    /**
+     * 导演
+     */
+    private String director;
+
+    /**
+     * 制作商
+     */
+    private String maker;
+
+    /**
+     * 发行商
+     */
+    private String issuer;
+
+    /**
+     * 图片URL
+     */
+    private String imgUrl;
+
+    /**
+     * 影片URL
+     */
+    private String videoUrl;
+
+    /**
+     * 类型{1:有码,2:无码}
+     */
+    private Integer type;
+
+    /**
+     * 主体是谁
+     */
+    private String mainWho;
+
+    /**
+     * 删除标志{1:正常,2:已删除}
+     */
+    private Integer deleteFlag;
+
+    /**
+     * 创建时间
+     */
+    @JsonFormat(pattern = DateUtils.PATTERN_TO_SECONDS)
+    private LocalDateTime createTime;
+
+    /**
+     * 最后修改时间
+     */
+    @JsonFormat(pattern = DateUtils.PATTERN_TO_SECONDS)
+    private LocalDateTime modifyTime;
+
+    private String score;
+}

+ 43 - 0
src/main/java/top/lvzhiqiang/entity/VideoInfoCast.java

@@ -0,0 +1,43 @@
+package top.lvzhiqiang.entity;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 电影信息类别关联表
+ *
+ * @author lvzhiqiang
+ * 2022/4/9 21:36
+ */
+@Data
+public class VideoInfoCast implements Serializable {
+
+    /**
+     * 主键
+     */
+    private Long id;
+
+    /**
+     * 识别码
+     */
+    private String identificationCode;
+
+    /**
+     * 类别名称
+     */
+    private String name;
+
+    /**
+     * 类型{1:主体,2:链接}
+     */
+    private Integer type;
+
+    /**
+     * 创建时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime createTime;
+}

+ 43 - 0
src/main/java/top/lvzhiqiang/entity/VideoInfoGenres.java

@@ -0,0 +1,43 @@
+package top.lvzhiqiang.entity;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 电影信息演员关联表
+ *
+ * @author lvzhiqiang
+ * 2022/4/9 21:36
+ */
+@Data
+public class VideoInfoGenres implements Serializable {
+
+    /**
+     * 主键
+     */
+    private Long id;
+
+    /**
+     * 识别码
+     */
+    private String identificationCode;
+
+    /**
+     * 演员名称
+     */
+    private String name;
+
+    /**
+     * 类型{1:主体,2:链接}
+     */
+    private Integer type;
+
+    /**
+     * 创建时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime createTime;
+}

+ 44 - 0
src/main/java/top/lvzhiqiang/mapper/DicCodeMapper.java

@@ -0,0 +1,44 @@
+package top.lvzhiqiang.mapper;
+
+import org.apache.ibatis.annotations.Delete;
+import org.apache.ibatis.annotations.Insert;
+import org.apache.ibatis.annotations.Select;
+import top.lvzhiqiang.entity.DicCode;
+import top.lvzhiqiang.entity.VideoCast;
+
+import java.util.List;
+
+/**
+ * 字典码Mapper
+ *
+ * @author lvzhiqiang
+ * 2022/4/6 20:47
+ */
+public interface DicCodeMapper {
+
+    /**
+     * 删除所有
+     */
+    @Delete("DELETE FROM dic_code")
+    void deleteAll();
+
+    /**
+     * 批量新增
+     *
+     * @param dicCodeList
+     */
+    @Insert({"<script>" +
+            "INSERT INTO dic_code(code_key, code_value, code_desc, type, create_time, modify_time) " +
+            "VALUES " +
+            "<foreach collection='list' item='dc' index=\"index\" separator=\",\">" +
+            "   (#{dc.codeKey}, #{dc.codeValue}, #{dc.codeDesc}, #{dc.type}, now(), now())" +
+            " </foreach>" +
+            "</script>"})
+    void insertList(List<DicCode> dicCodeList);
+
+    /**
+     * 查询所有
+     */
+    @Select("SELECT * FROM dic_code WHERE delete_flag = 1")
+    List<DicCode> findAll();
+}

+ 54 - 0
src/main/java/top/lvzhiqiang/mapper/VideoCastMapper.java

@@ -0,0 +1,54 @@
+package top.lvzhiqiang.mapper;
+
+import org.apache.ibatis.annotations.Delete;
+import org.apache.ibatis.annotations.Insert;
+import org.apache.ibatis.annotations.Options;
+import org.apache.ibatis.annotations.Select;
+import top.lvzhiqiang.entity.VideoCast;
+
+import java.util.List;
+
+/**
+ * 电影演员Mapper
+ *
+ * @author lvzhiqiang
+ * 2022/4/4 15:28
+ */
+public interface VideoCastMapper {
+
+    /**
+     * 删除所有
+     */
+    @Delete("DELETE FROM video_cast where 1=1")
+    void deleteAll();
+
+    /**
+     * 批量新增
+     *
+     * @param videoCastList
+     */
+    @Insert({"<script>" +
+            "INSERT INTO video_cast(name, code, type, sort, create_time, modify_time) " +
+            "VALUES " +
+            "<foreach collection='list' item='vc' index=\"index\" separator=\",\">" +
+            "   (#{ve.name}, #{ve.code}, #{ve.type}, #{ve.sort}, now(), now())" +
+            " </foreach>" +
+            "</script>"})
+    void insertList(List<VideoCast> videoCastList);
+
+    /**
+     * 新增
+     *
+     * @param videoCast
+     */
+    @Insert("INSERT INTO video_cast(name, code, type, sort, create_time, modify_time) " +
+            "VALUES (#{name}, #{code}, #{type}, #{sort}, now(), now())")
+    @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
+    int insert(VideoCast videoCast);
+
+    /**
+     * 查询所有
+     */
+    @Select("SELECT * FROM video_cast WHERE delete_flag = 1 ORDER BY sort")
+    List<VideoCast> findAll();
+}

+ 54 - 0
src/main/java/top/lvzhiqiang/mapper/VideoGenresMapper.java

@@ -0,0 +1,54 @@
+package top.lvzhiqiang.mapper;
+
+import org.apache.ibatis.annotations.Delete;
+import org.apache.ibatis.annotations.Insert;
+import org.apache.ibatis.annotations.Options;
+import org.apache.ibatis.annotations.Select;
+import top.lvzhiqiang.entity.VideoGenres;
+
+import java.util.List;
+
+/**
+ * 电影类别Mapper
+ *
+ * @author lvzhiqiang
+ * 2022/4/4 15:28
+ */
+public interface VideoGenresMapper {
+
+    /**
+     * 删除所有
+     */
+    @Delete("DELETE FROM video_genres where 1=1")
+    void deleteAll();
+
+    /**
+     * 批量新增
+     *
+     * @param videoGenresList
+     */
+    @Insert({"<script>" +
+            "INSERT INTO video_genres(name, code, sort, create_time, modify_time) " +
+            "VALUES " +
+            "<foreach collection='list' item='ve' index=\"index\" separator=\",\">" +
+            "   (#{ve.name}, #{ve.code}, #{ve.sort}, now(), now())" +
+            " </foreach>" +
+            "</script>"})
+    void insertList(List<VideoGenres> videoGenresList);
+
+    /**
+     * 新增
+     *
+     * @param videoGenres
+     */
+    @Insert("INSERT INTO video_genres(name, code, sort, create_time, modify_time) " +
+            "VALUES (#{name}, #{code}, #{sort}, now(), now())")
+    @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
+    int insert(VideoGenres videoGenres);
+
+    /**
+     * 查询所有
+     */
+    @Select("SELECT * FROM video_genres WHERE delete_flag = 1 ORDER BY sort")
+    List<VideoGenres> findAll();
+}

+ 45 - 0
src/main/java/top/lvzhiqiang/mapper/VideoInfoCastMapper.java

@@ -0,0 +1,45 @@
+package top.lvzhiqiang.mapper;
+
+import org.apache.ibatis.annotations.Delete;
+import org.apache.ibatis.annotations.Insert;
+import top.lvzhiqiang.entity.VideoInfoCast;
+
+import java.util.Set;
+
+/**
+ * 电影信息演员关联Mapper
+ *
+ * @author lvzhiqiang
+ * 2022/4/9 21:36
+ */
+public interface VideoInfoCastMapper {
+
+    /**
+     * 删除所有
+     */
+    @Delete("DELETE FROM video_info_cast where 1=1")
+    void deleteAll();
+
+    /**
+     * 批量新增
+     *
+     * @param videoInfoCastList
+     */
+    @Insert({"<script>" +
+            "INSERT INTO video_info_cast(identification_code, name , type, create_time) " +
+            "VALUES " +
+            "<foreach collection='collection' item='vic' index=\"index\" separator=\",\">" +
+            "   (#{vic.identificationCode}, #{vic.name}, #{vic.type}, now())" +
+            " </foreach>" +
+            "</script>"})
+    void insertList(Set<VideoInfoCast> videoInfoCastList);
+
+    /**
+     * 新增
+     *
+     * @param videoInfoCast
+     */
+    @Insert("INSERT INTO video_info_cast(identification_code, name , type, create_time) " +
+            "VALUES (#{identificationCode}, #{name}, #{type}, now())")
+    int insert(VideoInfoCast videoInfoCast);
+}

+ 46 - 0
src/main/java/top/lvzhiqiang/mapper/VideoInfoGenresMapper.java

@@ -0,0 +1,46 @@
+package top.lvzhiqiang.mapper;
+
+import org.apache.ibatis.annotations.Delete;
+import org.apache.ibatis.annotations.Insert;
+import top.lvzhiqiang.entity.VideoInfoGenres;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * 电影信息类别关联Mapper
+ *
+ * @author lvzhiqiang
+ * 2022/4/9 21:36
+ */
+public interface VideoInfoGenresMapper {
+
+    /**
+     * 删除所有
+     */
+    @Delete("DELETE FROM video_info_genres where 1=1")
+    void deleteAll();
+
+    /**
+     * 批量新增
+     *
+     * @param videoInfoGenresList
+     */
+    @Insert({"<script>" +
+            "INSERT INTO video_info_genres(identification_code, name , type, create_time) " +
+            "VALUES " +
+            "<foreach collection='collection' item='vig' index=\"index\" separator=\",\">" +
+            "   (#{vig.identificationCode}, #{vig.name}, #{vig.type}, now())" +
+            " </foreach>" +
+            "</script>"})
+    void insertList(Set<VideoInfoGenres> videoInfoGenresList);
+
+    /**
+     * 新增
+     *
+     * @param videoInfoGenres
+     */
+    @Insert("INSERT INTO video_info_genres(identification_code, name , type, create_time) " +
+            "VALUES (#{identificationCode}, #{name}, #{type}, now())")
+    int insert(VideoInfoGenres videoInfoGenres);
+}

+ 62 - 0
src/main/java/top/lvzhiqiang/mapper/VideoInfoMapper.java

@@ -0,0 +1,62 @@
+package top.lvzhiqiang.mapper;
+
+import org.apache.ibatis.annotations.Delete;
+import org.apache.ibatis.annotations.Insert;
+import org.apache.ibatis.annotations.Options;
+import org.apache.ibatis.annotations.Select;
+import top.lvzhiqiang.entity.VideoInfo;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 电影信息Mapper
+ *
+ * @author lvzhiqiang
+ * 2022/4/4 15:28
+ */
+public interface VideoInfoMapper {
+
+    /**
+     * 删除所有
+     */
+    @Delete("DELETE FROM video_info where 1=1")
+    void deleteAll();
+
+    /**
+     * 批量新增
+     *
+     * @param videoInfoList
+     */
+    @Insert({"<script>" +
+            "INSERT INTO video_info(name, identification_code, issue_date, length, director, maker, issuer, img_url, video_url, type, main_who, create_time, modify_time) " +
+            "VALUES " +
+            "<foreach collection='list' item='vi' index=\"index\" separator=\",\">" +
+            "   (#{vi.name}, #{vi.identificationCode}, #{vi.issueDate}, #{vi.length}, #{vi.director}, #{vi.maker}, #{vi.issuer}, #{vi.imgUrl}, #{vi.videoUrl}, #{vi.type}, #{vi.mainWho}, #{vi.createTime}, now())" +
+            " </foreach>" +
+            "</script>"})
+    int insertList(List<VideoInfo> videoInfoList);
+
+    /**
+     * 新增
+     *
+     * @param videoInfo
+     */
+    @Insert("INSERT INTO video_info(name, identification_code, issue_date, length, director, maker, issuer, img_url, video_url, type, main_who, create_time, modify_time) " +
+            "VALUES (#{name}, #{identificationCode}, #{issueDate}, #{length}, #{director}, #{maker}, #{issuer}, #{imgUrl}, #{videoUrl}, #{type}, #{mainWho} ,#{createTime}, now())")
+    @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
+    int insert(VideoInfo videoInfo);
+
+    /**
+     * 查询所有
+     */
+    @Select("select vi.*, IFNULL(vio.score, 0) AS score from video_info vi " +
+            "left join video_info_other vio on vi.identification_code = vio.identification_code and vio.delete_flag = 1 " +
+            "where vi.delete_flag = 1 ORDER BY vi.issue_date desc")
+    List<VideoInfo> findAll();
+
+    /**
+     * 根据条件查询
+     */
+    List<VideoInfo> getVideoInfoList(Map<String, Object> params);
+}

+ 11 - 0
src/main/java/top/lvzhiqiang/service/BaseService.java

@@ -0,0 +1,11 @@
+package top.lvzhiqiang.service;
+
+/**
+ * 基础服务接口,所有Service接口都要继承
+ *
+ * @author lvzhiqiang
+ * 2021/10/25 11:02
+ */
+public interface BaseService<T> {
+
+}

+ 29 - 0
src/main/java/top/lvzhiqiang/service/VideoCastService.java

@@ -0,0 +1,29 @@
+package top.lvzhiqiang.service;
+
+import com.github.pagehelper.PageInfo;
+import top.lvzhiqiang.entity.VideoCast;
+
+import java.util.List;
+
+/**
+ * 电影演员Service
+ *
+ * @author lvzhiqiang
+ * 2022/4/4 15:28
+ */
+public interface VideoCastService {
+
+    /**
+     * 查询所有
+     *
+     * @return
+     */
+    List<VideoCast> findAll();
+
+    /**
+     * 分页查询所有
+     *
+     * @return
+     */
+    PageInfo<VideoCast> findAll(int pageNo, int pageSize);
+}

+ 29 - 0
src/main/java/top/lvzhiqiang/service/VideoGenresService.java

@@ -0,0 +1,29 @@
+package top.lvzhiqiang.service;
+
+import com.github.pagehelper.PageInfo;
+import top.lvzhiqiang.entity.VideoGenres;
+
+import java.util.List;
+
+/**
+ * 电影类别Service
+ *
+ * @author lvzhiqiang
+ * 2022/4/8 15:20
+ */
+public interface VideoGenresService {
+
+    /**
+     * 查询所有
+     *
+     * @return
+     */
+    List<VideoGenres> findAll();
+
+    /**
+     * 分页查询所有
+     *
+     * @return
+     */
+    PageInfo<VideoGenres> findAll(int pageNo, int pageSize);
+}

+ 43 - 0
src/main/java/top/lvzhiqiang/service/VideoInfoService.java

@@ -0,0 +1,43 @@
+package top.lvzhiqiang.service;
+
+import com.github.pagehelper.PageInfo;
+import top.lvzhiqiang.entity.VideoInfo;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 电影信息Service
+ *
+ * @author lvzhiqiang
+ * 2022/4/4 15:28
+ */
+public interface VideoInfoService {
+
+    /**
+     * 查询所有
+     *
+     * @return
+     */
+    List<VideoInfo> findAll();
+
+    /**
+     * 分页查询所有
+     *
+     * @return
+     */
+    PageInfo<VideoInfo> findAll(int pageNo, int pageSize);
+
+    /**
+     * 初始化数据
+     */
+    void initData();
+
+    /**
+     * 条件查询
+     *
+     * @return
+     */
+    PageInfo<VideoInfo> getVideoInfoPage(Map<String, Object> params);
+}

+ 115 - 0
src/main/java/top/lvzhiqiang/service/impl/BaseServiceImpl.java

@@ -0,0 +1,115 @@
+package top.lvzhiqiang.service.impl;
+
+import com.github.pagehelper.PageHelper;
+import org.springframework.util.ObjectUtils;
+import top.lvzhiqiang.service.BaseService;
+import top.lvzhiqiang.util.StringUtils;
+
+import java.util.Arrays;
+import java.util.Map;
+
+/**
+ * 基础服务类,所有Service都要继承
+ *
+ * @author lvzhiqiang
+ * 2021/10/25 11:02
+ */
+public abstract class BaseServiceImpl<T> implements BaseService<T> {
+
+    /**
+     * 当前页码
+     */
+    String PAGE_NUM = "pageNo";
+    /**
+     * 每页显示记录数
+     */
+    String PAGE_SIZE = "pageSize";
+    /**
+     * 排序字段
+     */
+    String ORDER_FIELD = "orderField";
+    /**
+     * 排序顺序
+     */
+    String ORDER = "order";
+
+    /**
+     * 转换成Like
+     *
+     * @param params
+     * @param likes
+     * @return
+     */
+    protected Map<String, Object> paramsToLike(Map<String, Object> params, String... likes) {
+        Arrays.stream(likes).forEach(like -> {
+            String val = (String) params.get(like);
+            if (StringUtils.isNotEmpty(val)) {
+                params.put(like, "%" + top.lvzhiqiang.util.StringUtils.escapeSqlParam(val) + "%");
+            } else {
+                params.put(like, null);
+            }
+        });
+        return params;
+    }
+
+    /**
+     * 转换成In
+     *
+     * @param params
+     * @param ins
+     * @return
+     */
+    protected Map<String, Object> paramsToIn(Map<String, Object> params, String... ins) {
+        Arrays.stream(ins).forEach(in -> {
+            String val = (String) params.get(in);
+            if (StringUtils.isNotEmpty(val)) {
+                params.put(in, val.split(","));
+            } else {
+                params.put(in, null);
+            }
+        });
+        return params;
+    }
+
+    /**
+     * 转换分页大小
+     *
+     * @param params
+     * @return
+     */
+    protected void paramsToPagination(Map<String, Object> params) {
+        //分页参数
+        int pageNum = 1;
+        int pageSize = 10;
+
+        if (params.containsKey(PAGE_NUM) && params.get(PAGE_NUM) != null) {
+            pageNum = Integer.parseInt(String.valueOf(params.get(PAGE_NUM)));
+        }
+        if (params.containsKey(PAGE_SIZE) && params.get(PAGE_SIZE) != null) {
+            pageSize = Integer.parseInt(String.valueOf(params.get(PAGE_SIZE)));
+        }
+        PageHelper.startPage(pageNum, pageSize, true);
+    }
+
+    /**
+     * 排序转换
+     *
+     * @param params
+     * @return
+     */
+    protected void paramsToSort(Map<String, Object> params) {
+        if (!params.containsKey(ORDER_FIELD) || !params.containsKey(ORDER)
+                || ObjectUtils.isEmpty(params.get(ORDER_FIELD)) || ObjectUtils.isEmpty(params.get(ORDER))) {
+            return;
+        }
+
+        //if ("creditRating".equals(params.get(ORDER_FIELD))) {
+        //    params.put(ORDER_FIELD, "creditRating || 'Z'");
+        //    params.put(ORDER, "desc".equalsIgnoreCase(params.get(ORDER).toString()) ? "asc" : "desc");
+        //}
+
+        StringBuilder sb = new StringBuilder();
+        sb.append(params.get(ORDER_FIELD)).append(" ").append(params.get(ORDER));
+        PageHelper.orderBy(sb.toString());
+    }
+}

+ 47 - 0
src/main/java/top/lvzhiqiang/service/impl/VideoCastServiceImpl.java

@@ -0,0 +1,47 @@
+package top.lvzhiqiang.service.impl;
+
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import org.springframework.stereotype.Service;
+import top.lvzhiqiang.entity.VideoCast;
+import top.lvzhiqiang.mapper.VideoCastMapper;
+import top.lvzhiqiang.service.VideoCastService;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 电影演员 ServiceImpl
+ *
+ * @author lvzhiqiang
+ * 2022/4/4 15:28
+ */
+@Service
+public class VideoCastServiceImpl implements VideoCastService {
+
+    @Resource
+    private VideoCastMapper videoCastMapper;
+
+    /**
+     * 查询所有
+     *
+     * @return
+     */
+    @Override
+    public List<VideoCast> findAll() {
+        return videoCastMapper.findAll();
+    }
+
+    /**
+     * 分页查询所有
+     *
+     * @return
+     */
+    @Override
+    public PageInfo<VideoCast> findAll(int pageNo, int pageSize) {
+        PageHelper.startPage(pageNo, pageSize);
+        List<VideoCast> videoCastList = videoCastMapper.findAll();
+        PageInfo<VideoCast> videoCastPageInfo = new PageInfo<VideoCast>(videoCastList);
+        return videoCastPageInfo;
+    }
+}

+ 47 - 0
src/main/java/top/lvzhiqiang/service/impl/VideoGenresServiceImpl.java

@@ -0,0 +1,47 @@
+package top.lvzhiqiang.service.impl;
+
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import org.springframework.stereotype.Service;
+import top.lvzhiqiang.entity.VideoGenres;
+import top.lvzhiqiang.mapper.VideoGenresMapper;
+import top.lvzhiqiang.service.VideoGenresService;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 电影类别ServiceImpl
+ *
+ * @author lvzhiqiang
+ * 2022/4/8 15:20
+ */
+@Service
+public class VideoGenresServiceImpl implements VideoGenresService {
+
+    @Resource
+    private VideoGenresMapper videoGenresMapper;
+
+    /**
+     * 查询所有
+     *
+     * @return
+     */
+    @Override
+    public List<VideoGenres> findAll() {
+        return videoGenresMapper.findAll();
+    }
+
+    /**
+     * 分页查询所有
+     *
+     * @return
+     */
+    @Override
+    public PageInfo<VideoGenres> findAll(int pageNo, int pageSize) {
+        PageHelper.startPage(pageNo, pageSize);
+        List<VideoGenres> videoGenresList = videoGenresMapper.findAll();
+        PageInfo<VideoGenres> videoGenresPageInfo = new PageInfo<>(videoGenresList);
+        return videoGenresPageInfo;
+    }
+}

+ 257 - 0
src/main/java/top/lvzhiqiang/service/impl/VideoInfoServiceImpl.java

@@ -0,0 +1,257 @@
+package top.lvzhiqiang.service.impl;
+
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+import top.lvzhiqiang.config.WebAppConfig;
+import top.lvzhiqiang.dto.JavAllInfo;
+import top.lvzhiqiang.entity.*;
+import top.lvzhiqiang.mapper.*;
+import top.lvzhiqiang.service.VideoInfoService;
+import top.lvzhiqiang.util.DateUtils;
+
+import javax.annotation.Resource;
+import java.io.File;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.ZoneOffset;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 电影信息ServiceImpl
+ *
+ * @author lvzhiqiang
+ * 2022/4/4 15:28
+ */
+@Service
+public class VideoInfoServiceImpl extends BaseServiceImpl<Object> implements VideoInfoService {
+
+    @Resource
+    private VideoInfoMapper videoInfoMapper;
+
+    @Resource
+    private VideoGenresMapper videoGenresMapper;
+
+    @Resource
+    private VideoCastMapper videoCastMapper;
+
+    @Resource
+    private VideoInfoCastMapper videoInfoCastMapper;
+    @Resource
+    private VideoInfoGenresMapper videoInfoGenresMapper;
+
+    /**
+     * 查询所有
+     *
+     * @return
+     */
+    @Override
+    public List<VideoInfo> findAll() {
+        return videoInfoMapper.findAll();
+    }
+
+    /**
+     * 分页查询所有
+     *
+     * @return
+     */
+    @Override
+    public PageInfo<VideoInfo> findAll(int pageNo, int pageSize) {
+        PageHelper.startPage(pageNo, pageSize);
+        List<VideoInfo> videoInfoList = videoInfoMapper.findAll();
+        PageInfo<VideoInfo> videoInfoPageInfo = new PageInfo<>(videoInfoList);
+        return videoInfoPageInfo;
+    }
+
+    @Override
+    public PageInfo<VideoInfo> getVideoInfoPage(Map<String, Object> params) {
+        // 转换成like
+        paramsToLike(params, "keyword");
+
+        // 分页
+        paramsToPagination(params);
+
+        // 排序
+        paramsToSort(params);
+
+        List<VideoInfo> videoInfoList = videoInfoMapper.getVideoInfoList(params);
+        PageInfo<VideoInfo> videoInfoPageInfo = new PageInfo<>(videoInfoList);
+        return videoInfoPageInfo;
+    }
+
+    /**
+     * 初始化数据
+     */
+    @Override
+    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
+    @Async
+    public void initData() {
+        long startTime = System.currentTimeMillis();
+
+        DicCode dicCode = WebAppConfig.dicCodeList.stream().filter(x -> 1 == x.getType() && "pic_path".equals(x.getCodeKey())).findFirst().get();
+        if (dicCode == null) {
+            return;
+        }
+        String picPath = dicCode.getCodeValue();
+
+        JavAllInfo javAllInfo = new JavAllInfo();
+        getAllFilePaths(picPath, javAllInfo);
+
+        saveInfo(javAllInfo);
+
+        long endTime = System.currentTimeMillis();
+        System.err.println((endTime - startTime) / 1000);
+    }
+
+    // 递归获取某目录下的所有子目录以及子文件
+    private void getAllFilePaths(String filePath, JavAllInfo javAllInfo) {
+        File[] files = new File(filePath).listFiles();
+        if (files == null) {
+            return;
+        }
+
+        int type = 0;
+        if (filePath.contains("骑兵")) {
+            type = 1;
+        } else if (filePath.contains("步兵")) {
+            type = 2;
+        }
+        for (File file : files) {
+            if (file.isDirectory()) {
+                // 文件夹
+                getAllFilePaths(file.getAbsolutePath(), javAllInfo);
+            } else {
+                String fileName = file.getName();
+                if (fileName.endsWith(".jpg") || (fileName.endsWith(".lnk") && fileName.contains(".jpg"))) {
+                    String parentName = file.getParentFile().getName();
+                    // 识别码
+                    String name = fileName.substring(10).replace(".jpg", "").trim();
+                    String[] nameArr = name.split("\\s+");
+                    try {
+                        boolean isMain = false;
+                        if (fileName.endsWith(".jpg")) {
+                            isMain = true;
+                            // 获取正片信息
+                            VideoInfo videoInfo = new VideoInfo();
+                            // 发行日期
+                            String issueDate = fileName.substring(0, 10);
+                            videoInfo.setIssueDate(LocalDate.parse(issueDate, DateUtils.dateFormatter));
+                            videoInfo.setIdentificationCode(nameArr[0]);
+                            // 名称
+                            if (nameArr.length > 1) {
+                                videoInfo.setName(name.substring(nameArr[0].length()).trim());
+                            } else {
+                                videoInfo.setName(nameArr[0]);
+                            }
+
+                            // 类型
+                            videoInfo.setType(type);
+                            // 图片URL
+                            videoInfo.setImgUrl(parentName.concat("/").concat(fileName));
+                            // 创建时间 TODO
+                            // 修改时间
+                            videoInfo.setCreateTime(Instant.ofEpochMilli(file.lastModified()).atZone(ZoneOffset.ofHours(8)).toLocalDateTime());
+                            // 主体是谁
+                            videoInfo.setMainWho(parentName);
+
+                            javAllInfo.getVideoInfoList().add(videoInfo);
+                        }
+
+                        if (parentName.contains("类别")) {
+                            // 获取类别
+                            String videoGenres = parentName.replace("(类别)", "");
+                            javAllInfo.getVideoGenresSet().add(videoGenres);
+
+                            VideoInfoGenres videoInfoGenres = new VideoInfoGenres();
+                            videoInfoGenres.setIdentificationCode(nameArr[0]);
+                            videoInfoGenres.setName(videoGenres);
+                            videoInfoGenres.setType(isMain ? 1 : 2);
+                            javAllInfo.getVideoInfoGenresSet().add(videoInfoGenres);
+                        } else if (parentName.contains("优)")) {
+                            // 获取演员
+                            String videoCast = "";
+                            if (parentName.contains("(男")) {
+                                videoCast = parentName.replace("(男优)", "");
+                                javAllInfo.getVideoCastMap().put(videoCast, "1");
+                            } else if (parentName.contains("(女")) {
+                                videoCast = parentName.replace("(女优)", "");
+                                javAllInfo.getVideoCastMap().put(videoCast, "2");
+                            }
+
+                            VideoInfoCast videoInfoCast = new VideoInfoCast();
+                            videoInfoCast.setIdentificationCode(nameArr[0]);
+                            videoInfoCast.setName(videoCast);
+                            videoInfoCast.setType(isMain ? 1 : 2);
+                            javAllInfo.getVideoInfoCastSet().add(videoInfoCast);
+                        }
+                    } catch (Exception e) {
+                        System.err.println("error:" + file.getAbsolutePath());
+                        System.err.println("error reason:" + e.getMessage());
+                    }
+                }
+            }
+        }
+    }
+
+    // 保存所有文件
+    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
+    public void saveInfo(JavAllInfo javAllInfo) {
+        // 删除所有
+        videoGenresMapper.deleteAll();
+        videoInfoMapper.deleteAll();
+        videoCastMapper.deleteAll();
+        videoGenresMapper.deleteAll();
+        videoInfoCastMapper.deleteAll();
+
+        // 保存分类
+        Set<String> videoGenresSet = javAllInfo.getVideoGenresSet();
+        //List<VideoGenres> videoGenresList = new ArrayList<>();
+        for (String s : videoGenresSet) {
+            VideoGenres videoGenres = new VideoGenres();
+            videoGenres.setName(s);
+            videoGenresMapper.insert(videoGenres);
+            System.out.println(videoGenres);
+            //videoGenresList.add(videoGenres);
+        }
+        //Map<String, VideoGenres> stringVideoGenresMap = videoGenresList.stream().collect(Collectors.toMap(VideoGenres::getName, Function.identity(), (k1, k2) -> k2));
+
+        // 保存演员
+        Map<String, String> videoCastMap = javAllInfo.getVideoCastMap();
+        //List<VideoCast> videoCastList = new ArrayList<>();
+        for (Map.Entry<String, String> entry : videoCastMap.entrySet()) {
+            VideoCast videoCast = new VideoCast();
+            videoCast.setName(entry.getKey());
+            videoCast.setType(Integer.parseInt(entry.getValue()));
+            videoCastMapper.insert(videoCast);
+            System.out.println(videoCast);
+            //videoCastList.add(videoCast);
+        }
+        // Map<String, VideoCast> stringVideoCastMap = videoCastList.stream().collect(Collectors.toMap(VideoCast::getName, Function.identity(), (k1, k2) -> k2));
+
+        // 保存影片信息
+        List<VideoInfo> videoInfoList = javAllInfo.getVideoInfoList();
+        int videoInfoCount = videoInfoMapper.insertList(videoInfoList);
+        System.out.println("videoInfoCount:" + videoInfoCount);
+        //for (VideoInfo videoInfo : videoInfoList) {
+        //    try {
+        //        videoInfoMapper.insert(videoInfo);
+        //        System.out.println("success:" + videoInfo);
+        //    } catch (Exception e) {
+        //        e.printStackTrace();
+        //        System.out.println("error:" + videoInfo);
+        //    }
+        //}
+
+        // 保存影片类别关联信息
+        Set<VideoInfoGenres> videoInfoGenresSet = javAllInfo.getVideoInfoGenresSet();
+        videoInfoGenresMapper.insertList(videoInfoGenresSet);
+        // 保存影片类别关联信息
+        Set<VideoInfoCast> videoInfoCastSet = javAllInfo.getVideoInfoCastSet();
+        videoInfoCastMapper.insertList(videoInfoCastSet);
+    }
+}

+ 338 - 0
src/main/java/top/lvzhiqiang/util/DateUtils.java

@@ -0,0 +1,338 @@
+/**
+ * All rights Reserved, Designed By 上海风声企业信用征信有限公司
+ * @Title: DateUtils.java
+ * @Package com.riskraider.fxld.utils
+ * @Description: TODO(用一句话描述该文件做什么)
+ * @author: 施勇
+ * @date: 2018年12月13日 上午8:50:27
+ * @version V1.0
+ * @Copyright: 2018 上海风声企业信用征信有限公司 Inc. All rights reserved.
+ * 注意:本内容仅限于上海风声企业信用征信有限公司内部传阅,禁止外泄以及用于其他的商业目
+ */
+package top.lvzhiqiang.util;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Calendar;
+import java.util.Date;
+
+/**
+ * @ClassName: DateUtils
+ * @Description: 日期工具类
+ * @author: 施勇
+ * @date: 2018年12月13日 上午8:50:27
+ * @Copyright: 2018 上海风声企业信用征信有限公司 Inc. All rights reserved.
+ * 注意:本内容仅限于上海风声企业信用征信有限公司内部传阅,禁止外泄以及用于其他的商业目
+ */
+public class DateUtils {
+
+	/**
+	 * (精确到天的)日期样式
+	 */
+	public static final String PATTERN_TO_DAYS = "yyyy-MM-dd";
+
+	/**
+	 * (精确到秒的)日期样式
+	 */
+	public static final String PATTERN_TO_SECONDS = "yyyy-MM-dd HH:mm:ss";
+
+	public static final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(PATTERN_TO_DAYS);
+
+	public static final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(PATTERN_TO_SECONDS);
+
+	/**
+	* @Title: getToday 
+	* @Description: 获取今天的日期
+	* @param @return 设定文件 
+	* @return Date 返回类型 
+	* @throws 
+	* @author shiyong
+	* @date 2017年8月24日 下午2:11:03
+	*/
+	public static Date getToday() {
+		Calendar cal = Calendar.getInstance();
+		
+		return cal.getTime();
+	}
+	
+	/**
+	 * @Title: getYesterday
+	 * @Description: 获取昨天的日期
+	 * @author: 施勇
+	 * @date: 2019年1月17日 上午7:18:38
+	 * @param: @return
+	 * @return: Date
+	 * @throws
+	 */
+	public static Date getYesterday() {
+		Calendar cal = Calendar.getInstance();
+		cal.add(Calendar.DATE, -1);
+		
+		return cal.getTime();
+	}
+	
+	/**
+	 * @Title: getTomorrow
+	 * @Description: 获取明天的日期
+	 * @author: 施勇
+	 * @date: 2019年1月17日 上午7:19:28
+	 * @param: @return
+	 * @return: Date
+	 * @throws
+	 */
+	public static Date getTomorrow() {
+		Calendar cal = Calendar.getInstance();
+		cal.add(Calendar.DATE, 1);
+		
+		return cal.getTime();
+	}
+	
+	/**
+	 * @Title: getTodayStr
+	 * @Description: 获取今天的日期字符串
+	 * @author: 施勇
+	 * @date: 2019年1月17日 上午7:21:51
+	 * @param: @param pattern
+	 * @param: @return
+	 * @return: String
+	 * @throws
+	 */
+	public static String getTodayStr(String pattern){
+		SimpleDateFormat format = new SimpleDateFormat(pattern);		
+		
+		return format.format(getToday());
+	}
+	
+	/**
+	 * @Title: getTodayStr
+	 * @Description: 获取今天的日期字符串
+	 * @author: 施勇
+	 * @date: 2019年1月17日 上午7:33:22
+	 * @param: @return
+	 * @return: String
+	 * @throws
+	 */
+	public static String getTodayStr(){
+		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
+		
+		return format.format(getToday());
+	}
+	
+	/**
+	 * @Title: getYesterdayStr
+	 * @Description: 获取昨天的日期字符串
+	 * @author: 施勇
+	 * @date: 2019年1月17日 上午7:21:11
+	 * @param: @return
+	 * @return: String
+	 * @throws
+	 */
+	public static String getYesterdayStr(){
+		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
+		
+		return format.format(getYesterday());
+	}
+	
+	/**
+	 * @Title: getTomorrowStr
+	 * @Description: 获取明天的日期字符串
+	 * @author: 施勇
+	 * @date: 2019年1月17日 上午7:25:00
+	 * @param: @return
+	 * @return: String
+	 * @throws
+	 */
+	public static String getTomorrowStr(){
+		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
+		
+		return format.format(getTomorrow());
+	}
+	
+	/**
+	 * @Title: formatDate
+	 * @Description: 格式化日期
+	 * @author: 施勇
+	 * @date: 2018年1月4日 上午9:30:29
+	 * @param: @param format
+	 * @param: @param date
+	 * @param: @return
+	 * @return: String
+	 * @throws
+	 */
+	public static String formatDate(Date date) {
+		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+		
+		return dateFormat.format(date);
+	}
+
+	public static String formatDate(LocalDate date) {
+		return dateFormatter.format(date);
+	}
+	
+	/**
+	 * @Title: formatDateTime
+	 * @Description: 格式化整个日期时间
+	 * @author: 施勇
+	 * @date: 2018年6月25日 下午1:30:24
+	 * @param: @param date
+	 * @param: @return
+	 * @return: String
+	 * @throws
+	 */
+	public static String formatDateTime(Date date) {
+		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		
+		return dateFormat.format(date);
+	}
+
+	public static String formatDateTime(LocalDateTime dateTime) {
+		return dateTimeFormatter.format(dateTime);
+	}
+	
+	/**
+	 * @Title: parseDate
+	 * @Description: 格式化日期字符串
+	 * @author: 施勇
+	 * @date: 2019年1月17日 上午7:40:06
+	 * @param: @param dateString
+	 * @param: @return
+	 * @param: @throws ParseException
+	 * @return: Date
+	 * @throws
+	 */
+	public static Date parseDate(String dateString) throws ParseException{
+		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+		
+		return dateFormat.parse(dateString);
+	}
+	
+	/**
+	 * @Title: parseDateTime
+	 * @Description: 格式化时间字符串
+	 * @author: 施勇
+	 * @date: 2019年1月17日 上午7:40:24
+	 * @param: @param dateString
+	 * @param: @return
+	 * @param: @throws ParseException
+	 * @return: Date
+	 * @throws
+	 */
+	public static Date parseDateTime(String dateString) throws ParseException{
+		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		
+		return dateFormat.parse(dateString);
+	}
+	
+	/**
+	 * @Title: getFewDateStrsByDate
+	 * @Description: 获取近几天的日期字符串
+	 * @author: 施勇
+	 * @date: 2019年1月17日 上午8:26:40
+	 * @param: @param date
+	 * @param: @param num
+	 * @param: @return
+	 * @return: String
+	 * @throws
+	 */
+	public static String getFewDateStrsByDate(Date date, int num){
+		StringBuffer str = new StringBuffer();
+		
+		Calendar cal = Calendar.getInstance();
+		
+		cal.setTime(date);
+		
+		cal.add(Calendar.DATE, -(num-1));
+		str.append(formatDate(cal.getTime()) + ",");
+		
+		for(int i=0;i<num-1;i++){
+			cal.add(Calendar.DATE, 1);
+			
+			str.append(formatDate(cal.getTime()) + ",");
+		}
+		
+		//去掉最后的逗号
+		
+		return str.substring(0, str.length()-1);
+	}
+	
+	/**
+	 * @Title: getFewDateStrsByWeek
+	 * @Description: 获取近几周同一天的日期字符串
+	 * @author: 施勇
+	 * @date: 2019年1月17日 上午8:33:23
+	 * @param: @param date
+	 * @param: @param num
+	 * @param: @return
+	 * @return: String
+	 * @throws
+	 */
+	public static String getFewDateStrsByWeek(Date date, int num){
+		StringBuffer str = new StringBuffer();
+		
+		Calendar cal = Calendar.getInstance();
+		
+		cal.setTime(date);
+		
+		cal.add(Calendar.WEEK_OF_YEAR, -(num-1));
+		str.append(formatDate(cal.getTime()) + ",");
+		
+		for(int i=0;i<num-1;i++){
+			cal.add(Calendar.WEEK_OF_YEAR, 1);
+			
+			str.append(formatDate(cal.getTime()) + ",");
+		}
+		
+		//去掉最后的逗号
+		
+		return str.substring(0, str.length()-1);
+	}
+	
+	/**
+	 * @Title: getFewDateStrsByMonth
+	 * @Description: 获取近几月同一天的日期字符串
+	 * @author: 施勇
+	 * @date: 2019年1月17日 上午8:31:31
+	 * @param: @param date
+	 * @param: @param num
+	 * @param: @return
+	 * @return: String
+	 * @throws
+	 */
+	public static String getFewDateStrsByMonth(Date date, int num){
+		StringBuffer str = new StringBuffer();
+		
+		Calendar cal = Calendar.getInstance();
+		
+		cal.setTime(date);
+		
+		cal.add(Calendar.MONTH, -(num-1));
+		str.append(formatDate(cal.getTime()) + ",");
+		
+		for(int i=0;i<num-1;i++){
+			cal.add(Calendar.MONTH, 1);
+			
+			str.append(formatDate(cal.getTime()) + ",");
+		}
+		
+		//去掉最后的逗号
+		
+		return str.substring(0, str.length()-1);
+	}
+	
+	/**
+     * 获取时间戳
+     * @author shiyong
+     * 2019-10-09 13:36
+     * @return long
+     */
+    public static long getTimeStamp() {
+        return System.currentTimeMillis();
+    }
+	
+	public static void main(String[] args) {
+		System.out.println(getFewDateStrsByMonth(getToday(), 7));
+	}
+}

+ 57 - 0
src/main/java/top/lvzhiqiang/util/StringUtils.java

@@ -0,0 +1,57 @@
+package top.lvzhiqiang.util;
+
+/**
+ * 字符串处理工具类
+ *
+ * @author shiyong
+ * 2021/10/25 10:48
+ */
+public class StringUtils extends org.apache.commons.lang3.StringUtils {
+    // 百分号,SQL参数中的任意长度通配符
+    private static final String PERCENT = "%";
+    // 下划线,SQL参数中的单个字符通配符
+    private static final String UNDERLINE = "_";
+
+    /**
+     * 判断字符串是否不为空
+     *
+     * @param str 字符串
+     * @return boolean
+     * @author shiyong
+     * 2019/10/16 16:15
+     */
+    public static boolean isNotEmpty(String str){
+        return null != str && !"".equals(str.trim());
+    }
+
+    /**
+     * 判断字符串是否为空
+     *
+     * @param str 字符串
+     * @return boolean
+     * @author shiyong
+     * 2019/10/16 16:16
+     */
+    public static boolean isEmpty(String str) {
+        return !isNotEmpty(str);
+    }
+
+    /**
+     * 转义SQL参数中的通配符
+     *
+     * @param raw 原字符串
+     * @return escaped sql parameter
+     * @author ziyan.li
+     * @since 15:00 2021/10/27
+     */
+    public static String escapeSqlParam(String raw) {
+        if (raw == null) {
+            return null;
+        }
+        // 转义通配符
+        String processed = raw.replace(PERCENT, "\\" + PERCENT)
+                .replace(UNDERLINE, "\\" + UNDERLINE);
+        // 转义后去除前后空格
+        return strip(processed);
+    }
+}

+ 79 - 0
src/main/resources/application.yml

@@ -0,0 +1,79 @@
+# Web容器配置
+server:
+  tomcat:
+    accept-count: 1000
+    max-connections: 10000
+    max-threads: 1000
+    min-spare-threads: 50
+    uri-encoding: UTF-8
+    max-http-post-size: 100MB
+    accesslog:
+      enabled: true
+  port: 8024
+  connection-timeout: 60000
+  servlet:
+    context-path: /jav
+  compression:
+    enabled: true
+  http2:
+    enabled: true
+spring:
+  application:
+    name: jav
+  datasource:
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    url: jdbc:mysql://144.34.207.84:3306/jav?useUnicode=true&allowMultiQueries=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false&useSSL=false
+    username: root
+    password: fa7777a9337be09f
+    type: com.zaxxer.hikari.HikariDataSource
+    # Hikari 连接池配置
+    hikari:
+      # 最小空闲连接数量
+      minimum-idle: 10
+      # 空闲连接存活最大时间,默认600000(10分钟)
+      idle-timeout: 60000
+      # 连接池最大连接数,默认是10
+      maximum-pool-size: 100
+      # 此属性控制从池返回的连接的默认自动提交行为,默认值:true
+      auto-commit: true
+      # 连接池名称
+      pool-name: HikariCP
+      # 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认1800000即30分钟
+      max-lifetime: 60000
+      # 数据库连接超时时间,默认30秒,即30000
+      connection-timeout: 60000
+      # 生效超时
+      validation-timeout: 3000
+      connection-test-query: SELECT 1
+
+  freemarker:
+    allow-request-override: false
+    cache: true
+    check-template-location: true
+    charset: UTF-8
+    content-type: text/html
+    expose-request-attributes: false
+    expose-session-attributes: false
+    expose-spring-macro-helpers: false
+    suffix: .ftl
+    template-loader-path: classpath:/templates/
+
+# mybatis
+mybatis:
+  # 映射文件的路径 ,支持 Ant 风格的通配符, 多个配置可以使用英文逗号隔开
+  mapper-locations: classpath:mapper/**/*.xml
+  # 类型别名包画配置,只能指定具体的包,多个配置可以使用英文逗号隔开
+  type-aliases-package: top.lvzhiqiang.entity
+  configuration:
+    # 开启驼峰命名转换,如:Table(create_time) -> Entity(createTime)。
+    # 不需要我们关心怎么进行字段匹配,mybatis会自动识别`大写字母与下划线`
+    map-underscore-to-camel-case: true
+    jdbc-type-for-null: 'NULL'
+    # 日志打印
+    log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
+# pagehelper
+pagehelper:
+  helperDialect: mysql
+  reasonable: true
+  supportMethodsArguments: true
+  params: count=countSql

+ 28 - 0
src/main/resources/log4j.properties

@@ -0,0 +1,28 @@
+log4j.rootLogger=info,error,CONSOLE,DEBUG
+log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
+log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
+log4j.appender.CONSOLE.layout.ConversionPattern=%d{yyyy-MM-dd-HH-mm} [%t] [%c] [%p] - %m%n
+log4j.logger.info=info
+log4j.appender.info=org.apache.log4j.DailyRollingFileAppender
+log4j.appender.info.layout=org.apache.log4j.PatternLayout
+log4j.appender.info.layout.ConversionPattern=%d{yyyy-MM-dd-HH-mm} [%t] [%c] [%p] - %m%n
+log4j.appender.info.datePattern='.'yyyy-MM-dd
+log4j.appender.info.Threshold = info
+log4j.appender.info.append=true
+log4j.appender.info.File=D:\\log4j\\springbootdemo\\info
+log4j.logger.error=error
+log4j.appender.error=org.apache.log4j.DailyRollingFileAppender
+log4j.appender.error.layout=org.apache.log4j.PatternLayout
+log4j.appender.error.layout.ConversionPattern=%d{yyyy-MM-dd-HH-mm} [%t] [%c] [%p] - %m%n
+log4j.appender.error.datePattern='.'yyyy-MM-dd
+log4j.appender.error.Threshold = error
+log4j.appender.error.append=true
+log4j.appender.error.File=D:\\log4j\\springbootdemo\\error
+log4j.logger.DEBUG=DEBUG
+log4j.appender.DEBUG=org.apache.log4j.DailyRollingFileAppender
+log4j.appender.DEBUG.layout=org.apache.log4j.PatternLayout
+log4j.appender.DEBUG.layout.ConversionPattern=%d{yyyy-MM-dd-HH-mm} [%t] [%c] [%p] - %m%n
+log4j.appender.DEBUG.datePattern='.'yyyy-MM-dd
+log4j.appender.DEBUG.Threshold = DEBUG
+log4j.appender.DEBUG.append=true
+log4j.appender.DEBUG.File=D:\\log4j\\springbootdemo\\debug

+ 23 - 0
src/main/resources/mapper/VideoInfoMapper.xml

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+
+<!-- 当Mapper接口和XML文件关联的时候,namespace的值就需要配置成接口的全限定名称 -->
+<mapper namespace="top.lvzhiqiang.mapper.VideoInfoMapper">
+
+    <select id="getVideoInfoList" resultType="top.lvzhiqiang.entity.VideoInfo">
+        select vi.*, IFNULL(vio.score, 0) AS score
+        from video_info vi
+        left join video_info_other vio on vi.identification_code = vio.identification_code and vio.delete_flag = 1
+        where vi.delete_flag = 1
+        <if test="keyword != null and keyword != ''">
+            and (vi.name like #{keyword} or vi.identification_code like #{keyword})
+        </if>
+        <if test="genres != null and genres != ''">
+            and exists(select 1 from video_info_genres vig where vig.name = #{genres} and vig.identification_code = vi.identification_code)
+        </if>
+        <if test="cast != null and cast != ''">
+            and exists(select 1 from video_info_cast vic where vic.name = #{cast} and vic.identification_code = vi.identification_code)
+        </if>
+    </select>
+</mapper>

BIN
src/main/resources/static/cover/favicon.ico


BIN
src/main/resources/static/cover/load.png


BIN
src/main/resources/static/cover/loading.gif


BIN
src/main/resources/static/cover/no.png


BIN
src/main/resources/static/cover/play.png


+ 94 - 0
src/main/resources/static/css/my.css

@@ -0,0 +1,94 @@
+body {
+    line-height: 100%;
+}
+
+@media (min-width: 1200px) {
+    .container {
+        max-width: 1920px;
+    }
+
+    .container {
+        padding-left: 120px;
+        padding-right: 120px;
+    }
+}
+
+.myui-panel-bg2, .myui-vodlist__bg, .myui-screen__item, .myui-vodlist__text.striped .striped-head, .myui-vodlist__text.to-color li:nth-of-type(odd), .myui-extra li a {
+    background-color: #ffffff;
+}
+
+.myui-panel {
+    margin-top: 2px;
+    margin-bottom: 10px;
+    border-radius: 5px;
+}
+
+.myui-panel-box {
+    padding: 1px;
+}
+
+.myui-screen__list {
+    padding: 10px 10px 0;
+}
+
+.myui-screen__list li {
+    margin-bottom: 10px;
+    margin-right: 10px;
+}
+
+.text-muted {
+    color: #99a2aa;
+}
+
+.btn {
+    border-radius: 5px;
+}
+
+.myui-vodlist__thumb {
+    border-radius: 5px;
+    padding-top: 60%;
+    background: url(cover/load.png) no-repeat;
+}
+
+[class*=col-], .myui-content__list li, .myui-vodlist__media.col li {
+    padding: 10px;
+}
+
+@media (max-width: 1500px) {
+    .myui-header__search {
+        width: 200px;
+        margin-left: 20px;
+        float: right;
+        margin-right: 32px;
+        margin-top: 0px;
+    }
+}
+.myui-header__search {
+    width: 200px;
+    margin-left: 20px;
+    float: right;
+    margin-right: 32px;
+    margin-top: 0px;
+}
+
+#cover {
+    position: absolute;
+    left: 0px;
+    top: 0px;
+    background: #FFFFFF;
+    width: 100%; /*宽度设置为100%,这样才能使隐藏背景层覆盖原页面*/
+    height: 100%;
+    filter: alpha(opacity=60); /*设置透明度为60%*/
+    opacity: 1; /*非IE浏览器下设置透明度为60%*/
+    display: none;
+    z-Index: 999;
+}
+
+#cover img {
+    position: absolute;
+    bottom: 50%;
+    right: 50%;
+    margin-left: 40px;
+    margin-top: 40px;
+}
+

+ 131 - 0
src/main/resources/static/css/mytheme-color3.css

@@ -0,0 +1,131 @@
+@charset "utf-8";
+/*!
+ * 版本:MYUI Copyright © 2019
+ * 作者:QQ726662013版权所有
+ * 官网:https://www.mytheme.cn
+ */
+
+/* style */
+.myui-panel,.myui-panel-box{ padding: 10px;}
+.myui-panel_hd{ padding: 10px;}
+.myui-panel-box.active{ margin: -10px;}
+
+/* all  */
+body{ background: #f8f8f8; color: #666;}
+
+/* text */
+a,h1, h2, h3, h4, h5, h6,h1 a, h2 a, h3 a, h4 a, h5 a, h6 a{ color: #333;}
+a:hover{ color: cornflowerblue;}
+a.disabled{ cursor: not-allowed; opacity: 0.6;}
+.text-333{ color: #333;}
+.text-muted{ color: #999;}
+.text-red{ color: red;}
+.text-link{ color: blue;}
+.text-fff{ color: #fff;}
+
+/* form */
+.form-control{ background-color:#F5F5F5; color: #999999; border: 1px solid #eee;}
+.form-control:focus{ border-color:#ff9900; -webkit-box-shadow:inset 0 1px 1px rgba(255,136,0,.075),0 0 8px rgba(255,136,0,.6);}
+
+/* btn */
+.btn-default{ background-color: #eee; color: #333; background: linear-gradient(to right,#eeeeee 0,#f6f6f6 100%);}
+.btn-warm{ background-color: #FB7299; background: linear-gradient(to right,#FB7299 0,#FB7299 100%);}
+.btn-primary{ background-color: #4fb1f7; background: linear-gradient(to right,#4fb1f7 0,#6bb8ee 100%);}
+.btn-danger{ background-color: #00C0FF; background: linear-gradient(to right,#00C0FF 0,#00C0FF 100%);}
+.btn-info{ background-color: #5bc0de; background: linear-gradient(to right,#5bc0de 0,#7cc1d6 100%); }
+.btn-gray{ background-color: #282828; color: #ddd; background: linear-gradient(to right,#282828 0,#3b3b3b 100%);}
+.btn-warm,.btn-primary,.btn-danger,.btn-info{  color: #fff;}
+.btn-warm:hover,.btn-primary:hover,.btn-danger:hover,.btn-info:hover,.btn-gray:hover{ color: #fff; box-shadow: 0 5px 8px rgba(0,0,0,.1);}
+.btn.disabled{ cursor: not-allowed; opacity: 0.6;}
+
+/* border */
+.border{ border-color: #eee;}
+.border-primary{ border-color: #4fb1f7;}
+.border-danger{ border-color: red;}
+.border-info{ border-color: #5bc0de;}
+
+/* line */
+.spot{ border-color: #FB7299;}
+.split-line{ background-color: #eee;}
+.top-line:before,.bottom-line:after,.top-line-dot:before,.bottom-line-dot:before{ border-color: #eee;}
+
+/* badge */
+.badge{ background-color: #eee; color: #333;}
+.badge-first{ background-color: #ff4a4a; color: #fff;}
+.badge-second{ background-color: #ff7701; color: #fff;}
+.badge-third{ background-color: #ffb400; color: #fff;}
+
+/* dropdown */
+.dropdown-box .item{ background-color: #fff; box-shadow: 0 2px 5px rgba(0,0,0,.1);}
+
+/* pic-tag */
+.pic-tag .tag{ background-color: rgba(0,0,0,0.6); color: #fff;}
+.pic-tag .tag.active,.pic-tag-h{ background-color: #ff9900; color: #fff;}
+.pic-text,.pic-title-bottom{ background-repeat: no-repeat; background-image: linear-gradient(transparent,rgba(0,0,0,.5)); color: #fff;}
+.pic-text.active{ background: rgba(0,0,0,0.6); color: #fff;}
+.pic-title-top{background: linear-gradient(to bottom, rgba(0,0,0,0.7) 0%,rgba(0,0,0,0) 100%); color: #fff;}
+
+/* link */
+.myui-link__pic li img{ display: block; padding: 2px 6px; border-radius: 4px; background-color: #fff;}
+
+/* nav */
+.nav-tabs > li.active a{ border-color: #ff9900; color: #ff9900;}
+.nav-tabs > li .dropdown-box .item li a{ color: #333;}
+.nav-tabs > li .dropdown-box .item li.active a{ color: #ff9900;}
+.nav-btn > li a{ background-color: #f5f5f5;}
+.nav-btn > li.active a{ background-color: #ff9900; color: #fff;}
+
+/* header */
+.myui-header__top{ background-color: #fff; box-shadow: 0 2px 5px rgba(0,0,0,.1);}
+.myui-header__menu > li > a{ color: #333;}
+.myui-header__menu > li.active > a{ color: #FB7299;}
+.myui-header__search .form-control{ background-color: #f5f5f5;}
+.myui-header__user > li > a,.myui-header__user > li > a .fa{ color: #333;}
+
+/* panel */
+.myui-panel-bg,.myui-panel-bg2{background-color: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.05);}
+
+/* vodlist */
+.myui-vodlist__bg{background-color: #f5f5f5;}
+.myui-vodlist__bg:hover{ box-shadow: 0 3px 5px rgba(0,0,0,.08);}
+
+/* text-list */
+.myui-vodlist__text.striped .striped-head,.myui-vodlist__text.to-color li:nth-of-type(odd){ background-color: #f5f5f5;}
+
+/* table */
+.myui-table>thead>tr>th,.myui-table>tbody>tr>td, .myui-table>tbody>tr>th, .myui-table>tfoot>tr>td, .myui-table>tfoot>tr>th, .myui-table>thead>tr>td, .myui-table>thead>tr>th { border-color: #ddd;}
+
+/* player */
+.myui-player__video{ background-color: #000;}
+.myui-player__operate > li > a{ color: #999;}
+
+/* popup */
+.popup{ background-color: #f8f8f8;}
+.popup-head{ background-color: #fff;}
+
+/* content */
+.myui-content__detail .score .rating li .fa,.myui-content__detail .score .branch{ color: #ff9900;}
+
+/* flickity */
+.flickity-page-dots .dot{ background-color: #FB7299;}
+
+/* carousel */
+.carousel-indicators-dots li{ background-color: #ff9900;}
+.carousel-indicators-text li.active .title{ color: red;}
+.carousel-indicators-thumb li.active{ border: 3px solid #ff9900;}
+
+/* extra */
+.myui-extra li a{ background-color: #fff; box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);}
+.myui-extra li a.backtop{ background-color: rgba(251,114,153,0.8); color: #fff; }
+
+/* autocomplete */
+.autocomplete-suggestions{ background-color: #fff; box-shadow: 0 2px 10px rgba(0,0,0,.05);}
+.autocomplete-suggestion, .autocomplete-suggestions li,.autocomplete-suggestion, .autocomplete-suggestions li a{ color: #333;}
+.autocomplete-suggestions li strong{ color: red;}
+
+/* tabbar */
+.myui-nav__tabbar{background-color: #f8f8f8; border-color: #eee;}
+.myui-nav__tabbar .item .title{ color: #999;}
+
+/* footer */
+.myui-foot{ background-color: #f8f8f8;}

+ 2926 - 0
src/main/resources/static/css/mytheme-font.css

@@ -0,0 +1,2926 @@
+/*!
+ *  Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
+ *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
+ */
+@font-face {
+    font-family: 'FontAwesome';
+    src: url('../font/fontawesome-webfont.eot?v=4.7.0');
+    src: url('../font/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'), url('../font/fontawesome-webfont.woff2?v=4.7.0') format('woff2'), url('../font/fontawesome-webfont.woff?v=4.7.0') format('woff'), url('../font/fontawesome-webfont.ttf?v=4.7.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');
+    font-weight: normal;
+    font-style: normal
+}
+
+.fa {
+    display: inline-block;
+    font: normal normal normal 14px/1 FontAwesome;
+    font-size: inherit;
+    text-rendering: auto;
+    -webkit-font-smoothing: antialiased;
+    -moz-osx-font-smoothing: grayscale
+}
+
+.fa-lg {
+    font-size: 1.33333333em;
+    line-height: .75em;
+    vertical-align: -15%
+}
+
+.fa-2x {
+    font-size: 2em
+}
+
+.fa-3x {
+    font-size: 3em
+}
+
+.fa-4x {
+    font-size: 4em
+}
+
+.fa-5x {
+    font-size: 5em
+}
+
+.fa-fw {
+    width: 1.28571429em;
+    text-align: center
+}
+
+.fa-ul {
+    padding-left: 0;
+    margin-left: 2.14285714em;
+    list-style-type: none
+}
+
+.fa-ul > li {
+    position: relative
+}
+
+.fa-li {
+    position: absolute;
+    left: -2.14285714em;
+    width: 2.14285714em;
+    top: .14285714em;
+    text-align: center
+}
+
+.fa-li.fa-lg {
+    left: -1.85714286em
+}
+
+.fa-border {
+    padding: .2em .25em .15em;
+    border: solid .08em #eee;
+    border-radius: .1em
+}
+
+.fa-pull-left {
+    float: left
+}
+
+.fa-pull-right {
+    float: right
+}
+
+.fa.fa-pull-left {
+    margin-right: .3em
+}
+
+.fa.fa-pull-right {
+    margin-left: .3em
+}
+
+.pull-right {
+    float: right
+}
+
+.pull-left {
+    float: left
+}
+
+.fa.pull-left {
+    margin-right: .3em
+}
+
+.fa.pull-right {
+    margin-left: .3em
+}
+
+.fa-spin {
+    -webkit-animation: fa-spin 2s infinite linear;
+    animation: fa-spin 2s infinite linear
+}
+
+.fa-pulse {
+    -webkit-animation: fa-spin 1s infinite steps(8);
+    animation: fa-spin 1s infinite steps(8)
+}
+
+@-webkit-keyframes fa-spin {
+    0% {
+        -webkit-transform: rotate(0deg);
+        transform: rotate(0deg)
+    }
+    100% {
+        -webkit-transform: rotate(359deg);
+        transform: rotate(359deg)
+    }
+}
+
+@keyframes fa-spin {
+    0% {
+        -webkit-transform: rotate(0deg);
+        transform: rotate(0deg)
+    }
+    100% {
+        -webkit-transform: rotate(359deg);
+        transform: rotate(359deg)
+    }
+}
+
+.fa-rotate-90 {
+    -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";
+    -webkit-transform: rotate(90deg);
+    -ms-transform: rotate(90deg);
+    transform: rotate(90deg)
+}
+
+.fa-rotate-180 {
+    -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";
+    -webkit-transform: rotate(180deg);
+    -ms-transform: rotate(180deg);
+    transform: rotate(180deg)
+}
+
+.fa-rotate-270 {
+    -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";
+    -webkit-transform: rotate(270deg);
+    -ms-transform: rotate(270deg);
+    transform: rotate(270deg)
+}
+
+.fa-flip-horizontal {
+    -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";
+    -webkit-transform: scale(-1, 1);
+    -ms-transform: scale(-1, 1);
+    transform: scale(-1, 1)
+}
+
+.fa-flip-vertical {
+    -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";
+    -webkit-transform: scale(1, -1);
+    -ms-transform: scale(1, -1);
+    transform: scale(1, -1)
+}
+
+:root .fa-rotate-90, :root .fa-rotate-180, :root .fa-rotate-270, :root .fa-flip-horizontal, :root .fa-flip-vertical {
+    filter: none
+}
+
+.fa-stack {
+    position: relative;
+    display: inline-block;
+    width: 2em;
+    height: 2em;
+    line-height: 2em;
+    vertical-align: middle
+}
+
+.fa-stack-1x, .fa-stack-2x {
+    position: absolute;
+    left: 0;
+    width: 100%;
+    text-align: center
+}
+
+.fa-stack-1x {
+    line-height: inherit
+}
+
+.fa-stack-2x {
+    font-size: 2em
+}
+
+.fa-inverse {
+    color: #fff
+}
+
+.fa-glass:before {
+    content: "\f000"
+}
+
+.fa-music:before {
+    content: "\f001"
+}
+
+.fa-search:before {
+    content: "\f002"
+}
+
+.fa-envelope-o:before {
+    content: "\f003"
+}
+
+.fa-heart:before {
+    content: "\f004"
+}
+
+.fa-star:before {
+    content: "\f005"
+}
+
+.fa-star-o:before {
+    content: "\f006"
+}
+
+.fa-user:before {
+    content: "\f007"
+}
+
+.fa-film:before {
+    content: "\f008"
+}
+
+.fa-th-large:before {
+    content: "\f009"
+}
+
+.fa-th:before {
+    content: "\f00a"
+}
+
+.fa-th-list:before {
+    content: "\f00b"
+}
+
+.fa-check:before {
+    content: "\f00c"
+}
+
+.fa-remove:before, .fa-close:before, .fa-times:before {
+    content: "\f00d"
+}
+
+.fa-search-plus:before {
+    content: "\f00e"
+}
+
+.fa-search-minus:before {
+    content: "\f010"
+}
+
+.fa-power-off:before {
+    content: "\f011"
+}
+
+.fa-signal:before {
+    content: "\f012"
+}
+
+.fa-gear:before, .fa-cog:before {
+    content: "\f013"
+}
+
+.fa-trash-o:before {
+    content: "\f014"
+}
+
+.fa-home:before {
+    content: "\f015"
+}
+
+.fa-file-o:before {
+    content: "\f016"
+}
+
+.fa-clock-o:before {
+    content: "\f017"
+}
+
+.fa-road:before {
+    content: "\f018"
+}
+
+.fa-download:before {
+    content: "\f019"
+}
+
+.fa-arrow-circle-o-down:before {
+    content: "\f01a"
+}
+
+.fa-arrow-circle-o-up:before {
+    content: "\f01b"
+}
+
+.fa-inbox:before {
+    content: "\f01c"
+}
+
+.fa-play-circle-o:before {
+    content: "\f01d"
+}
+
+.fa-rotate-right:before, .fa-repeat:before {
+    content: "\f01e"
+}
+
+.fa-refresh:before {
+    content: "\f021"
+}
+
+.fa-list-alt:before {
+    content: "\f022"
+}
+
+.fa-lock:before {
+    content: "\f023"
+}
+
+.fa-flag:before {
+    content: "\f024"
+}
+
+.fa-headphones:before {
+    content: "\f025"
+}
+
+.fa-volume-off:before {
+    content: "\f026"
+}
+
+.fa-volume-down:before {
+    content: "\f027"
+}
+
+.fa-volume-up:before {
+    content: "\f028"
+}
+
+.fa-qrcode:before {
+    content: "\f029"
+}
+
+.fa-barcode:before {
+    content: "\f02a"
+}
+
+.fa-tag:before {
+    content: "\f02b"
+}
+
+.fa-tags:before {
+    content: "\f02c"
+}
+
+.fa-book:before {
+    content: "\f02d"
+}
+
+.fa-bookmark:before {
+    content: "\f02e"
+}
+
+.fa-print:before {
+    content: "\f02f"
+}
+
+.fa-camera:before {
+    content: "\f030"
+}
+
+.fa-font:before {
+    content: "\f031"
+}
+
+.fa-bold:before {
+    content: "\f032"
+}
+
+.fa-italic:before {
+    content: "\f033"
+}
+
+.fa-text-height:before {
+    content: "\f034"
+}
+
+.fa-text-width:before {
+    content: "\f035"
+}
+
+.fa-align-left:before {
+    content: "\f036"
+}
+
+.fa-align-center:before {
+    content: "\f037"
+}
+
+.fa-align-right:before {
+    content: "\f038"
+}
+
+.fa-align-justify:before {
+    content: "\f039"
+}
+
+.fa-list:before {
+    content: "\f03a"
+}
+
+.fa-dedent:before, .fa-outdent:before {
+    content: "\f03b"
+}
+
+.fa-indent:before {
+    content: "\f03c"
+}
+
+.fa-video-camera:before {
+    content: "\f03d"
+}
+
+.fa-photo:before, .fa-image:before, .fa-picture-o:before {
+    content: "\f03e"
+}
+
+.fa-pencil:before {
+    content: "\f040"
+}
+
+.fa-map-marker:before {
+    content: "\f041"
+}
+
+.fa-adjust:before {
+    content: "\f042"
+}
+
+.fa-tint:before {
+    content: "\f043"
+}
+
+.fa-edit:before, .fa-pencil-square-o:before {
+    content: "\f044"
+}
+
+.fa-share-square-o:before {
+    content: "\f045"
+}
+
+.fa-check-square-o:before {
+    content: "\f046"
+}
+
+.fa-arrows:before {
+    content: "\f047"
+}
+
+.fa-step-backward:before {
+    content: "\f048"
+}
+
+.fa-fast-backward:before {
+    content: "\f049"
+}
+
+.fa-backward:before {
+    content: "\f04a"
+}
+
+.fa-play:before {
+    content: "\f04b"
+}
+
+.fa-pause:before {
+    content: "\f04c"
+}
+
+.fa-stop:before {
+    content: "\f04d"
+}
+
+.fa-forward:before {
+    content: "\f04e"
+}
+
+.fa-fast-forward:before {
+    content: "\f050"
+}
+
+.fa-step-forward:before {
+    content: "\f051"
+}
+
+.fa-eject:before {
+    content: "\f052"
+}
+
+.fa-chevron-left:before {
+    content: "\f053"
+}
+
+.fa-chevron-right:before {
+    content: "\f054"
+}
+
+.fa-plus-circle:before {
+    content: "\f055"
+}
+
+.fa-minus-circle:before {
+    content: "\f056"
+}
+
+.fa-times-circle:before {
+    content: "\f057"
+}
+
+.fa-check-circle:before {
+    content: "\f058"
+}
+
+.fa-question-circle:before {
+    content: "\f059"
+}
+
+.fa-info-circle:before {
+    content: "\f05a"
+}
+
+.fa-crosshairs:before {
+    content: "\f05b"
+}
+
+.fa-times-circle-o:before {
+    content: "\f05c"
+}
+
+.fa-check-circle-o:before {
+    content: "\f05d"
+}
+
+.fa-ban:before {
+    content: "\f05e"
+}
+
+.fa-arrow-left:before {
+    content: "\f060"
+}
+
+.fa-arrow-right:before {
+    content: "\f061"
+}
+
+.fa-arrow-up:before {
+    content: "\f062"
+}
+
+.fa-arrow-down:before {
+    content: "\f063"
+}
+
+.fa-mail-forward:before, .fa-share:before {
+    content: "\f064"
+}
+
+.fa-expand:before {
+    content: "\f065"
+}
+
+.fa-compress:before {
+    content: "\f066"
+}
+
+.fa-plus:before {
+    content: "\f067"
+}
+
+.fa-minus:before {
+    content: "\f068"
+}
+
+.fa-asterisk:before {
+    content: "\f069"
+}
+
+.fa-exclamation-circle:before {
+    content: "\f06a"
+}
+
+.fa-gift:before {
+    content: "\f06b"
+}
+
+.fa-leaf:before {
+    content: "\f06c"
+}
+
+.fa-fire:before {
+    content: "\f06d"
+}
+
+.fa-eye:before {
+    content: "\f06e"
+}
+
+.fa-eye-slash:before {
+    content: "\f070"
+}
+
+.fa-warning:before, .fa-exclamation-triangle:before {
+    content: "\f071"
+}
+
+.fa-plane:before {
+    content: "\f072"
+}
+
+.fa-calendar:before {
+    content: "\f073"
+}
+
+.fa-random:before {
+    content: "\f074"
+}
+
+.fa-comment:before {
+    content: "\f075"
+}
+
+.fa-magnet:before {
+    content: "\f076"
+}
+
+.fa-chevron-up:before {
+    content: "\f077"
+}
+
+.fa-chevron-down:before {
+    content: "\f078"
+}
+
+.fa-retweet:before {
+    content: "\f079"
+}
+
+.fa-shopping-cart:before {
+    content: "\f07a"
+}
+
+.fa-folder:before {
+    content: "\f07b"
+}
+
+.fa-folder-open:before {
+    content: "\f07c"
+}
+
+.fa-arrows-v:before {
+    content: "\f07d"
+}
+
+.fa-arrows-h:before {
+    content: "\f07e"
+}
+
+.fa-bar-chart-o:before, .fa-bar-chart:before {
+    content: "\f080"
+}
+
+.fa-twitter-square:before {
+    content: "\f081"
+}
+
+.fa-facebook-square:before {
+    content: "\f082"
+}
+
+.fa-camera-retro:before {
+    content: "\f083"
+}
+
+.fa-key:before {
+    content: "\f084"
+}
+
+.fa-gears:before, .fa-cogs:before {
+    content: "\f085"
+}
+
+.fa-comments:before {
+    content: "\f086"
+}
+
+.fa-thumbs-o-up:before {
+    content: "\f087"
+}
+
+.fa-thumbs-o-down:before {
+    content: "\f088"
+}
+
+.fa-star-half:before {
+    content: "\f089"
+}
+
+.fa-heart-o:before {
+    content: "\f08a"
+}
+
+.fa-sign-out:before {
+    content: "\f08b"
+}
+
+.fa-linkedin-square:before {
+    content: "\f08c"
+}
+
+.fa-thumb-tack:before {
+    content: "\f08d"
+}
+
+.fa-external-link:before {
+    content: "\f08e"
+}
+
+.fa-sign-in:before {
+    content: "\f090"
+}
+
+.fa-trophy:before {
+    content: "\f091"
+}
+
+.fa-github-square:before {
+    content: "\f092"
+}
+
+.fa-upload:before {
+    content: "\f093"
+}
+
+.fa-lemon-o:before {
+    content: "\f094"
+}
+
+.fa-phone:before {
+    content: "\f095"
+}
+
+.fa-square-o:before {
+    content: "\f096"
+}
+
+.fa-bookmark-o:before {
+    content: "\f097"
+}
+
+.fa-phone-square:before {
+    content: "\f098"
+}
+
+.fa-twitter:before {
+    content: "\f099"
+}
+
+.fa-facebook-f:before, .fa-facebook:before {
+    content: "\f09a"
+}
+
+.fa-github:before {
+    content: "\f09b"
+}
+
+.fa-unlock:before {
+    content: "\f09c"
+}
+
+.fa-credit-card:before {
+    content: "\f09d"
+}
+
+.fa-feed:before, .fa-rss:before {
+    content: "\f09e"
+}
+
+.fa-hdd-o:before {
+    content: "\f0a0"
+}
+
+.fa-bullhorn:before {
+    content: "\f0a1"
+}
+
+.fa-bell:before {
+    content: "\f0f3"
+}
+
+.fa-certificate:before {
+    content: "\f0a3"
+}
+
+.fa-hand-o-right:before {
+    content: "\f0a4"
+}
+
+.fa-hand-o-left:before {
+    content: "\f0a5"
+}
+
+.fa-hand-o-up:before {
+    content: "\f0a6"
+}
+
+.fa-hand-o-down:before {
+    content: "\f0a7"
+}
+
+.fa-arrow-circle-left:before {
+    content: "\f0a8"
+}
+
+.fa-arrow-circle-right:before {
+    content: "\f0a9"
+}
+
+.fa-arrow-circle-up:before {
+    content: "\f0aa"
+}
+
+.fa-arrow-circle-down:before {
+    content: "\f0ab"
+}
+
+.fa-globe:before {
+    content: "\f0ac"
+}
+
+.fa-wrench:before {
+    content: "\f0ad"
+}
+
+.fa-tasks:before {
+    content: "\f0ae"
+}
+
+.fa-filter:before {
+    content: "\f0b0"
+}
+
+.fa-briefcase:before {
+    content: "\f0b1"
+}
+
+.fa-arrows-alt:before {
+    content: "\f0b2"
+}
+
+.fa-group:before, .fa-users:before {
+    content: "\f0c0"
+}
+
+.fa-chain:before, .fa-link:before {
+    content: "\f0c1"
+}
+
+.fa-cloud:before {
+    content: "\f0c2"
+}
+
+.fa-flask:before {
+    content: "\f0c3"
+}
+
+.fa-cut:before, .fa-scissors:before {
+    content: "\f0c4"
+}
+
+.fa-copy:before, .fa-files-o:before {
+    content: "\f0c5"
+}
+
+.fa-paperclip:before {
+    content: "\f0c6"
+}
+
+.fa-save:before, .fa-floppy-o:before {
+    content: "\f0c7"
+}
+
+.fa-square:before {
+    content: "\f0c8"
+}
+
+.fa-navicon:before, .fa-reorder:before, .fa-bars:before {
+    content: "\f0c9"
+}
+
+.fa-list-ul:before {
+    content: "\f0ca"
+}
+
+.fa-list-ol:before {
+    content: "\f0cb"
+}
+
+.fa-strikethrough:before {
+    content: "\f0cc"
+}
+
+.fa-underline:before {
+    content: "\f0cd"
+}
+
+.fa-table:before {
+    content: "\f0ce"
+}
+
+.fa-magic:before {
+    content: "\f0d0"
+}
+
+.fa-truck:before {
+    content: "\f0d1"
+}
+
+.fa-pinterest:before {
+    content: "\f0d2"
+}
+
+.fa-pinterest-square:before {
+    content: "\f0d3"
+}
+
+.fa-google-plus-square:before {
+    content: "\f0d4"
+}
+
+.fa-google-plus:before {
+    content: "\f0d5"
+}
+
+.fa-money:before {
+    content: "\f0d6"
+}
+
+.fa-caret-down:before {
+    content: "\f0d7"
+}
+
+.fa-caret-up:before {
+    content: "\f0d8"
+}
+
+.fa-caret-left:before {
+    content: "\f0d9"
+}
+
+.fa-caret-right:before {
+    content: "\f0da"
+}
+
+.fa-columns:before {
+    content: "\f0db"
+}
+
+.fa-unsorted:before, .fa-sort:before {
+    content: "\f0dc"
+}
+
+.fa-sort-down:before, .fa-sort-desc:before {
+    content: "\f0dd"
+}
+
+.fa-sort-up:before, .fa-sort-asc:before {
+    content: "\f0de"
+}
+
+.fa-envelope:before {
+    content: "\f0e0"
+}
+
+.fa-linkedin:before {
+    content: "\f0e1"
+}
+
+.fa-rotate-left:before, .fa-undo:before {
+    content: "\f0e2"
+}
+
+.fa-legal:before, .fa-gavel:before {
+    content: "\f0e3"
+}
+
+.fa-dashboard:before, .fa-tachometer:before {
+    content: "\f0e4"
+}
+
+.fa-comment-o:before {
+    content: "\f0e5"
+}
+
+.fa-comments-o:before {
+    content: "\f0e6"
+}
+
+.fa-flash:before, .fa-bolt:before {
+    content: "\f0e7"
+}
+
+.fa-sitemap:before {
+    content: "\f0e8"
+}
+
+.fa-umbrella:before {
+    content: "\f0e9"
+}
+
+.fa-paste:before, .fa-clipboard:before {
+    content: "\f0ea"
+}
+
+.fa-lightbulb-o:before {
+    content: "\f0eb"
+}
+
+.fa-exchange:before {
+    content: "\f0ec"
+}
+
+.fa-cloud-download:before {
+    content: "\f0ed"
+}
+
+.fa-cloud-upload:before {
+    content: "\f0ee"
+}
+
+.fa-user-md:before {
+    content: "\f0f0"
+}
+
+.fa-stethoscope:before {
+    content: "\f0f1"
+}
+
+.fa-suitcase:before {
+    content: "\f0f2"
+}
+
+.fa-bell-o:before {
+    content: "\f0a2"
+}
+
+.fa-coffee:before {
+    content: "\f0f4"
+}
+
+.fa-cutlery:before {
+    content: "\f0f5"
+}
+
+.fa-file-text-o:before {
+    content: "\f0f6"
+}
+
+.fa-building-o:before {
+    content: "\f0f7"
+}
+
+.fa-hospital-o:before {
+    content: "\f0f8"
+}
+
+.fa-ambulance:before {
+    content: "\f0f9"
+}
+
+.fa-medkit:before {
+    content: "\f0fa"
+}
+
+.fa-fighter-jet:before {
+    content: "\f0fb"
+}
+
+.fa-beer:before {
+    content: "\f0fc"
+}
+
+.fa-h-square:before {
+    content: "\f0fd"
+}
+
+.fa-plus-square:before {
+    content: "\f0fe"
+}
+
+.fa-angle-double-left:before {
+    content: "\f100"
+}
+
+.fa-angle-double-right:before {
+    content: "\f101"
+}
+
+.fa-angle-double-up:before {
+    content: "\f102"
+}
+
+.fa-angle-double-down:before {
+    content: "\f103"
+}
+
+.fa-angle-left:before {
+    content: "\f104"
+}
+
+.fa-angle-right:before {
+    content: "\f105"
+}
+
+.fa-angle-up:before {
+    content: "\f106"
+}
+
+.fa-angle-down:before {
+    content: "\f107"
+}
+
+.fa-desktop:before {
+    content: "\f108"
+}
+
+.fa-laptop:before {
+    content: "\f109"
+}
+
+.fa-tablet:before {
+    content: "\f10a"
+}
+
+.fa-mobile-phone:before, .fa-mobile:before {
+    content: "\f10b"
+}
+
+.fa-circle-o:before {
+    content: "\f10c"
+}
+
+.fa-quote-left:before {
+    content: "\f10d"
+}
+
+.fa-quote-right:before {
+    content: "\f10e"
+}
+
+.fa-spinner:before {
+    content: "\f110"
+}
+
+.fa-circle:before {
+    content: "\f111"
+}
+
+.fa-mail-reply:before, .fa-reply:before {
+    content: "\f112"
+}
+
+.fa-github-alt:before {
+    content: "\f113"
+}
+
+.fa-folder-o:before {
+    content: "\f114"
+}
+
+.fa-folder-open-o:before {
+    content: "\f115"
+}
+
+.fa-smile-o:before {
+    content: "\f118"
+}
+
+.fa-frown-o:before {
+    content: "\f119"
+}
+
+.fa-meh-o:before {
+    content: "\f11a"
+}
+
+.fa-gamepad:before {
+    content: "\f11b"
+}
+
+.fa-keyboard-o:before {
+    content: "\f11c"
+}
+
+.fa-flag-o:before {
+    content: "\f11d"
+}
+
+.fa-flag-checkered:before {
+    content: "\f11e"
+}
+
+.fa-terminal:before {
+    content: "\f120"
+}
+
+.fa-code:before {
+    content: "\f121"
+}
+
+.fa-mail-reply-all:before, .fa-reply-all:before {
+    content: "\f122"
+}
+
+.fa-star-half-empty:before, .fa-star-half-full:before, .fa-star-half-o:before {
+    content: "\f123"
+}
+
+.fa-location-arrow:before {
+    content: "\f124"
+}
+
+.fa-crop:before {
+    content: "\f125"
+}
+
+.fa-code-fork:before {
+    content: "\f126"
+}
+
+.fa-unlink:before, .fa-chain-broken:before {
+    content: "\f127"
+}
+
+.fa-question:before {
+    content: "\f128"
+}
+
+.fa-info:before {
+    content: "\f129"
+}
+
+.fa-exclamation:before {
+    content: "\f12a"
+}
+
+.fa-superscript:before {
+    content: "\f12b"
+}
+
+.fa-subscript:before {
+    content: "\f12c"
+}
+
+.fa-eraser:before {
+    content: "\f12d"
+}
+
+.fa-puzzle-piece:before {
+    content: "\f12e"
+}
+
+.fa-microphone:before {
+    content: "\f130"
+}
+
+.fa-microphone-slash:before {
+    content: "\f131"
+}
+
+.fa-shield:before {
+    content: "\f132"
+}
+
+.fa-calendar-o:before {
+    content: "\f133"
+}
+
+.fa-fire-extinguisher:before {
+    content: "\f134"
+}
+
+.fa-rocket:before {
+    content: "\f135"
+}
+
+.fa-maxcdn:before {
+    content: "\f136"
+}
+
+.fa-chevron-circle-left:before {
+    content: "\f137"
+}
+
+.fa-chevron-circle-right:before {
+    content: "\f138"
+}
+
+.fa-chevron-circle-up:before {
+    content: "\f139"
+}
+
+.fa-chevron-circle-down:before {
+    content: "\f13a"
+}
+
+.fa-html5:before {
+    content: "\f13b"
+}
+
+.fa-css3:before {
+    content: "\f13c"
+}
+
+.fa-anchor:before {
+    content: "\f13d"
+}
+
+.fa-unlock-alt:before {
+    content: "\f13e"
+}
+
+.fa-bullseye:before {
+    content: "\f140"
+}
+
+.fa-ellipsis-h:before {
+    content: "\f141"
+}
+
+.fa-ellipsis-v:before {
+    content: "\f142"
+}
+
+.fa-rss-square:before {
+    content: "\f143"
+}
+
+.fa-play-circle:before {
+    content: "\f144"
+}
+
+.fa-ticket:before {
+    content: "\f145"
+}
+
+.fa-minus-square:before {
+    content: "\f146"
+}
+
+.fa-minus-square-o:before {
+    content: "\f147"
+}
+
+.fa-level-up:before {
+    content: "\f148"
+}
+
+.fa-level-down:before {
+    content: "\f149"
+}
+
+.fa-check-square:before {
+    content: "\f14a"
+}
+
+.fa-pencil-square:before {
+    content: "\f14b"
+}
+
+.fa-external-link-square:before {
+    content: "\f14c"
+}
+
+.fa-share-square:before {
+    content: "\f14d"
+}
+
+.fa-compass:before {
+    content: "\f14e"
+}
+
+.fa-toggle-down:before, .fa-caret-square-o-down:before {
+    content: "\f150"
+}
+
+.fa-toggle-up:before, .fa-caret-square-o-up:before {
+    content: "\f151"
+}
+
+.fa-toggle-right:before, .fa-caret-square-o-right:before {
+    content: "\f152"
+}
+
+.fa-euro:before, .fa-eur:before {
+    content: "\f153"
+}
+
+.fa-gbp:before {
+    content: "\f154"
+}
+
+.fa-dollar:before, .fa-usd:before {
+    content: "\f155"
+}
+
+.fa-rupee:before, .fa-inr:before {
+    content: "\f156"
+}
+
+.fa-cny:before, .fa-rmb:before, .fa-yen:before, .fa-jpy:before {
+    content: "\f157"
+}
+
+.fa-ruble:before, .fa-rouble:before, .fa-rub:before {
+    content: "\f158"
+}
+
+.fa-won:before, .fa-krw:before {
+    content: "\f159"
+}
+
+.fa-bitcoin:before, .fa-btc:before {
+    content: "\f15a"
+}
+
+.fa-file:before {
+    content: "\f15b"
+}
+
+.fa-file-text:before {
+    content: "\f15c"
+}
+
+.fa-sort-alpha-asc:before {
+    content: "\f15d"
+}
+
+.fa-sort-alpha-desc:before {
+    content: "\f15e"
+}
+
+.fa-sort-amount-asc:before {
+    content: "\f160"
+}
+
+.fa-sort-amount-desc:before {
+    content: "\f161"
+}
+
+.fa-sort-numeric-asc:before {
+    content: "\f162"
+}
+
+.fa-sort-numeric-desc:before {
+    content: "\f163"
+}
+
+.fa-thumbs-up:before {
+    content: "\f164"
+}
+
+.fa-thumbs-down:before {
+    content: "\f165"
+}
+
+.fa-youtube-square:before {
+    content: "\f166"
+}
+
+.fa-youtube:before {
+    content: "\f167"
+}
+
+.fa-xing:before {
+    content: "\f168"
+}
+
+.fa-xing-square:before {
+    content: "\f169"
+}
+
+.fa-youtube-play:before {
+    content: "\f16a"
+}
+
+.fa-dropbox:before {
+    content: "\f16b"
+}
+
+.fa-stack-overflow:before {
+    content: "\f16c"
+}
+
+.fa-instagram:before {
+    content: "\f16d"
+}
+
+.fa-flickr:before {
+    content: "\f16e"
+}
+
+.fa-adn:before {
+    content: "\f170"
+}
+
+.fa-bitbucket:before {
+    content: "\f171"
+}
+
+.fa-bitbucket-square:before {
+    content: "\f172"
+}
+
+.fa-tumblr:before {
+    content: "\f173"
+}
+
+.fa-tumblr-square:before {
+    content: "\f174"
+}
+
+.fa-long-arrow-down:before {
+    content: "\f175"
+}
+
+.fa-long-arrow-up:before {
+    content: "\f176"
+}
+
+.fa-long-arrow-left:before {
+    content: "\f177"
+}
+
+.fa-long-arrow-right:before {
+    content: "\f178"
+}
+
+.fa-apple:before {
+    content: "\f179"
+}
+
+.fa-windows:before {
+    content: "\f17a"
+}
+
+.fa-android:before {
+    content: "\f17b"
+}
+
+.fa-linux:before {
+    content: "\f17c"
+}
+
+.fa-dribbble:before {
+    content: "\f17d"
+}
+
+.fa-skype:before {
+    content: "\f17e"
+}
+
+.fa-foursquare:before {
+    content: "\f180"
+}
+
+.fa-trello:before {
+    content: "\f181"
+}
+
+.fa-female:before {
+    content: "\f182"
+}
+
+.fa-male:before {
+    content: "\f183"
+}
+
+.fa-gittip:before, .fa-gratipay:before {
+    content: "\f184"
+}
+
+.fa-sun-o:before {
+    content: "\f185"
+}
+
+.fa-moon-o:before {
+    content: "\f186"
+}
+
+.fa-archive:before {
+    content: "\f187"
+}
+
+.fa-bug:before {
+    content: "\f188"
+}
+
+.fa-vk:before {
+    content: "\f189"
+}
+
+.fa-weibo:before {
+    content: "\f18a"
+}
+
+.fa-renren:before {
+    content: "\f18b"
+}
+
+.fa-pagelines:before {
+    content: "\f18c"
+}
+
+.fa-stack-exchange:before {
+    content: "\f18d"
+}
+
+.fa-arrow-circle-o-right:before {
+    content: "\f18e"
+}
+
+.fa-arrow-circle-o-left:before {
+    content: "\f190"
+}
+
+.fa-toggle-left:before, .fa-caret-square-o-left:before {
+    content: "\f191"
+}
+
+.fa-dot-circle-o:before {
+    content: "\f192"
+}
+
+.fa-wheelchair:before {
+    content: "\f193"
+}
+
+.fa-vimeo-square:before {
+    content: "\f194"
+}
+
+.fa-turkish-lira:before, .fa-try:before {
+    content: "\f195"
+}
+
+.fa-plus-square-o:before {
+    content: "\f196"
+}
+
+.fa-space-shuttle:before {
+    content: "\f197"
+}
+
+.fa-slack:before {
+    content: "\f198"
+}
+
+.fa-envelope-square:before {
+    content: "\f199"
+}
+
+.fa-wordpress:before {
+    content: "\f19a"
+}
+
+.fa-openid:before {
+    content: "\f19b"
+}
+
+.fa-institution:before, .fa-bank:before, .fa-university:before {
+    content: "\f19c"
+}
+
+.fa-mortar-board:before, .fa-graduation-cap:before {
+    content: "\f19d"
+}
+
+.fa-yahoo:before {
+    content: "\f19e"
+}
+
+.fa-google:before {
+    content: "\f1a0"
+}
+
+.fa-reddit:before {
+    content: "\f1a1"
+}
+
+.fa-reddit-square:before {
+    content: "\f1a2"
+}
+
+.fa-stumbleupon-circle:before {
+    content: "\f1a3"
+}
+
+.fa-stumbleupon:before {
+    content: "\f1a4"
+}
+
+.fa-delicious:before {
+    content: "\f1a5"
+}
+
+.fa-digg:before {
+    content: "\f1a6"
+}
+
+.fa-pied-piper-pp:before {
+    content: "\f1a7"
+}
+
+.fa-pied-piper-alt:before {
+    content: "\f1a8"
+}
+
+.fa-drupal:before {
+    content: "\f1a9"
+}
+
+.fa-joomla:before {
+    content: "\f1aa"
+}
+
+.fa-language:before {
+    content: "\f1ab"
+}
+
+.fa-fax:before {
+    content: "\f1ac"
+}
+
+.fa-building:before {
+    content: "\f1ad"
+}
+
+.fa-child:before {
+    content: "\f1ae"
+}
+
+.fa-paw:before {
+    content: "\f1b0"
+}
+
+.fa-spoon:before {
+    content: "\f1b1"
+}
+
+.fa-cube:before {
+    content: "\f1b2"
+}
+
+.fa-cubes:before {
+    content: "\f1b3"
+}
+
+.fa-behance:before {
+    content: "\f1b4"
+}
+
+.fa-behance-square:before {
+    content: "\f1b5"
+}
+
+.fa-steam:before {
+    content: "\f1b6"
+}
+
+.fa-steam-square:before {
+    content: "\f1b7"
+}
+
+.fa-recycle:before {
+    content: "\f1b8"
+}
+
+.fa-automobile:before, .fa-car:before {
+    content: "\f1b9"
+}
+
+.fa-cab:before, .fa-taxi:before {
+    content: "\f1ba"
+}
+
+.fa-tree:before {
+    content: "\f1bb"
+}
+
+.fa-spotify:before {
+    content: "\f1bc"
+}
+
+.fa-deviantart:before {
+    content: "\f1bd"
+}
+
+.fa-soundcloud:before {
+    content: "\f1be"
+}
+
+.fa-database:before {
+    content: "\f1c0"
+}
+
+.fa-file-pdf-o:before {
+    content: "\f1c1"
+}
+
+.fa-file-word-o:before {
+    content: "\f1c2"
+}
+
+.fa-file-excel-o:before {
+    content: "\f1c3"
+}
+
+.fa-file-powerpoint-o:before {
+    content: "\f1c4"
+}
+
+.fa-file-photo-o:before, .fa-file-picture-o:before, .fa-file-image-o:before {
+    content: "\f1c5"
+}
+
+.fa-file-zip-o:before, .fa-file-archive-o:before {
+    content: "\f1c6"
+}
+
+.fa-file-sound-o:before, .fa-file-audio-o:before {
+    content: "\f1c7"
+}
+
+.fa-file-movie-o:before, .fa-file-video-o:before {
+    content: "\f1c8"
+}
+
+.fa-file-code-o:before {
+    content: "\f1c9"
+}
+
+.fa-vine:before {
+    content: "\f1ca"
+}
+
+.fa-codepen:before {
+    content: "\f1cb"
+}
+
+.fa-jsfiddle:before {
+    content: "\f1cc"
+}
+
+.fa-life-bouy:before, .fa-life-buoy:before, .fa-life-saver:before, .fa-support:before, .fa-life-ring:before {
+    content: "\f1cd"
+}
+
+.fa-circle-o-notch:before {
+    content: "\f1ce"
+}
+
+.fa-ra:before, .fa-resistance:before, .fa-rebel:before {
+    content: "\f1d0"
+}
+
+.fa-ge:before, .fa-empire:before {
+    content: "\f1d1"
+}
+
+.fa-git-square:before {
+    content: "\f1d2"
+}
+
+.fa-git:before {
+    content: "\f1d3"
+}
+
+.fa-y-combinator-square:before, .fa-yc-square:before, .fa-hacker-news:before {
+    content: "\f1d4"
+}
+
+.fa-tencent-weibo:before {
+    content: "\f1d5"
+}
+
+.fa-qq:before {
+    content: "\f1d6"
+}
+
+.fa-wechat:before, .fa-weixin:before {
+    content: "\f1d7"
+}
+
+.fa-send:before, .fa-paper-plane:before {
+    content: "\f1d8"
+}
+
+.fa-send-o:before, .fa-paper-plane-o:before {
+    content: "\f1d9"
+}
+
+.fa-history:before {
+    content: "\f1da"
+}
+
+.fa-circle-thin:before {
+    content: "\f1db"
+}
+
+.fa-header:before {
+    content: "\f1dc"
+}
+
+.fa-paragraph:before {
+    content: "\f1dd"
+}
+
+.fa-sliders:before {
+    content: "\f1de"
+}
+
+.fa-share-alt:before {
+    content: "\f1e0"
+}
+
+.fa-share-alt-square:before {
+    content: "\f1e1"
+}
+
+.fa-bomb:before {
+    content: "\f1e2"
+}
+
+.fa-soccer-ball-o:before, .fa-futbol-o:before {
+    content: "\f1e3"
+}
+
+.fa-tty:before {
+    content: "\f1e4"
+}
+
+.fa-binoculars:before {
+    content: "\f1e5"
+}
+
+.fa-plug:before {
+    content: "\f1e6"
+}
+
+.fa-slideshare:before {
+    content: "\f1e7"
+}
+
+.fa-twitch:before {
+    content: "\f1e8"
+}
+
+.fa-yelp:before {
+    content: "\f1e9"
+}
+
+.fa-newspaper-o:before {
+    content: "\f1ea"
+}
+
+.fa-wifi:before {
+    content: "\f1eb"
+}
+
+.fa-calculator:before {
+    content: "\f1ec"
+}
+
+.fa-paypal:before {
+    content: "\f1ed"
+}
+
+.fa-google-wallet:before {
+    content: "\f1ee"
+}
+
+.fa-cc-visa:before {
+    content: "\f1f0"
+}
+
+.fa-cc-mastercard:before {
+    content: "\f1f1"
+}
+
+.fa-cc-discover:before {
+    content: "\f1f2"
+}
+
+.fa-cc-amex:before {
+    content: "\f1f3"
+}
+
+.fa-cc-paypal:before {
+    content: "\f1f4"
+}
+
+.fa-cc-stripe:before {
+    content: "\f1f5"
+}
+
+.fa-bell-slash:before {
+    content: "\f1f6"
+}
+
+.fa-bell-slash-o:before {
+    content: "\f1f7"
+}
+
+.fa-trash:before {
+    content: "\f1f8"
+}
+
+.fa-copyright:before {
+    content: "\f1f9"
+}
+
+.fa-at:before {
+    content: "\f1fa"
+}
+
+.fa-eyedropper:before {
+    content: "\f1fb"
+}
+
+.fa-paint-brush:before {
+    content: "\f1fc"
+}
+
+.fa-birthday-cake:before {
+    content: "\f1fd"
+}
+
+.fa-area-chart:before {
+    content: "\f1fe"
+}
+
+.fa-pie-chart:before {
+    content: "\f200"
+}
+
+.fa-line-chart:before {
+    content: "\f201"
+}
+
+.fa-lastfm:before {
+    content: "\f202"
+}
+
+.fa-lastfm-square:before {
+    content: "\f203"
+}
+
+.fa-toggle-off:before {
+    content: "\f204"
+}
+
+.fa-toggle-on:before {
+    content: "\f205"
+}
+
+.fa-bicycle:before {
+    content: "\f206"
+}
+
+.fa-bus:before {
+    content: "\f207"
+}
+
+.fa-ioxhost:before {
+    content: "\f208"
+}
+
+.fa-angellist:before {
+    content: "\f209"
+}
+
+.fa-cc:before {
+    content: "\f20a"
+}
+
+.fa-shekel:before, .fa-sheqel:before, .fa-ils:before {
+    content: "\f20b"
+}
+
+.fa-meanpath:before {
+    content: "\f20c"
+}
+
+.fa-buysellads:before {
+    content: "\f20d"
+}
+
+.fa-connectdevelop:before {
+    content: "\f20e"
+}
+
+.fa-dashcube:before {
+    content: "\f210"
+}
+
+.fa-forumbee:before {
+    content: "\f211"
+}
+
+.fa-leanpub:before {
+    content: "\f212"
+}
+
+.fa-sellsy:before {
+    content: "\f213"
+}
+
+.fa-shirtsinbulk:before {
+    content: "\f214"
+}
+
+.fa-simplybuilt:before {
+    content: "\f215"
+}
+
+.fa-skyatlas:before {
+    content: "\f216"
+}
+
+.fa-cart-plus:before {
+    content: "\f217"
+}
+
+.fa-cart-arrow-down:before {
+    content: "\f218"
+}
+
+.fa-diamond:before {
+    content: "\f219"
+}
+
+.fa-ship:before {
+    content: "\f21a"
+}
+
+.fa-user-secret:before {
+    content: "\f21b"
+}
+
+.fa-motorcycle:before {
+    content: "\f21c"
+}
+
+.fa-street-view:before {
+    content: "\f21d"
+}
+
+.fa-heartbeat:before {
+    content: "\f21e"
+}
+
+.fa-venus:before {
+    content: "\f221"
+}
+
+.fa-mars:before {
+    content: "\f222"
+}
+
+.fa-mercury:before {
+    content: "\f223"
+}
+
+.fa-intersex:before, .fa-transgender:before {
+    content: "\f224"
+}
+
+.fa-transgender-alt:before {
+    content: "\f225"
+}
+
+.fa-venus-double:before {
+    content: "\f226"
+}
+
+.fa-mars-double:before {
+    content: "\f227"
+}
+
+.fa-venus-mars:before {
+    content: "\f228"
+}
+
+.fa-mars-stroke:before {
+    content: "\f229"
+}
+
+.fa-mars-stroke-v:before {
+    content: "\f22a"
+}
+
+.fa-mars-stroke-h:before {
+    content: "\f22b"
+}
+
+.fa-neuter:before {
+    content: "\f22c"
+}
+
+.fa-genderless:before {
+    content: "\f22d"
+}
+
+.fa-facebook-official:before {
+    content: "\f230"
+}
+
+.fa-pinterest-p:before {
+    content: "\f231"
+}
+
+.fa-whatsapp:before {
+    content: "\f232"
+}
+
+.fa-server:before {
+    content: "\f233"
+}
+
+.fa-user-plus:before {
+    content: "\f234"
+}
+
+.fa-user-times:before {
+    content: "\f235"
+}
+
+.fa-hotel:before, .fa-bed:before {
+    content: "\f236"
+}
+
+.fa-viacoin:before {
+    content: "\f237"
+}
+
+.fa-train:before {
+    content: "\f238"
+}
+
+.fa-subway:before {
+    content: "\f239"
+}
+
+.fa-medium:before {
+    content: "\f23a"
+}
+
+.fa-yc:before, .fa-y-combinator:before {
+    content: "\f23b"
+}
+
+.fa-optin-monster:before {
+    content: "\f23c"
+}
+
+.fa-opencart:before {
+    content: "\f23d"
+}
+
+.fa-expeditedssl:before {
+    content: "\f23e"
+}
+
+.fa-battery-4:before, .fa-battery:before, .fa-battery-full:before {
+    content: "\f240"
+}
+
+.fa-battery-3:before, .fa-battery-three-quarters:before {
+    content: "\f241"
+}
+
+.fa-battery-2:before, .fa-battery-half:before {
+    content: "\f242"
+}
+
+.fa-battery-1:before, .fa-battery-quarter:before {
+    content: "\f243"
+}
+
+.fa-battery-0:before, .fa-battery-empty:before {
+    content: "\f244"
+}
+
+.fa-mouse-pointer:before {
+    content: "\f245"
+}
+
+.fa-i-cursor:before {
+    content: "\f246"
+}
+
+.fa-object-group:before {
+    content: "\f247"
+}
+
+.fa-object-ungroup:before {
+    content: "\f248"
+}
+
+.fa-sticky-note:before {
+    content: "\f249"
+}
+
+.fa-sticky-note-o:before {
+    content: "\f24a"
+}
+
+.fa-cc-jcb:before {
+    content: "\f24b"
+}
+
+.fa-cc-diners-club:before {
+    content: "\f24c"
+}
+
+.fa-clone:before {
+    content: "\f24d"
+}
+
+.fa-balance-scale:before {
+    content: "\f24e"
+}
+
+.fa-hourglass-o:before {
+    content: "\f250"
+}
+
+.fa-hourglass-1:before, .fa-hourglass-start:before {
+    content: "\f251"
+}
+
+.fa-hourglass-2:before, .fa-hourglass-half:before {
+    content: "\f252"
+}
+
+.fa-hourglass-3:before, .fa-hourglass-end:before {
+    content: "\f253"
+}
+
+.fa-hourglass:before {
+    content: "\f254"
+}
+
+.fa-hand-grab-o:before, .fa-hand-rock-o:before {
+    content: "\f255"
+}
+
+.fa-hand-stop-o:before, .fa-hand-paper-o:before {
+    content: "\f256"
+}
+
+.fa-hand-scissors-o:before {
+    content: "\f257"
+}
+
+.fa-hand-lizard-o:before {
+    content: "\f258"
+}
+
+.fa-hand-spock-o:before {
+    content: "\f259"
+}
+
+.fa-hand-pointer-o:before {
+    content: "\f25a"
+}
+
+.fa-hand-peace-o:before {
+    content: "\f25b"
+}
+
+.fa-trademark:before {
+    content: "\f25c"
+}
+
+.fa-registered:before {
+    content: "\f25d"
+}
+
+.fa-creative-commons:before {
+    content: "\f25e"
+}
+
+.fa-gg:before {
+    content: "\f260"
+}
+
+.fa-gg-circle:before {
+    content: "\f261"
+}
+
+.fa-tripadvisor:before {
+    content: "\f262"
+}
+
+.fa-odnoklassniki:before {
+    content: "\f263"
+}
+
+.fa-odnoklassniki-square:before {
+    content: "\f264"
+}
+
+.fa-get-pocket:before {
+    content: "\f265"
+}
+
+.fa-wikipedia-w:before {
+    content: "\f266"
+}
+
+.fa-safari:before {
+    content: "\f267"
+}
+
+.fa-chrome:before {
+    content: "\f268"
+}
+
+.fa-firefox:before {
+    content: "\f269"
+}
+
+.fa-opera:before {
+    content: "\f26a"
+}
+
+.fa-internet-explorer:before {
+    content: "\f26b"
+}
+
+.fa-tv:before, .fa-television:before {
+    content: "\f26c"
+}
+
+.fa-contao:before {
+    content: "\f26d"
+}
+
+.fa-500px:before {
+    content: "\f26e"
+}
+
+.fa-amazon:before {
+    content: "\f270"
+}
+
+.fa-calendar-plus-o:before {
+    content: "\f271"
+}
+
+.fa-calendar-minus-o:before {
+    content: "\f272"
+}
+
+.fa-calendar-times-o:before {
+    content: "\f273"
+}
+
+.fa-calendar-check-o:before {
+    content: "\f274"
+}
+
+.fa-industry:before {
+    content: "\f275"
+}
+
+.fa-map-pin:before {
+    content: "\f276"
+}
+
+.fa-map-signs:before {
+    content: "\f277"
+}
+
+.fa-map-o:before {
+    content: "\f278"
+}
+
+.fa-map:before {
+    content: "\f279"
+}
+
+.fa-commenting:before {
+    content: "\f27a"
+}
+
+.fa-commenting-o:before {
+    content: "\f27b"
+}
+
+.fa-houzz:before {
+    content: "\f27c"
+}
+
+.fa-vimeo:before {
+    content: "\f27d"
+}
+
+.fa-black-tie:before {
+    content: "\f27e"
+}
+
+.fa-fonticons:before {
+    content: "\f280"
+}
+
+.fa-reddit-alien:before {
+    content: "\f281"
+}
+
+.fa-edge:before {
+    content: "\f282"
+}
+
+.fa-credit-card-alt:before {
+    content: "\f283"
+}
+
+.fa-codiepie:before {
+    content: "\f284"
+}
+
+.fa-modx:before {
+    content: "\f285"
+}
+
+.fa-fort-awesome:before {
+    content: "\f286"
+}
+
+.fa-usb:before {
+    content: "\f287"
+}
+
+.fa-product-hunt:before {
+    content: "\f288"
+}
+
+.fa-mixcloud:before {
+    content: "\f289"
+}
+
+.fa-scribd:before {
+    content: "\f28a"
+}
+
+.fa-pause-circle:before {
+    content: "\f28b"
+}
+
+.fa-pause-circle-o:before {
+    content: "\f28c"
+}
+
+.fa-stop-circle:before {
+    content: "\f28d"
+}
+
+.fa-stop-circle-o:before {
+    content: "\f28e"
+}
+
+.fa-shopping-bag:before {
+    content: "\f290"
+}
+
+.fa-shopping-basket:before {
+    content: "\f291"
+}
+
+.fa-hashtag:before {
+    content: "\f292"
+}
+
+.fa-bluetooth:before {
+    content: "\f293"
+}
+
+.fa-bluetooth-b:before {
+    content: "\f294"
+}
+
+.fa-percent:before {
+    content: "\f295"
+}
+
+.fa-gitlab:before {
+    content: "\f296"
+}
+
+.fa-wpbeginner:before {
+    content: "\f297"
+}
+
+.fa-wpforms:before {
+    content: "\f298"
+}
+
+.fa-envira:before {
+    content: "\f299"
+}
+
+.fa-universal-access:before {
+    content: "\f29a"
+}
+
+.fa-wheelchair-alt:before {
+    content: "\f29b"
+}
+
+.fa-question-circle-o:before {
+    content: "\f29c"
+}
+
+.fa-blind:before {
+    content: "\f29d"
+}
+
+.fa-audio-description:before {
+    content: "\f29e"
+}
+
+.fa-volume-control-phone:before {
+    content: "\f2a0"
+}
+
+.fa-braille:before {
+    content: "\f2a1"
+}
+
+.fa-assistive-listening-systems:before {
+    content: "\f2a2"
+}
+
+.fa-asl-interpreting:before, .fa-american-sign-language-interpreting:before {
+    content: "\f2a3"
+}
+
+.fa-deafness:before, .fa-hard-of-hearing:before, .fa-deaf:before {
+    content: "\f2a4"
+}
+
+.fa-glide:before {
+    content: "\f2a5"
+}
+
+.fa-glide-g:before {
+    content: "\f2a6"
+}
+
+.fa-signing:before, .fa-sign-language:before {
+    content: "\f2a7"
+}
+
+.fa-low-vision:before {
+    content: "\f2a8"
+}
+
+.fa-viadeo:before {
+    content: "\f2a9"
+}
+
+.fa-viadeo-square:before {
+    content: "\f2aa"
+}
+
+.fa-snapchat:before {
+    content: "\f2ab"
+}
+
+.fa-snapchat-ghost:before {
+    content: "\f2ac"
+}
+
+.fa-snapchat-square:before {
+    content: "\f2ad"
+}
+
+.fa-pied-piper:before {
+    content: "\f2ae"
+}
+
+.fa-first-order:before {
+    content: "\f2b0"
+}
+
+.fa-yoast:before {
+    content: "\f2b1"
+}
+
+.fa-themeisle:before {
+    content: "\f2b2"
+}
+
+.fa-google-plus-circle:before, .fa-google-plus-official:before {
+    content: "\f2b3"
+}
+
+.fa-fa:before, .fa-font-awesome:before {
+    content: "\f2b4"
+}
+
+.fa-handshake-o:before {
+    content: "\f2b5"
+}
+
+.fa-envelope-open:before {
+    content: "\f2b6"
+}
+
+.fa-envelope-open-o:before {
+    content: "\f2b7"
+}
+
+.fa-linode:before {
+    content: "\f2b8"
+}
+
+.fa-address-book:before {
+    content: "\f2b9"
+}
+
+.fa-address-book-o:before {
+    content: "\f2ba"
+}
+
+.fa-vcard:before, .fa-address-card:before {
+    content: "\f2bb"
+}
+
+.fa-vcard-o:before, .fa-address-card-o:before {
+    content: "\f2bc"
+}
+
+.fa-user-circle:before {
+    content: "\f2bd"
+}
+
+.fa-user-circle-o:before {
+    content: "\f2be"
+}
+
+.fa-user-o:before {
+    content: "\f2c0"
+}
+
+.fa-id-badge:before {
+    content: "\f2c1"
+}
+
+.fa-drivers-license:before, .fa-id-card:before {
+    content: "\f2c2"
+}
+
+.fa-drivers-license-o:before, .fa-id-card-o:before {
+    content: "\f2c3"
+}
+
+.fa-quora:before {
+    content: "\f2c4"
+}
+
+.fa-free-code-camp:before {
+    content: "\f2c5"
+}
+
+.fa-telegram:before {
+    content: "\f2c6"
+}
+
+.fa-thermometer-4:before, .fa-thermometer:before, .fa-thermometer-full:before {
+    content: "\f2c7"
+}
+
+.fa-thermometer-3:before, .fa-thermometer-three-quarters:before {
+    content: "\f2c8"
+}
+
+.fa-thermometer-2:before, .fa-thermometer-half:before {
+    content: "\f2c9"
+}
+
+.fa-thermometer-1:before, .fa-thermometer-quarter:before {
+    content: "\f2ca"
+}
+
+.fa-thermometer-0:before, .fa-thermometer-empty:before {
+    content: "\f2cb"
+}
+
+.fa-shower:before {
+    content: "\f2cc"
+}
+
+.fa-bathtub:before, .fa-s15:before, .fa-bath:before {
+    content: "\f2cd"
+}
+
+.fa-podcast:before {
+    content: "\f2ce"
+}
+
+.fa-window-maximize:before {
+    content: "\f2d0"
+}
+
+.fa-window-minimize:before {
+    content: "\f2d1"
+}
+
+.fa-window-restore:before {
+    content: "\f2d2"
+}
+
+.fa-times-rectangle:before, .fa-window-close:before {
+    content: "\f2d3"
+}
+
+.fa-times-rectangle-o:before, .fa-window-close-o:before {
+    content: "\f2d4"
+}
+
+.fa-bandcamp:before {
+    content: "\f2d5"
+}
+
+.fa-grav:before {
+    content: "\f2d6"
+}
+
+.fa-etsy:before {
+    content: "\f2d7"
+}
+
+.fa-imdb:before {
+    content: "\f2d8"
+}
+
+.fa-ravelry:before {
+    content: "\f2d9"
+}
+
+.fa-eercast:before {
+    content: "\f2da"
+}
+
+.fa-microchip:before {
+    content: "\f2db"
+}
+
+.fa-snowflake-o:before {
+    content: "\f2dc"
+}
+
+.fa-superpowers:before {
+    content: "\f2dd"
+}
+
+.fa-wpexplorer:before {
+    content: "\f2de"
+}
+
+.fa-meetup:before {
+    content: "\f2e0"
+}
+
+.sr-only {
+    position: absolute;
+    width: 1px;
+    height: 1px;
+    padding: 0;
+    margin: -1px;
+    overflow: hidden;
+    clip: rect(0, 0, 0, 0);
+    border: 0
+}
+
+.sr-only-focusable:active, .sr-only-focusable:focus {
+    position: static;
+    width: auto;
+    height: auto;
+    margin: 0;
+    overflow: visible;
+    clip: auto
+}

+ 692 - 0
src/main/resources/static/css/mytheme-site.css

@@ -0,0 +1,692 @@
+@charset "utf-8";
+/*!
+ * 版本:MYUI Copyright © 2019
+ * 作者:QQ726662013版权所有
+ * 官网:https://www.mytheme.cn
+ */
+
+/* header */
+.myui-header__top {
+    top: 0;
+    z-index: 999;
+    width: 100%;
+    min-height: 60px;
+}
+
+.top-fixed-down {
+    margin-top: -60px;
+}
+
+/* header-logo */
+.myui-header__logo, .myui-header__menu, .myui-header__search {
+    float: left;
+}
+
+.myui-header__logo img {
+    max-width: 162px;
+}
+
+/* header-seacrh */
+.myui-header__search {
+    position: relative;
+    width: 260px;
+    margin-left: 50px;
+    margin-top: 12px;
+}
+
+.myui-header__search .form-control {
+    padding-right: 30px;
+    border-radius: 18px;
+    background-color: #f5f5f5;
+    border: 0;
+}
+
+.myui-header__search .submit {
+    display: block;
+    position: absolute;
+    top: 0;
+    right: 15px;
+    height: 32px;
+    line-height: 30px;
+    text-align: center;
+    background: none;
+    border: 0;
+    font-size: 12px;
+    cursor: pointer;
+}
+
+.myui-header__search .dropdown-box {
+    margin-left: -130px;
+}
+
+.myui-header__search .dropdown-box .item {
+    width: 260px;
+    padding: 20px;
+}
+
+.myui-header__search.search-box:hover .search-dropdown-hot {
+    display: block;
+}
+
+.myui-header__search .search-select {
+    position: absolute;
+    top: 8px;
+    left: 15px;
+    padding-right: 8px;
+    background: none;
+    box-shadow: none;
+    color: #666;
+    border-right: 1px solid #ddd;
+}
+
+.myui-header__search .search-select .dropdown-box {
+    margin-left: -40px;
+    z-index: 101;
+}
+
+.myui-header__search .search-select .dropdown-box .item {
+    width: 80px;
+    padding: 10px;
+}
+
+.myui-header__search .search-select .dropdown-box .item li {
+    text-align: center;
+    padding: 2px 0;
+}
+
+/* header-menu */
+.myui-header__menu {
+    position: relative;
+}
+
+.myui-header__menu > li {
+    position: relative;
+    float: left;
+    margin-left: 35px;
+}
+
+.myui-header__menu > li > a {
+    font-size: 14px;
+    line-height: 60px;
+}
+
+.myui-header__menu > li .dropdown-box {
+    margin-left: -250px;
+    padding-top: 0;
+}
+
+.myui-header__menu > li .dropdown-box .item {
+    width: 500px;
+}
+
+.myui-header__menu > li .dropdown-box .item li {
+    padding: 6px;
+}
+
+/* header-user */
+.myui-header__user {
+    float: right;
+}
+
+.myui-header__user > li {
+    float: left;
+    position: relative;
+    padding: 18px 0 10px;
+    margin-left: 30px;
+}
+
+.myui-header__user > li > a, .myui-header__user > li > a .fa {
+    display: inline-block;
+    font-size: 24px;
+    line-height: 24px;
+}
+
+.myui-header__user > li .dropdown-box {
+    right: 0;
+    margin-left: 0;
+    margin-right: -50px;
+    padding-top: 10px;
+}
+
+.myui-header__user > li .dropdown-box .item {
+    width: 260px;
+    padding: 20px;
+}
+
+.myui-header__user > li.menu .dropdown-box {
+    right: 0;
+    margin-left: 0;
+    margin-right: -50px;
+    padding-top: 10px;
+}
+
+.myui-header__user > li.menu .dropdown-box .item {
+    width: 120px;
+    padding: 10px;
+}
+
+.myui-header__user > li.menu .dropdown-box .item li {
+    padding: 5px 0;
+    text-align: center;
+}
+
+/* content */
+.myui-content__thumb {
+    float: left;
+}
+
+.myui-content__thumb .myui-vodlist__thumb {
+    width: 220px;
+}
+
+.myui-content__thumb.active .myui-vodlist__thumb {
+    width: 150px;
+}
+
+.myui-content__detail, .myui-content__operate {
+    float: left;
+    width: calc(100% - 220px);
+    padding-left: 20px;
+}
+
+.myui-content__detail.active {
+    width: calc(100% - 150px);
+}
+
+.myui-content__detail .title {
+    margin: 10px 0 10px;
+    font-size: 24px;
+    line-height: 30px
+}
+
+.myui-content__detail .title .score {
+    display: inline-block;
+    margin-left: 10px;
+    font-family: Georgia, "Times New Roman", Times, serif;
+}
+
+.myui-content__detail .data {
+    margin-bottom: 10px;
+    line-height: 20px;
+    word-wrap: break-word;
+    white-space: normal;
+    word-break: break-all;
+}
+
+.myui-content__detail .score {
+    margin-bottom: 20px;
+}
+
+.myui-content__detail .score .rating {
+    display: inline-block;
+    position: relative;
+    top: 5px;
+}
+
+.myui-content__detail .score .rating li {
+    cursor: pointer;
+    display: inline-block;
+    margin-right: 5px;
+}
+
+.myui-content__detail .score .rating li .fa {
+    font-size: 24px;
+}
+
+.myui-content__detail .score .branch {
+    display: inline-block;
+    font-family: Georgia, "Times New Roman", Times, serif;
+    font-size: 24px;
+    line-height: 24px;
+}
+
+.myui-content__operate {
+    float: left;
+    margin-top: 20px
+}
+
+.myui-content__operate .btn {
+    margin-left: 10px;
+    margin-bottom: 10px;
+}
+
+.myui-content__operate .btn:first-child {
+    margin-left: 0;
+}
+
+.myui-content__operate .share {
+    margin-top: 5px
+}
+
+.myui-content__tag a {
+    display: inline-block;
+    line-height: 20px;
+    padding: 2px 10px;
+    margin-left: 5px;
+    border: 1px solid rgba(0, 0, 0, .1);
+    font-size: 12px;
+    border-radius: 15px;
+}
+
+/* player */
+.myui-player {
+    margin-bottom: 50px;
+    padding-bottom: 15px;
+    padding-top: 50px;
+}
+
+.myui-player__item {
+    position: relative;
+}
+
+.myui-player__item .fixed {
+    position: fixed;
+    z-index: 998;
+    right: 0;
+    bottom: 0;
+    padding: 10px;
+    background-color: #fff;
+    box-shadow: 0 2px 5px rgba(0, 0, 0, .1);
+}
+
+.myui-player__item .tips {
+    position: relative;
+    height: 40px;
+    line-height: 40px;
+    overflow: hidden;
+    padding: 0 20px;
+    color: #fff;
+}
+
+.myui-player__item .is-btn {
+    position: absolute;
+    z-index: 99;
+    top: 50%;
+    right: -12px;
+    margin-top: -30px;
+    display: block;
+    width: 12px;
+    text-align: center;
+    height: 60px;
+    line-height: 60px;
+    font-size: 10px;
+    border-radius: 0 4px 4px 0;
+    background-color: #404040;
+    color: #999;
+}
+
+.myui-player__item .player-fixed-off {
+    display: none;
+    position: absolute;
+    top: -10px;
+    left: -10px;
+    width: 20px;
+    height: 20px;
+    text-align: center;
+    line-height: 20px;
+    background-color: #fff;
+    border-radius: 50%;
+    color: #333;
+    box-shadow: 0 2px 5px rgba(0, 0, 0, .1);
+}
+
+.myui-player__data {
+    padding: 20px 0 10px;
+}
+
+.myui-player__data .title {
+    font-size: 24px;
+}
+
+.myui-player__operate {
+    padding: 20px 10px;
+    display: -webkit-box;
+    display: -webkit-flex;
+    display: flex;
+}
+
+.myui-player__operate li {
+    display: block;
+    text-align: center;
+    -webkit-box-flex: 1;
+    -webkit-flex: 1;
+    flex: 1;
+}
+
+.myui-player__operate li.playshare .dropdown-box {
+    margin-left: -130px;
+}
+
+.myui-player__detail .title {
+    margin: 0 0 10px
+}
+
+.myui-player__detail .detail-content {
+    padding-top: 10px
+}
+
+.myui-player__detail .desc {
+    padding-left: 42px
+}
+
+.myui-player__detail .desc .left {
+    margin-left: -42px
+}
+
+#player-sidebar::-webkit-scrollbar {
+    width: 4px;
+    background-color: #1c1b1e;
+}
+
+#player-sidebar::-webkit-scrollbar-thumb {
+    background-color: #434145;
+}
+
+.myui-player__notice {
+    position: absolute;
+    top: 50%;
+    left: 0;
+    width: 100%;
+    margin-top: -65px;
+}
+
+.myui-player__notice h3, .myui-player__notice h5, .myui-player__notice p {
+    color: #fff;
+}
+
+.myui-player-links {
+    position: relative;
+    top: 15px;
+    right: 10px;
+}
+
+.myui-player-links .btn {
+    position: absolute;
+    top: 0;
+    right: -5px;
+    border-radius: 0 5px 5px 0;
+}
+
+/* news */
+.myui-newslist li {
+    padding: 30px 0;
+}
+
+.myui-newslist li .title {
+    margin: 0;
+    font-size: 22px;
+    line-height: 30px;
+    font-weight: 600;
+}
+
+.myui-newslist li .desc {
+    text-indent: 2em;
+    margin: 0;
+    padding: 20px 0;
+    line-height: 25px;
+}
+
+.myui-newslist__text li .title {
+    margin: 0;
+    font-size: 15px;
+}
+
+.myui-art__nav li {
+    padding: 6px 0;
+}
+
+.myui-art__nav li.active a {
+    font-weight: bold;
+    color: #ff9900;
+}
+
+/* footer */
+.myui-foot {
+    padding: 20px 0;
+}
+
+.myui-foot p {
+    line-height: 25px;
+}
+
+@media (max-width: 1500px) {
+
+    /* header */
+    .myui-header__top {
+        padding: 0 20px;
+    }
+
+    .myui-header__search {
+        width: 200px;
+        margin-left: 20px;
+    }
+
+    .myui-header__menu > li {
+        margin-left: 20px;
+    }
+
+    .myui-header__user > li {
+        margin-left: 20px;
+    }
+
+    .myui-header__menu > li:hover .head-dropdown, .myui-header__user > li:hover .head-dropdown {
+        display: none;
+    }
+
+}
+
+@media (max-width: 1024px) {
+    .myui-content__thumb .myui-vodlist__thumb {
+        width: 200px;
+    }
+
+    .myui-content__detail {
+        float: left;
+        width: calc(100% - 200px);
+    }
+}
+
+@media (max-width: 767px) {
+
+    .myui-panel.myui-panel-bg2 {
+        border-radius: 0;
+    }
+
+    .myui-panel-bg, .myui-vodlist__bg, .myui-vodlist__bg:hover {
+        box-shadow: none;
+    }
+
+    .myui-panel__head .title, .myui-panel__head .title a {
+        font-size: 18px;
+    }
+
+    /* header */
+    .myui-header__logo img {
+        max-width: 120px;
+    }
+
+    .myui-header__top {
+        padding: 0 10px;
+    }
+
+    .myui-header__search {
+        position: absolute;
+        top: -100%;
+        left: 10px;
+        right: 10px;
+        margin-left: 0;
+        width: auto;
+        padding-right: 30px;
+    }
+
+    .myui-header__search .form-control {
+        height: 32px;
+        padding: 0 10px;
+        border-radius: 16px;
+    }
+
+    .myui-header__search .submit {
+        right: 30px;
+        width: 32px;
+        height: 32px;
+        line-height: 30px;
+    }
+
+    .myui-header__search .search-close {
+        position: absolute;
+        top: 6px;
+        right: 0;
+    }
+
+    .myui-header__menu > li .dropdown-box {
+        margin-left: -150px;
+        padding-top: 0;
+    }
+
+    .myui-header__menu > li .dropdown-box .item {
+        width: 300px;
+    }
+
+    .myui-header__user > li {
+        margin-left: 15px;
+        padding: 15px 0 10px;
+    }
+
+    .myui-header__user > li > a .fa {
+        font-size: 20px;
+        line-height: 20px;
+    }
+
+    .myui-header__user > li.menu .dropdown-box, .myui-header__user > li .dropdown-box {
+        margin-right: 0;
+    }
+
+    /* content */
+    .myui-content__thumb .myui-vodlist__thumb {
+        width: 120px;
+    }
+
+    .myui-content__thumb.active .myui-vodlist__thumb {
+        width: 120px;
+    }
+
+    .myui-content__detail {
+        float: left;
+        width: calc(100% - 120px);
+    }
+
+    .myui-content__detail.active {
+        width: calc(100% - 120px);
+    }
+
+    .myui-content__detail .title {
+        margin: 5px 0 8px;
+        font-size: 18px;
+        line-height: 24px
+    }
+
+    .myui-content__detail .data {
+        margin: 0 0 10px;
+        font-size: 12px;
+        line-height: 18px;
+        word-wrap: break-word;
+        white-space: normal;
+    }
+
+    .myui-content__detail .score {
+        margin-bottom: 5px;
+    }
+
+    .myui-content__detail .score .branch {
+        font-size: 16px;
+    }
+
+    .myui-content__detail .score .rating {
+        top: 0;
+    }
+
+    .myui-content__detail .score .rating li {
+        margin: 0;
+    }
+
+    .myui-content__detail .score .rating li .fa {
+        font-size: 18px;
+    }
+
+    .myui-content__operate {
+        width: 100%;
+        padding: 0;
+        display: -webkit-box;
+        display: -webkit-flex;
+        display: flex;
+    }
+
+    .myui-content__operate .btn {
+        text-align: center;
+        padding: 8px;
+        -webkit-box-flex: 1;
+        -webkit-flex: 1;
+        flex: 1;
+    }
+
+    /* player */
+    .myui-player {
+        padding-top: 0;
+    }
+
+    .myui-player__item {
+        padding: 0;
+    }
+
+    .myui-player__detail {
+        margin: 0;
+    }
+
+    .myui-player__detail .data .title {
+        font-size: 16px
+    }
+
+    .myui-player__detail.detail .title {
+        font-size: 18px;
+    }
+
+    .myui-player__operate li {
+        margin: 0;
+        display: block;
+        text-align: center;
+    }
+
+    .myui-player__operate li .fa {
+        display: block;
+        margin-bottom: 5px;
+        font-size: 16px;
+    }
+
+    .myui-player__operate li.playshare .dropdown-box {
+        margin-left: -180px;
+    }
+
+    .myui-player-links {
+        top: 0;
+        right: 0;
+        padding: 0 10px;
+    }
+
+    .myui-player-links .btn {
+        height: 35px;
+        right: 8px;
+    }
+
+    /* news */
+    .myui-newslist li .title {
+        font-size: 18px;
+        line-height: 30px;
+    }
+
+    .myui-art__nav li a {
+        display: block;
+        padding: 0 10px;
+        white-space: nowrap;
+    }
+
+}

+ 2929 - 0
src/main/resources/static/css/mytheme-ui.css

@@ -0,0 +1,2929 @@
+@charset "utf-8";
+/*!
+ * 版本:MYUI Copyright © 2019
+ * 作者:QQ726662013版权所有
+ * 官网:https://www.mytheme.cn
+ */
+
+
+/* body */
+body, html {
+    width: 100%;
+}
+
+body {
+    font-size: 14px;
+    line-height: 140%;
+    -webkit-overflow-scrolling: touch;
+    -webkit-transition: .5s;
+    -o-transition: .5s;
+    -moz-transition: .5s;
+    -ms-transition: .5s;
+    transition: .5s;
+}
+
+body, ul, ol, li, p, h1, h2, h3, h4, h5, h6, form, fieldset, table, td, img, div, tr {
+    margin: 0;
+    padding: 0;
+    font-weight: normal
+}
+
+input, select {
+    font-size: 12px;
+    vertical-align: middle;
+    border: none;
+}
+
+ul, li {
+    list-style-type: none;
+}
+
+img {
+    border: 0 none;
+}
+
+p {
+    margin-bottom: 10px;
+}
+
+/* container */
+* {
+    margin: 0;
+    padding: 0;
+    -webkit-box-sizing: border-box;
+    -moz-box-sizing: border-box;
+    box-sizing: border-box
+}
+
+:after, :before {
+    -webkit-box-sizing: border-box;
+    -moz-box-sizing: border-box;
+    box-sizing: border-box
+}
+
+.container {
+    position: relative;
+    margin-right: auto;
+    margin-left: auto;
+}
+
+.row {
+    position: relative;
+    margin: 0;
+    padding: 0;
+}
+
+.container:before, .container:after, .row:before, .row:after, .clearfix:before, .clearfix:after {
+    display: table;
+    content: " ";
+    clear: both;
+}
+
+/* text */
+h1 {
+    font-size: 36px;
+}
+
+h2 {
+    font-size: 32px;
+}
+
+h3 {
+    font-size: 24px;
+}
+
+h4 {
+    font-size: 18px;
+}
+
+h5 {
+    font-size: 16px;
+}
+
+h6 {
+    font-size: 14px;
+}
+
+h1, h2, h3, h4, h5, h6 {
+    font-weight: 400;
+    margin-bottom: 10px
+}
+
+a, button {
+    text-decoration: none;
+    outline: none;
+    -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+
+button {
+    border: 0;
+}
+
+button:hover, input.btn {
+    cursor: pointer;
+}
+
+a:focus, a:hover, a:active {
+    text-decoration: none;
+}
+
+.text-center {
+    text-align: center;
+}
+
+.text-left {
+    text-align: left;
+}
+
+.text-right {
+    text-align: right;
+}
+
+.text-overflow {
+    width: 100%;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    -o-text-overflow: ellipsis;
+    white-space: nowrap;
+}
+
+.content {
+    font-size: 16px;
+    line-height: 30px;
+    word-wrap: break-word;
+    white-space: normal;
+    word-break: break-all;
+}
+
+/* font */
+.font-12 {
+    font-size: 12px;
+}
+
+.font-13 {
+    font-size: 13px;
+}
+
+.font-14 {
+    font-size: 14px;
+}
+
+.font-15 {
+    font-size: 15px;
+}
+
+.font-16 {
+    font-size: 16px;
+}
+
+.font-18 {
+    font-size: 18px;
+}
+
+.font-20 {
+    font-size: 20px;
+}
+
+.font-22 {
+    font-size: 22px;
+}
+
+.font-24 {
+    font-size: 24px;
+}
+
+.font-25 {
+    font-size: 24px;
+}
+
+.font-40 {
+    font-size: 40px;
+}
+
+.font-bold {
+    font-weight: 700;
+}
+
+/* img */
+img {
+    border: 0;
+    vertical-align: middle
+}
+
+.img-circle {
+    border-radius: 50%;
+}
+
+.img-rounded {
+    border-radius: 5px;
+}
+
+.img-thumbnail {
+    padding: 5px;
+    border-radius: 5px;
+}
+
+.img-responsive {
+    max-width: 100%;
+}
+
+.img-thumb {
+    width: 220px;
+}
+
+.content img {
+    display: block;
+    max-width: 100%;
+}
+
+/* form */
+select {
+    cursor: pointer;
+    border: none;
+    outline: none;
+}
+
+input, textarea {
+    outline: medium none;
+    outline: none;
+    -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+
+input.form-control, input.btn {
+    outline: 0px;
+    -webkit-appearance: none;
+}
+
+input[type="checkbox"] {
+    vertical-align: -2px;
+}
+
+.form-control {
+    display: block;
+    width: 100%;
+    height: 35px;
+    padding: 0 10px;
+    font-size: 12px;
+    line-height: 20px;
+    border-radius: 4px;
+    transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+}
+
+textarea.form-control {
+    height: auto;
+    padding: 10px;
+}
+
+.form-control.verify {
+    width: 90px;
+    text-align: center;
+    margin-right: 10px;
+    display: inline-block;
+}
+
+/* padding */
+.pb10 {
+    padding-bottom: 10px;
+}
+
+.pt10 {
+    padding-top: 10px;
+}
+
+.pb15 {
+    padding-bottom: 15px;
+}
+
+.pt15 {
+    padding-top: 15px;
+}
+
+.pb20 {
+    padding-bottom: 20px;
+}
+
+.pt20 {
+    padding-top: 20px;
+}
+
+.pb30 {
+    padding-bottom: 30px;
+}
+
+.pt30 {
+    padding-top: 30px;
+}
+
+/* padding */
+.mb10 {
+    margin-bottom: 10px;
+}
+
+.mt10 {
+    margin-top: 10px;
+}
+
+.mb15 {
+    margin-bottom: 15px;
+}
+
+.mt15 {
+    margin-top: 15px;
+}
+
+.mb20 {
+    margin-bottom: 20px;
+}
+
+.mt20 {
+    margin-top: 20px;
+}
+
+.mb30 {
+    margin-bottom: 30px;
+}
+
+.mt30 {
+    margin-top: 30px;
+}
+
+/* line */
+.spot {
+    display: inline-block;
+    margin-right: 5px;
+    width: 8px;
+    height: 8px;
+    background-color: #fff;
+    border-radius: 50%;
+    border: 2px solid;
+}
+
+.split-line {
+    display: inline-block;
+    margin-left: 12px;
+    margin-right: 12px;
+    width: 1px;
+    height: 14px;
+    vertical-align: -2px;
+}
+
+.top-line, .top-line-dot, .bottom-line, .bottom-line-dot {
+    position: relative;
+}
+
+.top-line:before, .top-line-dot:before {
+    content: " ";
+    position: absolute;
+    left: 0;
+    top: 0;
+    right: 0;
+    width: 100%;
+    height: 1px;
+}
+
+.bottom-line:after, .bottom-line-dot:before {
+    content: " ";
+    position: absolute;
+    left: 0;
+    bottom: 0;
+    right: 0;
+    width: 100%;
+    height: 1px;
+}
+
+.top-line:before {
+    border-top: 1px solid;
+}
+
+.bottom-line:after {
+    border-bottom: 1px solid;
+}
+
+.top-line-dot:before {
+    border-top: 1px dotted;
+}
+
+.bottom-line-dot:before {
+    border-bottom: 1px dotted;
+}
+
+/* border */
+.border {
+    border: 1px solid;
+}
+
+.border-2x {
+    border: 2px solid;
+}
+
+.border-3x {
+    border: 3px solid;
+}
+
+.border-4x {
+    border: 4px solid;
+}
+
+.border-5x {
+    border: 5px solid;
+}
+
+/* badge */
+.badge {
+    display: inline-block;
+    margin-right: 10px;
+    width: 18px;
+    height: 18px;
+    text-align: center;
+    line-height: 18px;
+    border-radius: 2px;
+    font-size: 12px;
+}
+
+.badge-radius {
+    border-radius: 50%;
+}
+
+/* btn */
+.btn {
+    display: inline-block;
+    padding: 8px 30px;
+    font-size: 12px;
+}
+
+.btn.btn-xs {
+    padding: 4px 15px;
+}
+
+.btn.btn-sm {
+    padding: 6px 20px;
+}
+
+.btn.btn-md {
+    padding: 8px 25px;
+}
+
+.btn.btn-lg {
+    padding: 12px 30px;
+}
+
+.btn.btn-block {
+    display: block;
+    width: 100%;
+    padding-left: 5px;
+    padding-right: 5px;
+    text-align: center;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    -o-text-overflow: ellipsis;
+    white-space: nowrap;
+}
+
+.btn.disabled {
+    cursor: not-allowed;
+}
+
+/* nav */
+.nav {
+    position: relative;
+}
+
+.nav > li {
+    float: left;
+}
+
+.nav-head > li, .nav-tabs > li {
+    margin-top: 10px;
+    margin-left: 30px;
+}
+
+.nav-head > li > a {
+    padding-bottom: 8px;
+    font-size: 16px;
+}
+
+.nav-tabs > li > a {
+    padding-bottom: 10px;
+}
+
+.nav-tabs > li.active > a {
+    border-bottom: 2px solid;
+}
+
+.nav-tabs > li .dropdown-box {
+    margin-left: -50px;
+    padding-top: 0;
+}
+
+.nav-tabs > li .dropdown-box .item {
+    width: 100px;
+    text-align: center;
+}
+
+.nav-tabs > li .dropdown-box .item li {
+    padding: 5px;
+}
+
+.nav-tag > li {
+    margin-left: 10px;
+}
+
+.nav-tag > li > a {
+    display: inline-block;
+    padding: 0 10px;
+    height: 25px;
+    line-height: 23px;
+    font-size: 14px;
+    border-radius: 20px;
+}
+
+.nav-text > li {
+    line-height: 30px;
+}
+
+.nav-text > li.active > a {
+    color: #f80;
+}
+
+.nav-page {
+    margin-left: 10px;
+}
+
+.nav-page > li {
+    margin-left: 5px;
+}
+
+.nav-page > li > a {
+    display: inline-block;
+    font-size: 14px;
+    padding: 0 6px;
+    height: 25px;
+    line-height: 23px;
+}
+
+.nav-page > li:first-child {
+    margin-left: 0;
+}
+
+.nav-page > li:first-child > a {
+    border-radius: 4px 0 0 4px;
+}
+
+.nav-page > li:last-child > a {
+    border-radius: 0 4px 4px 0;
+}
+
+.nav-btn > li {
+    margin-right: 15px;
+    margin-bottom: 15px;
+}
+
+.nav-btn > li a {
+    padding: 8px 12px;
+    border-radius: 5px;
+}
+
+/* pic-tag */
+.pic-tag {
+    display: block;
+    position: absolute;
+    padding: 2px 0;
+    width: 100%;
+    z-index: 99;
+}
+
+.pic-tag-top {
+    top: 5px;
+    left: 5px;
+}
+
+.pic-tag-left {
+    bottom: 5px;
+    left: 5px;
+}
+
+.pic-tag-bottom {
+    bottom: 5px;
+    right: 5px;
+    text-align: right;
+}
+
+.pic-tag-right {
+    top: 5px;
+    right: 5px;
+    text-align: right;
+}
+
+.pic-tag-h {
+    left: 0;
+    top: 0;
+    padding: 2px 8px;
+    border-radius: 0 0 8px 0;
+}
+
+.pic-tag-lg {
+    padding: 4px 10px;
+}
+
+.pic-tag .tag {
+    display: inline-block;
+    margin: 0 4px;
+    padding: 0 5px;
+    font-size: 12px;
+    border-radius: 2px;
+}
+
+.pic-text {
+    display: block;
+    width: 100%;
+    position: absolute;
+    z-index: 98;
+    bottom: 0;
+    left: 0;
+    padding: 5px 10px;
+    font-size: 12px;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    -o-text-overflow: ellipsis;
+    white-space: nowrap;
+}
+
+.pic-text-silde {
+    padding-bottom: 20px;
+    font-size: 14px;
+}
+
+.pic-text-lg {
+    padding: 8px 20px;
+    font-size: 14px;
+}
+
+.pic-title-top {
+    display: block;
+    width: 100%;
+    position: absolute;
+    top: 0;
+    left: 0;
+    padding: 5px 10px 10px;
+    font-size: 12px;
+    word-break: break-all;
+    display: -webkit-box;
+    -webkit-line-clamp: 2;
+    -webkit-box-orient: vertical;
+    overflow: hidden;
+}
+
+.pic-title-bottom {
+    display: block;
+    width: 100%;
+    position: absolute;
+    bottom: 0;
+    left: 0;
+    padding: 5px 10px;
+    font-size: 12px;
+    word-break: break-all;
+    display: -webkit-box;
+    -webkit-line-clamp: 2;
+    -webkit-box-orient: vertical;
+    overflow: hidden;
+}
+
+/* qrcode */
+.qrcode-box {
+    display: inline-block;
+    position: relative;
+    margin-bottom: 10px;
+}
+
+.qrcode-box .icon {
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    margin-top: -12.5px;
+    margin-left: -12.5px;
+    border-radius: 2px;
+    background-color: #fff;
+    box-shadow: 0 1px 2px rgba(0, 0, 0, .1);
+}
+
+/* dropdown */
+.dropdown {
+    position: relative;
+}
+
+.dropdown-box {
+    display: none;
+    position: absolute;
+    z-index: 99;
+}
+
+.dropdown-box.top {
+    bottom: 100%;
+    padding-bottom: 10px;
+    left: 50%;
+    margin-left: -80px;
+}
+
+.dropdown-box.bottom {
+    top: 100%;
+    padding-top: 10px;
+    left: 50%;
+    margin-left: -80px;
+}
+
+.dropdown-box.left {
+    left: 100%;
+    padding-left: 10px;
+    bottom: 0;
+}
+
+.dropdown-box.right {
+    right: 100%;
+    padding-right: 10px;
+    bottom: 0;
+}
+
+.dropdown-box .item {
+    padding: 10px;
+    width: 160px;
+    border-radius: 2px;
+}
+
+.dropdown-hover {
+    position: relative;
+}
+
+.dropdown-hover:hover .dropdown-box {
+    display: block;
+}
+
+.open > .dropdown-box {
+    display: block;
+}
+
+/* layout */
+.myui-layout {
+    position: relative;
+}
+
+/* panel */
+.myui-panel {
+    position: relative;
+}
+
+.myui-panel-box.active {
+    padding: 0;
+}
+
+/* panel-head */
+.myui-panel__head {
+    position: relative;
+    height: 30px;
+}
+
+.myui-panel__head .title {
+    float: left;
+    display: inline-block;
+    margin: 0;
+    padding-right: 10px;
+    line-height: 30px;
+}
+
+.myui-panel__head .title img {
+    display: inline-block;
+    width: 24px;
+    height: 24px;
+    margin-right: 10px;
+    vertical-align: -5px;
+}
+
+.myui-panel__head .title, .myui-panel__head .title a {
+    font-size: 24px;
+}
+
+.myui-panel__head .more {
+    line-height: 30px;
+}
+
+.myui-panel__head .operate {
+    position: relative;
+    padding-bottom: 5px;
+}
+
+.myui-panel__head .operate.open .dropdown-menu {
+    display: block;
+}
+
+.myui-panel__head.active {
+    height: 42px;
+}
+
+/* vod-list */
+.myui-vodlist__thumb {
+    display: block;
+    position: relative;
+    background-position: 50% 50% !important;
+    background-size: cover !important;
+    overflow: hidden;
+    box-shadow: 0 1px 2px rgba(0, 0, 0, .1);
+}
+
+.myui-vodlist__thumb.picture {
+    background: none;
+    overflow: hidden;
+}
+
+.myui-vodlist__thumb.picture img {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+}
+
+.myui-vodlist__thumb .play {
+    opacity: 0;
+    position: absolute;
+    top: 0;
+    z-index: 1;
+    width: 100%;
+    height: 100%;
+    background: rgba(0, 0, 0, 0.2) url(../cover/play.png) center no-repeat;
+    background-color: rgba(0, 0, 0, .2);
+    -webkit-transition: all ease-out .35s;
+    transition: all ease-out .35s;
+}
+
+.myui-vodlist__thumb .play-v {
+    opacity: 0;
+    position: absolute;
+    top: 0;
+    z-index: 1;
+    width: 100%;
+    height: 100%;
+    background-color: rgba(0, 0, 0, .2);
+    -webkit-transition: all ease-out .35s;
+    transition: all ease-out .35s;
+}
+
+.myui-vodlist__thumb .play.active {
+    opacity: 1;
+}
+
+.myui-vodlist__thumb:hover .play, .myui-vodlist__thumb:hover .play-v {
+    opacity: 1;
+}
+
+.myui-vodlist__detail.active {
+    padding: 0 10px 10px;
+}
+
+.myui-vodlist__detail .title {
+    margin: 10px 0 0;
+    font-size: 14px;
+}
+
+.myui-vodlist__detail .title.active {
+    font-size: 16px;
+    margin-bottom: 10px;
+}
+
+.myui-vodlist__detail .text {
+    min-height: 19px;
+    font-size: 12px;
+    margin-bottom: 0;
+    margin-top: 5px;
+}
+
+.myui-vodlist__detail .text-title {
+    font-size: 14px;
+    line-height: 18px;
+    margin: 11px 0 0;
+    height: 36px;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    display: -webkit-box;
+    -webkit-box-orient: vertical;
+    -webkit-line-clamp: 2;
+}
+
+/* text-list */
+.myui-vodlist__text li a {
+    display: block;
+}
+
+.myui-vodlist__text.active li a {
+    padding: 0 0 15px;
+}
+
+.myui-vodlist__text.active li:first-child a {
+    padding-top: 0;
+}
+
+.myui-vodlist__text.striped li {
+    padding: 10px 0 10px;
+}
+
+.myui-vodlist__text.striped li a {
+    display: inline-block;
+    padding: 0;
+}
+
+.myui-vodlist__text.striped .striped-head {
+    padding: 10px;
+    border-radius: 5px;
+}
+
+.myui-vodlist__text .striped-head {
+    font-weight: 700;
+}
+
+.myui-vodlist__text.to-color li {
+    padding: 10px;
+    border-radius: 5px;
+}
+
+.myui-vodlist__text.to-color li a {
+    padding: 0;
+}
+
+.myui-vodlist__text.downlist {
+    padding-top: 0;
+}
+
+.myui-vodlist__text.downlist li {
+    padding: 10px 0;
+}
+
+.myui-vodlist__text.downlist li .text {
+    line-height: 30px;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    -o-text-overflow: ellipsis;
+    white-space: nowrap;
+}
+
+.myui-vodlist__text.downlist li a {
+    display: inline-block;
+    padding: 0;
+}
+
+.myui-vodlist__text.downlist li a.btn {
+    padding: 4px 12px;
+    margin-left: 10px;
+}
+
+/* media-list */
+.myui-vodlist__media li:first-child {
+    padding-top: 0;
+}
+
+.myui-vodlist__media li:last-child {
+    padding-bottom: 0;
+}
+
+.myui-vodlist__media .thumb, .myui-vodlist__media .detail {
+    display: table-cell;
+    vertical-align: top;
+}
+
+.myui-vodlist__media .detail {
+    width: 100%;
+    padding: 0 0 0 20px;
+}
+
+.myui-vodlist__media .detail .desc {
+    height: 40px;
+}
+
+.myui-vodlist__media .detail-side {
+    padding: 0 10px 0;
+}
+
+.myui-vodlist__media .detail-left {
+    padding: 0 20px 0 0;
+}
+
+.myui-vodlist__media .detail h4.title {
+    margin: 10px 0 10px;
+    font-size: 18px;
+    line-height: 25px;
+}
+
+.myui-vodlist__media .detail h5.title {
+    font-size: 15px;
+    height: 38px;
+    line-height: 20px;
+}
+
+/* screen-list */
+.myui-vodlist__screen {
+    padding: 10px 0 5px;
+}
+
+.myui-vodlist__screen:first-child {
+    padding-top: 0;
+}
+
+.myui-vodlist__screen:last-child {
+    padding-bottom: 0;
+}
+
+.myui-vodlist__screen li {
+    float: left;
+    width: 25%;
+    margin-bottom: 5px;
+}
+
+/* rank-list */
+.myui-vodlist__rank li {
+    margin-bottom: 10px;
+}
+
+.myui-vodlist__rank li:last-child {
+    margin-bottom: 0;
+}
+
+/* link-list */
+.myui-link__text li {
+    float: left;
+    margin-right: 15px;
+    margin-bottom: 10px;
+}
+
+/* play-list */
+.myui-content__list {
+    position: relative;
+}
+
+.myui-content__list li {
+    float: left;
+    padding: 10px;
+}
+
+.myui-content__list li a {
+    display: block;
+    padding: 8px;
+    text-align: center;
+    width: 100%;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    -o-text-overflow: ellipsis;
+    white-space: nowrap;
+}
+
+.myui-play__list li {
+    float: left;
+}
+
+.myui-play__list li a {
+    display: block;
+    padding: 8px 0;
+    text-align: center;
+}
+
+/* down-list */
+.myui-down__list li {
+    padding: 10px;
+}
+
+.myui-down__list li:first-child {
+    margin-top: -20px;
+}
+
+.myui-down__list li .text {
+    line-height: 30px;
+}
+
+.myui-down__list li .operate {
+    float: right;
+}
+
+.myui-down__list li .operate .btn {
+    display: inline-block;
+    margin-left: 5px;
+    padding: 5px 10px;
+}
+
+.myui-down__list li .operate .btn:hover {
+    opacity: 0.8;
+}
+
+.myui-down__list li .operate .btn img {
+    vertical-align: -1px;
+}
+
+.myui-down__list li .operate .thunder {
+    background-color: #11a5e8;
+    border-color: #11a5e8;
+    color: #fff;
+}
+
+.myui-down__list li .operate .bendi {
+    background-color: #009966;
+    border-color: #009966;
+    color: #fff;
+}
+
+.myui-down__list li .operate .copy {
+    background-color: #ff9900;
+    border-color: #ff9900;
+    color: #fff;
+}
+
+.myui-down__list li .operate .xiaomi {
+    background-color: #FF5722;
+    border-color: #FF5722;
+    color: #fff;
+}
+
+.myui-down__list li .operate .thunderkk {
+    background-color: #009688;
+    border-color: #009688;
+    color: #fff;
+}
+
+/* article */
+.myui-article__title {
+    margin: 0 0 10px;
+    font-size: 24px;
+    line-height: 30px;
+    font-weight: 700;
+}
+
+.myui-article__sub {
+    margin-bottom: 10px;
+    padding-bottom: 10px;
+}
+
+.myui-article__content {
+    line-height: 30px;
+    font-size: 16px;
+}
+
+.myui-article__content img {
+    display: block;
+    max-width: 100%;
+}
+
+/* screen */
+.myui-screen__list {
+    position: relative;
+}
+
+.myui-screen__list li {
+    float: left;
+}
+
+.myui-screen__list li a.btn {
+    padding: 5px 12px;
+    font-size: 14px;
+}
+
+/* table */
+.myui-table {
+    position: relative;
+    width: 100%;
+    max-width: 100%;
+    border-spacing: 0;
+    border-collapse: collapse;
+}
+
+.myui-table > thead > tr > th {
+    vertical-align: bottom;
+    border-bottom: 2px solid;
+}
+
+.myui-table > tbody > tr > td, .myui-table > tbody > tr > th, .myui-table > tfoot > tr > td, .myui-table > tfoot > tr > th, .myui-table > thead > tr > td, .myui-table > thead > tr > th {
+    padding: 8px;
+    line-height: 25px;
+    vertical-align: top;
+    border-bottom: 1px solid;
+}
+
+/* message */
+.styu-message__list {
+    position: relative;
+    padding: 20px 0;
+}
+
+.styu-message__list .avatar {
+    float: left;
+    width: 60px;
+}
+
+.styu-message__list .data {
+    margin-left: 60px;
+}
+
+.styu-message__list .data .name {
+    margin: 0;
+    font-size: 16px;
+}
+
+.styu-message__list .data .content {
+    padding: 5px 0;
+    line-height: 20px;
+    word-wrap: break-word;
+    white-space: normal;
+}
+
+.styu-message__list .data .admin, .styu-message__list .data .content {
+    margin: 0;
+    font-size: 14px;
+}
+
+.styu-message__list.child {
+    margin-top: 20px;
+    padding-bottom: 0;
+}
+
+/* msg */
+.myui-msg__form {
+    max-width: 320px;
+    margin: 0 auto;
+    padding: 50px;
+    box-shadow: 0 2px 5px rgba(0, 0, 0, .1);
+}
+
+.myui-msg__head {
+    margin-bottom: 20px;
+}
+
+.myui-msg__head .fa {
+    margin-bottom: 20px;
+    font-size: 80px;
+    color: red;
+}
+
+/* page */
+.myui-page {
+    margin-bottom: 30px
+}
+
+.myui-page li {
+    display: inline-block;
+    margin-left: 10px
+}
+
+.myui-page li .num, .myui-page li a {
+    padding: 5px 15px;
+}
+
+/* extra */
+.myui-extra {
+    position: fixed;
+    z-index: 999;
+    right: 50px;
+    bottom: 50px
+}
+
+.myui-extra li {
+    position: relative;
+    padding: 15px 10px 0
+}
+
+.myui-extra li a {
+    display: block;
+    width: 50px;
+    height: 50px;
+    line-height: 50px;
+    text-align: center;
+    border-radius: 4px;
+    font-size: 18px;
+    cursor: pointer;
+}
+
+/* flickity */
+.flickity {
+    position: relative;
+    white-space: nowrap;
+    overflow: hidden;
+}
+
+.flickity [class^="col-"] {
+    float: none !important;
+    display: inline-block !important;
+}
+
+.flickity.dots {
+    padding-bottom: 20px;
+}
+
+.flickity-enabled {
+    position: relative;
+}
+
+.flickity-enabled:focus {
+    outline: 0
+}
+
+.flickity-viewport {
+    position: relative;
+    overflow: hidden;
+    height: 100%
+}
+
+.flickity-slider {
+    position: absolute;
+    width: 100%;
+    height: 100%
+}
+
+/*.flickity-viewport.is-pointer-down {*/
+/*    cursor: -webkit-grabbing;*/
+/*    cursor: grabbing*/
+/*}*/
+
+.flickity-prev-next-button {
+    opacity: 0;
+    position: absolute;
+    top: 50%;
+    width: 25px;
+    height: 50px;
+    border: none;
+    background-color: rgba(0, 0, 0, .6);
+    cursor: pointer;
+    -webkit-transform: translateY(-50%);
+    -ms-transform: translateY(-50%);
+    transform: translateY(-50%);
+    -webkit-transition: all ease-out .35s;
+    transition: all ease-out .35s;
+}
+
+.flickity-prev-next-button.previous {
+    left: 0;
+    border-radius: 0 6px 6px 0
+}
+
+.flickity-prev-next-button.next {
+    right: 0;
+    border-radius: 6px 0 0 6px
+}
+
+.flickity-prev-next-button:disabled {
+    opacity: 0;
+    cursor: auto
+}
+
+.flickity-prev-next-button svg {
+    position: absolute;
+    left: 20%;
+    top: 20%;
+    width: 60%;
+    height: 60%;
+}
+
+.flickity-prev-next-button .arrow {
+    fill: #fff
+}
+
+.flickity-prev-next-button.no-svg {
+    color: #fff;
+    font-size: 18px
+}
+
+.flickity-page-dots {
+    position: relative;
+    text-align: center;
+}
+
+.flickity-page-dots .dot {
+    display: inline-block;
+    width: 15px;
+    height: 3px;
+    margin: 0 5px;
+    opacity: .25;
+    cursor: pointer
+}
+
+.flickity-page-dots .dot.is-selected {
+    opacity: 1
+}
+
+.flickity:hover .flickity-prev-next-button {
+    opacity: 1;
+}
+
+.flickity.active .flickity-prev-next-button {
+    margin-top: -25px;
+}
+
+.flickity.center .flickity-prev-next-button.previous {
+    left: 0;
+}
+
+.flickity.center .flickity-prev-next-button.next {
+    right: 0;
+}
+
+/* slide */
+.carousel {
+    position: relative;
+}
+
+.carousel-control {
+    position: absolute;
+    z-index: 99;
+    top: 0;
+    bottom: 0;
+    display: block;
+    width: 50px;
+    height: 100%;
+}
+
+.carousel-control.left {
+    left: 30px;
+}
+
+.carousel-control.right {
+    right: 30px;
+}
+
+.carousel-control .fa {
+    position: absolute;
+    top: 50%;
+    margin-top: -25px;
+    display: block;
+    width: 50px;
+    height: 50px;
+    text-align: center;
+    font-size: 30px;
+    line-height: 50px;
+    background-color: rgba(0, 0, 0, 0.6);
+    color: #fff;
+    border-radius: 50%;
+    opacity: 0.5;
+}
+
+.carousel-control:hover .fa {
+    opacity: 1;
+}
+
+.carousel-indicators {
+    position: absolute;
+    z-index: 101;
+}
+
+.carousel-indicators-dots {
+    width: 100%;
+    bottom: 20px;
+    left: 0;
+    text-align: center;
+}
+
+.carousel-indicators-dots li {
+    display: inline-block;
+    margin: 0 5px;
+    width: 15px;
+    height: 3px;
+    opacity: .25;
+    cursor: pointer
+}
+
+.carousel-indicators-dots li.active {
+    opacity: 1;
+}
+
+.carousel-indicators-text {
+    z-index: 2;
+    top: 0;
+    bottom: 0;
+    right: 150px;
+    width: 260px;
+    padding: 50px 20px;
+    background-color: rgba(32, 32, 32, .6);
+}
+
+.carousel-indicators-text li {
+    padding: 10px 0;
+    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
+    cursor: pointer;
+}
+
+.carousel-indicators-text li:last-child {
+    border-bottom: 0;
+}
+
+.carousel-indicators-text li .title {
+    margin: 0;
+    color: #ccc;
+}
+
+.carousel-indicators-text li .text {
+    margin: 0;
+    font-size: 12px;
+    color: #999;
+}
+
+.carousel-indicators-thumb {
+    bottom: 20px;
+    left: 0;
+    width: 100%;
+    text-align: center;
+}
+
+.carousel-indicators-thumb li {
+    display: inline-block;
+    margin: 0 2px;
+    border: 3px solid rgba(255, 255, 255, .6);
+    box-shadow: 0 2px 5px rgba(0, 0, 0, .1);
+    border-radius: 2px;
+    overflow: hidden;
+}
+
+/* popup */
+.popup {
+    position: fixed;
+    z-index: 1001;
+    overflow-y: scroll;
+    -webkit-overflow-scrolling: touch;
+    -webkit-transition: .5s;
+    -o-transition: .5s;
+    -moz-transition: .5s;
+    -ms-transition: .5s;
+    transition: .5s;
+}
+
+.popup.left {
+    left: -100%;
+    top: 0;
+}
+
+.popup.right {
+    right: -100%;
+    top: 0;
+}
+
+.popup.top {
+    top: -100%;
+    left: 0;
+}
+
+.popup.bottom {
+    bottom: -100%;
+    right: 0;
+}
+
+.popup-visible.left {
+    left: 0;
+}
+
+.popup-visible.right {
+    right: 0;
+}
+
+.popup-visible.top {
+    top: 0;
+}
+
+.popup-visible.bottom {
+    bottom: 0;
+}
+
+.popup-head {
+    position: relative;
+    padding: 10px 20px;
+}
+
+.popup-body {
+    position: relative;
+    padding: 10px;
+}
+
+/* embed */
+.embed-responsive {
+    position: relative;
+    display: block;
+    overflow: hidden;
+    padding: 0;
+    height: 0
+}
+
+.embed-responsive .embed-responsive-item, .embed-responsive embed, .embed-responsive iframe, .embed-responsive object, .embed-responsive video {
+    position: absolute;
+    top: 0;
+    bottom: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    border: 0
+}
+
+.embed-responsive-16by9 {
+    padding-bottom: 56.25%
+}
+
+.embed-responsive-4by3 {
+    padding-bottom: 75%
+}
+
+/* bootstrap*/
+.fade {
+    opacity: 0;
+    -webkit-transition: opacity .15s linear;
+    -o-transition: opacity .15s linear;
+    transition: opacity .15s linear;
+}
+
+.fade.in {
+    opacity: 1;
+}
+
+.collapse {
+    display: none;
+}
+
+.collapse.in {
+    display: block;
+}
+
+.tab-content > .tab-pane, .carousel-inner > .item {
+    display: none;
+}
+
+.tab-content > .tab-pane.active, .carousel-inner > .item.active {
+    display: block;
+}
+
+/* modal */
+.modal-open {
+    overflow: hidden;
+}
+
+.modal-backdrop {
+    position: fixed;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    left: 0;
+    z-index: 1040;
+    background-color: #000;
+}
+
+.modal-backdrop.fade {
+    opacity: 0;
+}
+
+.modal-backdrop.fade.in {
+    opacity: .5;
+}
+
+/* autocomplete */
+.autocomplete-suggestions {
+    position: absolute;
+    top: 100%;
+    width: 100%;
+    z-index: 9999;
+    padding: 10px;
+    margin-top: 5px;
+    border-radius: 4px;
+}
+
+.autocomplete-suggestion, .autocomplete-suggestions li {
+    padding: 5px 0;
+    cursor: pointer;
+}
+
+.autocomplete-suggestion:first-child {
+    border-top: 0
+}
+
+/* mobile-share */
+.mobile-share {
+    position: fixed;
+    z-index: 999;
+    top: 0;
+    bottom: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    animation: fade-in;
+    animation-duration: .5s;
+    -webkit-animation: fade-in .5s;
+}
+
+/*.share-weixin {*/
+/*    background: url(../img/share_weixin.png) rgba(0, 0, 0, .8) no-repeat;*/
+/*    background-position: right top 10px;*/
+/*    background-size: 80%;*/
+/*}*/
+
+/*.share-other {*/
+/*    background: url(../img/share_other.png) rgba(0, 0, 0, .8) no-repeat;*/
+/*    background-position: center bottom 10px;*/
+/*    background-size: 80%;*/
+/*}*/
+
+/* taddar */
+.myui-nav__tabbar {
+    display: none;
+}
+
+/* more */
+.hidden {
+    overflow: hidden !important;
+}
+
+.relative {
+    position: relative;
+}
+
+.fixed {
+    position: fixed;
+}
+
+.block {
+    display: block !important;
+}
+
+.inline-block {
+    display: inline-block !important;
+}
+
+.top-fixed-up {
+    margin-top: 0 !important;
+}
+
+.top-fixed {
+    -webkit-transition: .5s;
+    -o-transition: .5s;
+    -moz-transition: .5s;
+    -ms-transition: .5s;
+    transition: .5s;
+}
+
+.pull-left {
+    float: left !important;
+}
+
+.pull-right {
+    float: right !important;
+}
+
+.margin-0 {
+    margin: 0 !important;
+}
+
+.padding-0 {
+    padding: 0 !important;
+}
+
+.margin-t0 {
+    margin: 0 !important;
+}
+
+.padding-t0 {
+    padding-top: 0 !important;
+}
+
+.margin-b0 {
+    margin-bottom: 0 !important;
+}
+
+.padding-b0 {
+    padding-top: 0 !important;
+}
+
+.radius-0 {
+    border-radius: 0 !important;
+}
+
+.hide, .visible-lg, .visible-md, .visible-sm, .visible-xs, .visible-mi, .visible-inline-lg, .visible-inline-md, .visible-inline-sm, .visible-inline-xs, .visible-inline-mi {
+    display: none !important;
+}
+
+.mask {
+    position: fixed;
+    top: 0;
+    left: 0;
+    bottom: 0;
+    z-index: 999;
+    width: 100%;
+    height: 100%;
+    background: rgba(0, 0, 0, 0.2);
+    animation: fade-in;
+    animation-duration: .5s;
+    -webkit-animation: fade-in .5s;
+}
+
+.fadeInDown {
+    -webkit-animation: fadeInDown .5s .2s ease both;
+    -moz-animation: fadeInDown .5s .2s ease both;
+}
+
+.scrollbar::-webkit-scrollbar {
+    width: 4px;
+    background-color: #f5f5f5;
+}
+
+.scrollbar::-webkit-scrollbar-thumb {
+    background-color: #ccc;
+}
+
+@keyframes fade-in {
+    0% {
+        opacity: 0;
+    }
+    40% {
+        opacity: 0;
+    }
+    100% {
+        opacity: 1;
+    }
+}
+
+@-webkit-keyframes fade-in {
+    0% {
+        opacity: 0;
+    }
+    40% {
+        opacity: 0;
+    }
+    100% {
+        opacity: 1;
+    }
+}
+
+@-webkit-keyframes fadeInDown {
+    0% {
+        opacity: 0;
+        -webkit-transform: translateY(-10px);
+    }
+    100% {
+        opacity: 1;
+        -webkit-transform: translateY(0);
+    }
+}
+
+@-moz-keyframes fadeInDown {
+    0% {
+        opacity: 0;
+        -moz-transform: translateY(-10px);
+    }
+    100% {
+        opacity: 1;
+        -moz-transform: translateY(0);
+    }
+}
+
+/* media */
+.col-pd, .col-lg-1, .col-lg-10, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-md-1, .col-md-10, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-sm-1, .col-sm-10, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-xs-1, .col-xs-10, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9 {
+    position: relative;
+    min-height: 1px
+}
+
+.col-xs-1, .col-xs-10, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-wide-1, .col-xs-wide-10, .col-xs-wide-15, .col-xs-wide-2, .col-xs-wide-25, .col-xs-wide-3, .col-xs-wide-35, .col-xs-wide-4, .col-xs-wide-45, .col-xs-wide-5, .col-xs-wide-55, .col-xs-wide-6, .col-xs-wide-65, .col-xs-wide-7, .col-xs-wide-75, .col-xs-wide-8, .col-xs-wide-85, .col-xs-wide-9, .col-xs-wide-95 {
+    float: left
+}
+
+.col-xs-10 {
+    width: 10%
+}
+
+.col-xs-9 {
+    width: 11.1111111%
+}
+
+.col-xs-8 {
+    width: 12.5%
+}
+
+.col-xs-7 {
+    width: 14.2857143%
+}
+
+.col-xs-6 {
+    width: 16.6666667%
+}
+
+.col-xs-5 {
+    width: 20%
+}
+
+.col-xs-4 {
+    width: 25%
+}
+
+.col-xs-3 {
+    width: 33.3333333%
+}
+
+.col-xs-2 {
+    width: 50%
+}
+
+.col-xs-1 {
+    width: 100%
+}
+
+.col-xs-wide-10 {
+    width: 10%
+}
+
+.col-xs-wide-9 {
+    width: 90%
+}
+
+.col-xs-wide-8 {
+    width: 80%
+}
+
+.col-xs-wide-7 {
+    width: 70%
+}
+
+.col-xs-wide-6 {
+    width: 60%
+}
+
+.col-xs-wide-5 {
+    width: 50%
+}
+
+.col-xs-wide-4 {
+    width: 40%
+}
+
+.col-xs-wide-3 {
+    width: 30%
+}
+
+.col-xs-wide-2 {
+    width: 20%
+}
+
+.col-xs-wide-15 {
+    width: 15%
+}
+
+.col-xs-wide-95 {
+    width: 95%
+}
+
+.col-xs-wide-85 {
+    width: 85%
+}
+
+.col-xs-wide-75 {
+    width: 75%
+}
+
+.col-xs-wide-65 {
+    width: 65%
+}
+
+.col-xs-wide-55 {
+    width: 55%
+}
+
+.col-xs-wide-45 {
+    width: 45%
+}
+
+.col-xs-wide-35 {
+    width: 35%
+}
+
+.col-xs-wide-25 {
+    width: 25%
+}
+
+.img-xs-300 {
+    width: 300px;
+}
+
+.img-xs-220 {
+    width: 220px;
+}
+
+.img-xs-190 {
+    width: 190px;
+}
+
+.img-xs-160 {
+    width: 160px;
+}
+
+.img-xs-150 {
+    width: 150px;
+}
+
+.img-xs-140 {
+    width: 140px;
+}
+
+.img-xs-130 {
+    width: 130px;
+}
+
+.img-xs-120 {
+    width: 120px;
+}
+
+.img-xs-110 {
+    width: 110px;
+}
+
+.img-xs-100 {
+    width: 100px;
+}
+
+.img-xs-90 {
+    width: 90px;
+}
+
+.img-xs-80 {
+    width: 80px;
+}
+
+.img-xs-70 {
+    width: 70px;
+}
+
+@media (min-width: 768px) {
+    .col-sm-1, .col-sm-10, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-wide-1, .col-sm-wide-10, .col-sm-wide-15, .col-sm-wide-2, .col-sm-wide-25, .col-sm-wide-3, .col-sm-wide-35, .col-sm-wide-4, .col-sm-wide-45, .col-sm-wide-5, .col-sm-wide-55, .col-sm-wide-6, .col-sm-wide-65, .col-sm-wide-7, .col-sm-wide-75, .col-sm-wide-8, .col-sm-wide-85, .col-sm-wide-9, .col-sm-wide-95 {
+        float: left
+    }
+
+    .col-sm-10 {
+        width: 10%
+    }
+
+    .col-sm-9 {
+        width: 11.1111111%
+    }
+
+    .col-sm-8 {
+        width: 12.5%
+    }
+
+    .col-sm-7 {
+        width: 14.2857143%
+    }
+
+    .col-sm-6 {
+        width: 16.6666667%
+    }
+
+    .col-sm-5 {
+        width: 20%
+    }
+
+    .col-sm-4 {
+        width: 25%
+    }
+
+    .col-sm-3 {
+        width: 33.3333333%
+    }
+
+    .col-sm-2 {
+        width: 50%
+    }
+
+    .col-sm-1 {
+        width: 100%
+    }
+
+    .col-sm-wide-10 {
+        width: 10%
+    }
+
+    .col-sm-wide-9 {
+        width: 90%
+    }
+
+    .col-sm-wide-8 {
+        width: 80%
+    }
+
+    .col-sm-wide-7 {
+        width: 70%
+    }
+
+    .col-sm-wide-6 {
+        width: 60%
+    }
+
+    .col-sm-wide-5 {
+        width: 50%
+    }
+
+    .col-sm-wide-4 {
+        width: 40%
+    }
+
+    .col-sm-wide-3 {
+        width: 30%
+    }
+
+    .col-sm-wide-2 {
+        width: 20%
+    }
+
+    .col-sm-wide-15 {
+        width: 15%
+    }
+
+    .col-sm-wide-95 {
+        width: 95%
+    }
+
+    .col-sm-wide-85 {
+        width: 85%
+    }
+
+    .col-sm-wide-75 {
+        width: 75%
+    }
+
+    .col-sm-wide-65 {
+        width: 65%
+    }
+
+    .col-sm-wide-55 {
+        width: 55%
+    }
+
+    .col-sm-wide-45 {
+        width: 45%
+    }
+
+    .col-sm-wide-35 {
+        width: 35%
+    }
+
+    .col-sm-wide-25 {
+        width: 25%
+    }
+
+    .img-sm-300 {
+        width: 300px;
+    }
+
+    .img-sm-220 {
+        width: 220px;
+    }
+
+    .img-sm-190 {
+        width: 190px;
+    }
+
+    .img-sm-160 {
+        width: 160px;
+    }
+
+    .img-sm-150 {
+        width: 150px;
+    }
+
+    .img-sm-140 {
+        width: 140px;
+    }
+
+    .img-sm-130 {
+        width: 130px;
+    }
+
+    .img-sm-120 {
+        width: 120px;
+    }
+
+    .img-sm-110 {
+        width: 110px;
+    }
+
+    .img-sm-100 {
+        width: 100px;
+    }
+
+    .img-sm-90 {
+        width: 90px;
+    }
+
+    .img-sm-80 {
+        width: 80px;
+    }
+
+    .img-sm-70 {
+        width: 70px;
+    }
+}
+
+@media (min-width: 1024px) {
+    .col-md-1, .col-md-10, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-wide-1, .col-md-wide-10, .col-md-wide-15, .col-md-wide-2, .col-md-wide-25, .col-md-wide-3, .col-md-wide-35, .col-md-wide-4, .col-md-wide-45, .col-md-wide-5, .col-md-wide-55, .col-md-wide-6, .col-md-wide-65, .col-md-wide-7, .col-md-wide-75, .col-md-wide-8, .col-md-wide-85, .col-md-wide-9, .col-md-wide-95 {
+        float: left
+    }
+
+    .col-md-10 {
+        width: 10%
+    }
+
+    .col-md-9 {
+        width: 11.1111111%
+    }
+
+    .col-md-8 {
+        width: 12.5%
+    }
+
+    .col-md-7 {
+        width: 14.2857143%
+    }
+
+    .col-md-6 {
+        width: 20%
+    }
+
+    .col-md-5 {
+        width: 20%
+    }
+
+    .col-md-4 {
+        width: 25%
+    }
+
+    .col-md-3 {
+        width: 33.3333333%
+    }
+
+    .col-md-2 {
+        width: 50%
+    }
+
+    .col-md-1 {
+        width: 100%
+    }
+
+    .col-md-wide-10 {
+        width: 10%
+    }
+
+    .col-md-wide-9 {
+        width: 90%
+    }
+
+    .col-md-wide-8 {
+        width: 80%
+    }
+
+    .col-md-wide-7 {
+        width: 70%
+    }
+
+    .col-md-wide-6 {
+        width: 60%
+    }
+
+    .col-md-wide-5 {
+        width: 50%
+    }
+
+    .col-md-wide-4 {
+        width: 40%
+    }
+
+    .col-md-wide-3 {
+        width: 30%
+    }
+
+    .col-md-wide-2 {
+        width: 20%
+    }
+
+    .col-md-wide-15 {
+        width: 15%
+    }
+
+    .col-md-wide-95 {
+        width: 95%
+    }
+
+    .col-md-wide-85 {
+        width: 85%
+    }
+
+    .col-md-wide-75 {
+        width: 75%
+    }
+
+    .col-md-wide-65 {
+        width: 65%
+    }
+
+    .col-md-wide-55 {
+        width: 55%
+    }
+
+    .col-md-wide-45 {
+        width: 45%
+    }
+
+    .col-md-wide-35 {
+        width: 35%
+    }
+
+    .col-md-wide-25 {
+        width: 25%
+    }
+
+    .img-md-300 {
+        width: 300px;
+    }
+
+    .img-md-220 {
+        width: 220px;
+    }
+
+    .img-md-190 {
+        width: 190px;
+    }
+
+    .img-md-160 {
+        width: 160px;
+    }
+
+    .img-md-150 {
+        width: 150px;
+    }
+
+    .img-md-140 {
+        width: 140px;
+    }
+
+    .img-md-130 {
+        width: 130px;
+    }
+
+    .img-md-120 {
+        width: 120px;
+    }
+
+    .img-md-110 {
+        width: 110px;
+    }
+
+    .img-md-100 {
+        width: 100px;
+    }
+
+    .img-md-90 {
+        width: 90px;
+    }
+
+    .img-md-80 {
+        width: 80px;
+    }
+
+    .img-md-70 {
+        width: 70px;
+    }
+}
+
+@media (min-width: 1440px) {
+    .col-lg-1, .col-lg-10, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-wide-1, .col-lg-wide-10, .col-lg-wide-15, .col-lg-wide-2, .col-lg-wide-25, .col-lg-wide-3, .col-lg-wide-35, .col-lg-wide-4, .col-lg-wide-45, .col-lg-wide-5, .col-lg-wide-55, .col-lg-wide-6, .col-lg-wide-65, .col-lg-wide-7, .col-lg-wide-75, .col-lg-wide-8, .col-lg-wide-85, .col-lg-wide-9, .col-lg-wide-95 {
+        float: left
+    }
+
+    .col-lg-10 {
+        width: 10%
+    }
+
+    .col-lg-9 {
+        width: 11.1111111%
+    }
+
+    .col-lg-8 {
+        width: 20%
+    }
+
+    .col-lg-7 {
+        width: 14.2857143%
+    }
+
+    .col-lg-6 {
+        width: 16.6666667%
+    }
+
+    .col-lg-5 {
+        width: 20%
+    }
+
+    .col-lg-4 {
+        width: 25%
+    }
+
+    .col-lg-3 {
+        width: 33.3333333%
+    }
+
+    .col-lg-2 {
+        width: 50%
+    }
+
+    .col-lg-1 {
+        width: 100%
+    }
+
+    .col-lg-wide-10 {
+        width: 10%
+    }
+
+    .col-lg-wide-9 {
+        width: 90%
+    }
+
+    .col-lg-wide-8 {
+        width: 80%
+    }
+
+    .col-lg-wide-7 {
+        width: 70%
+    }
+
+    .col-lg-wide-6 {
+        width: 60%
+    }
+
+    .col-lg-wide-5 {
+        width: 50%
+    }
+
+    .col-lg-wide-4 {
+        width: 40%
+    }
+
+    .col-lg-wide-3 {
+        width: 30%
+    }
+
+    .col-lg-wide-2 {
+        width: 20%
+    }
+
+    .col-lg-wide-15 {
+        width: 15%
+    }
+
+    .col-lg-wide-95 {
+        width: 95%
+    }
+
+    .col-lg-wide-85 {
+        width: 85%
+    }
+
+    .col-lg-wide-75 {
+        width: 75%
+    }
+
+    .col-lg-wide-65 {
+        width: 65%
+    }
+
+    .col-lg-wide-55 {
+        width: 55%
+    }
+
+    .col-lg-wide-45 {
+        width: 45%
+    }
+
+    .col-lg-wide-35 {
+        width: 35%
+    }
+
+    .col-lg-wide-25 {
+        width: 25%
+    }
+
+    .img-lg-300 {
+        width: 300px;
+    }
+
+    .img-lg-220 {
+        width: 220px;
+    }
+
+    .img-lg-190 {
+        width: 190px;
+    }
+
+    .img-lg-160 {
+        width: 160px;
+    }
+
+    .img-lg-150 {
+        width: 150px;
+    }
+
+    .img-lg-140 {
+        width: 140px;
+    }
+
+    .img-lg-130 {
+        width: 130px;
+    }
+
+    .img-lg-120 {
+        width: 120px;
+    }
+
+    .img-lg-110 {
+        width: 110px;
+    }
+
+    .img-lg-100 {
+        width: 100px;
+    }
+
+    .img-lg-90 {
+        width: 90px;
+    }
+
+    .img-lg-80 {
+        width: 80px;
+    }
+
+    .img-lg-70 {
+        width: 70px;
+    }
+
+}
+
+@media (min-width: 1600px) {
+    .visible-lg {
+        display: block !important;
+    }
+
+    .hidden-lg {
+        display: none !important;
+    }
+
+    .visible-inline-lg {
+        display: inline-block !important;
+    }
+
+    .visible-text-lg {
+        visibility: visible !important;
+    }
+
+    .hidden-text-lg {
+        visibility: hidden !important;
+    }
+}
+
+@media (max-width: 1199px) and (min-width: 1023px) {
+    .visible-md {
+        display: block !important;
+    }
+
+    .hidden-md {
+        display: none !important;
+    }
+
+    .visible-inline-md {
+        display: inline-block !important;
+    }
+
+    .visible-text-md {
+        visibility: visible !important;
+    }
+
+    .hidden-text-md {
+        visibility: hidden !important;
+    }
+}
+
+@media (max-width: 1023px) and (min-width: 767px) {
+    .visible-sm {
+        display: block !important;
+    }
+
+    .hidden-sm {
+        display: none !important;
+    }
+
+    .visible-inline-sm {
+        display: inline-block !important;
+    }
+
+    .visible-text-sm {
+        visibility: visible !important;
+    }
+
+    .hidden-text-sm {
+        visibility: hidden !important;
+    }
+}
+
+@media (max-width: 1023px) {
+
+    .dropdown-hover:hover .dropdown-box {
+        display: none;
+    }
+
+    /* panel-head */
+    .myui-panel__head .more {
+        line-height: 35px;
+    }
+
+    .myui-panel__head.active {
+        height: 35px;
+    }
+
+    /* nav */
+    .nav-head > li, .nav-tabs > li {
+        margin-top: 8px;
+        margin-left: 15px;
+    }
+
+    .nav-tabs.active {
+        height: 35px;
+        white-space: nowrap;
+        overflow-y: hidden;
+        overflow-x: scroll;
+        -webkit-overflow-scrolling: touch
+    }
+
+    .nav-tabs.active li {
+        float: none;
+        display: inline-block;
+    }
+
+    .nav-tabs > li .dropdown-box {
+        margin-left: -80px;
+    }
+
+    /* screen */
+    .myui-screen__list {
+        white-space: nowrap;
+        overflow-y: hidden;
+    }
+
+    .myui-screen__list li {
+        float: none;
+        display: inline-block;
+        margin-bottom: 0;
+    }
+
+    .myui-screen__list li a.btn {
+        font-size: 12px;
+        white-space: nowrap
+    }
+
+    /* vod-list */
+    .myui-vodlist__detail .title.active {
+        font-size: 14px;
+        margin-bottom: 0;
+    }
+
+    /* play-list */
+    .myui-content__playlist {
+        -webkit-overflow-scrolling: touch;
+    }
+
+    /* modal */
+    .myui-modal__dialog {
+        width: 320px;
+        margin: 50px auto;
+    }
+
+    @media (max-width: 767px) {
+
+        .visible-xs {
+            display: block !important;
+        }
+
+        .hidden-xs {
+            display: none !important;
+        }
+
+        .visible-inline-xs {
+            display: inline-block !important;
+        }
+
+        .visible-text-xs {
+            visibility: visible !important;
+        }
+
+        .hidden-text-xs {
+            visibility: hidden !important;
+        }
+
+        /* all */
+        body {
+            font-size: 12px;
+            line-height: 20px;
+        }
+
+        /* text */
+        h1 {
+            font-size: 24px;
+        }
+
+        h2 {
+            font-size: 20px;
+        }
+
+        h3 {
+            font-size: 18px;
+        }
+
+        h4 {
+            font-size: 16px;
+        }
+
+        h5 {
+            font-size: 14px;
+        }
+
+        h6 {
+            font-size: 12px;
+        }
+
+        /* tabbar */
+        .myui-nav__tabbar {
+            position: fixed;
+            bottom: 0;
+            width: 100%;
+            padding: 5px 0 0;
+            z-index: 999;
+            display: -webkit-box;
+            display: -webkit-flex;
+            display: flex;
+            border-top: 1px solid;
+        }
+
+        .myui-nav__tabbar .item {
+            display: block;
+            text-align: center;
+            -webkit-box-flex: 1;
+            -webkit-flex: 1;
+            flex: 1;
+        }
+
+        .myui-nav__tabbar .item .icon {
+            display: block;
+            text-align: center;
+            font-size: 20px;
+            line-height: 20px;
+        }
+
+        .myui-nav__tabbar .item .icon-img {
+            display: inline-block;
+            margin-top: 5px;
+            width: 24px;
+            height: 24px;
+        }
+
+        .myui-nav__tabbar .item .title {
+            margin: 5px 0;
+            font-size: 12px;
+        }
+
+        /* line */
+        .split-line {
+            height: 12px;
+            margin-left: 5px;
+            margin-right: 5px;
+        }
+
+        .top-line:before, .top-line-dot:before {
+            -webkit-transform-origin: 0 0;
+            transform-origin: 0 0;
+            -webkit-transform: scaleY(0.5);
+            transform: scaleY(0.5);
+        }
+
+        .bottom-line:after, .bottom-line-dot:before {
+            -webkit-transform-origin: 0 100%;
+            transform-origin: 0 100%;
+            -webkit-transform: scaleY(0.5);
+            transform: scaleY(0.5);
+        }
+
+        /* panel-head */
+        .myui-panel__head .title, .myui-panel__head .title a {
+            font-size: 18px;
+        }
+
+        /* vod-list */
+        .myui-vodlist__thumb .tag {
+            padding: 0 5px;
+        }
+
+        .myui-vodlist__thumb .silde-title {
+            font-size: 12px;
+        }
+
+        .myui-vodlist__detail .title, .myui-vodlist__detail .title.active {
+            margin-bottom: 0;
+            font-size: 12px;
+        }
+
+        /* media-list */
+        .myui-vodlist__media li .detail.active {
+            padding-left: 0;
+            padding-right: 10px;
+        }
+
+        /* text-list */
+        .myui-vodlist__text li a {
+            padding: 10px 0;
+        }
+
+        .myui-vodlist__text.downlist li {
+            padding: 5px 0 0;
+        }
+
+        /* down-list */
+        .myui-down__list li {
+            padding: 5px 0 10px;
+        }
+
+        .myui-down__list li .operate {
+            float: none;
+            display: block;
+        }
+
+        /* article */
+        .myui-article__title {
+            font-size: 18px;
+        }
+
+        /* page */
+        .myui-page li {
+            float: left;
+            width: 20%;
+            margin: 0;
+            padding: 0 5px 0 5px
+        }
+
+        .myui-page li a {
+            display: block;
+            padding: 5px 0;
+            text-align: center
+        }
+
+        /* extra */
+        .myui-extra li {
+            padding: 8px 0 0
+        }
+
+        .myui-extra li a {
+            width: 35px;
+            height: 35px;
+            line-height: 35px;
+            font-size: 16px
+        }
+
+        /* flickity */
+        .flickity-prev-next-button {
+            width: 20px;
+            height: 40px;
+        }
+
+        .flickity-prev-next-button.previous {
+            border-radius: 0 5px 5px 0
+        }
+
+        .flickity-prev-next-button.next {
+            border-radius: 5px 0 0 5px
+        }
+
+        /* slide */
+        .carousel-control {
+            width: 30px;
+            height: 100%;
+        }
+
+        .carousel-control .fa {
+            margin-top: -15px;
+            display: block;
+            width: 30px;
+            height: 30px;
+            font-size: 20px;
+            line-height: 30px;
+        }
+
+        .carousel-control.left {
+            left: 10px;
+        }
+
+        .carousel-control.right {
+            right: 10px;
+        }
+
+        /* more */
+        .m-margin-0 {
+            margin: 0 !important;
+        }
+
+        .m-padding-0 {
+            padding: 0 !important;
+        }
+
+    }
+}

BIN
src/main/resources/static/font/fontawesome-webfont.eot


BIN
src/main/resources/static/font/fontawesome-webfont.ttf


BIN
src/main/resources/static/font/fontawesome-webfont.woff


BIN
src/main/resources/static/font/fontawesome-webfont.woff2


+ 98 - 0
src/main/resources/static/index.html

@@ -0,0 +1,98 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+    <title>影片列表</title>
+
+    <meta http-equiv="pragma" content="no-cache">
+    <meta http-equiv="cache-control" content="no-cache">
+    <meta http-equiv="expires" content="0">
+    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
+    <meta http-equiv="description" content="This is my page">
+    <meta http-equiv="content-type" content="text/html;charset=utf-8">
+    <link rel="shortcut icon" href="cover/favicon.ico" type="image/x-icon">
+    <link href="css/main.css?1649066400" type="text/css" rel="stylesheet">
+    <link rel="stylesheet" href="css/mytheme-ui.css?v=2.8" type="text/css">
+    <link rel="stylesheet" href="css/mytheme-color3.css?v=2.8" type="text/css">
+    <link rel="stylesheet" href="css/mytheme-site.css?v=2.8" type="text/css">
+    <link rel="stylesheet" href="css/mytheme-font.css?v=2.8" type="text/css">
+    <script src="js/jquery-3.6.0.min.js"></script>
+    <script src="js/pagination.js"></script>
+    <link rel="stylesheet" href="css/my.css" type="text/css">
+    <script type="text/javascript" src="js/my.js"></script>
+</head>
+
+<body>
+<div class="container">
+    <div class="row">
+        <div class="myui-panel active myui-panel-bg2 clearfix">
+            <div class="myui-panel-box clearfix">
+                <div class="myui-panel_hd">
+                    <div class="myui-panel__head active bottom-line clearfix">
+                        <a class="slideDown-btn more pull-right" href="javascript:">收起 <i
+                                class="fa fa-angle-up"></i></a>
+                        <h3 class="title">电影 </h3>
+                        <a class="more text-muted" id="shaixuan">筛选</a>
+                        <div class="myui-header__search search-box">
+                            <a class="search-select dropdown-hover" href="javascript:">
+                                <span class="text" id="bigType">骑兵</span>
+                                <i class="fa fa-caret-down"></i>
+                                <div class="dropdown-box bottom fadeInDown">
+                                    <ul class="item" style="line-height: 140%;">
+                                        <li class="">骑兵</li>
+                                        <li class="">步兵</li>
+                                        <li class="">流出</li>
+                                    </ul>
+                                </div>
+                            </a>
+                            <input type="text" id="wd" name="wd" class="search_wd form-control ac_input" value=""
+                                   placeholder="" autocomplete="off" style=" padding-left: 72px; ">
+                            <button class="submit search_submit" id="searchbutton" type="submit" name="submit"><i
+                                    class="fa fa-search"></i></button>
+                        </div>
+                    </div>
+                </div>
+                <div class="myui-panel_bd">
+                    <div class="slideDown-box" style="">
+                        <ul class="myui-screen__list nav-slide clearfix leixingul" data-align="left">
+                            <li><a class="text-muted btn">类型</a></li>
+                            <li><a class="btn btn-warm searchbtn leixing">全部</a></li>
+                        </ul>
+                        <ul class="myui-screen__list nav-slide clearfix yanyuanul" data-align="left">
+                            <li><a class="btn text-muted">演员</a></li>
+                            <li><a class="btn btn-warm searchbtn yanyuan">全部</a></li>
+                        </ul>
+                    </div>
+                    <ul class="myui-screen__list nav-slide clearfix paixuul" data-align="left">
+                        <li><a class="btn text-muted">排序</a></li>
+                        <li><a class="btn btn-warm searchbtn" orderField="vi.issue_date" order="desc">发布时间</a></li>
+                        <li><a class="btn searchbtn" orderField="vi.modify_time" order="desc">更新时间</a></li>
+                        <li><a class="btn searchbtn" orderField="vio.score" order="desc">评分</a></li>
+                    </ul>
+                </div>
+            </div>
+        </div>
+        <!-- 筛选 -->
+        <div class="myui-panel myui-panel-bg clearfix">
+            <div class="myui-panel-box clearfix">
+                <div class="myui-panel_bd">
+                    <ul class="myui-vodlist clearfix">
+                    </ul>
+                </div>
+            </div>
+            <div class="text-center vodlistnone" style="padding: 50px;display: none;">
+                <p><img src="cover/no.png"></p>
+                <h4>没有找到您想要的结果哦!您可以 <a class="text-color">“留言反馈”</a> 给我们</h4>
+            </div>
+        </div>
+        <!--翻页-->
+        <ul class="myui-page text-center clearfix" style="line-height: 140%;margin-top: 20px;">
+        </ul>
+        <!-- 翻页-->
+    </div>
+</div>
+<div id="cover"><img src="cover/loading.gif" style="width: 80px; height: 80px;"/></div>
+</body>
+</html>
+
+
+

File diff suppressed because it is too large
+ 1 - 0
src/main/resources/static/js/jquery-3.6.0.min.js


+ 215 - 0
src/main/resources/static/js/my.js

@@ -0,0 +1,215 @@
+$(function () {
+    $(".slideDown-btn").click(function () {
+        var display = $('.slideDown-box');
+        if (display.css('display') == 'block') {
+            display.slideUp("slow");
+            $(this).html('展开  <i class="fa fa-angle-down"></i>');
+        } else {
+            display.slideDown("slow");
+            $(this).html('收起   <i class="fa fa-angle-up"></i>');
+        }
+    });
+    $.ajax({
+        url: "getIndexInfo", //请求的url地址
+        dataType: "json", //返回格式为json
+        data: {"pageNo": 1, "pageSize": 10}, //参数值
+        type: "post", //请求方式
+        async: true, //请求是否异步,默认为异步,这也是ajax重要特性
+        success: function (data) {
+            //请求成功时处理
+            if (data != null && $.trim(data) != "") {
+                if (data.videoCastList.length > 0) {
+                    var videoCastList = data.videoCastList;
+                    var str = "";
+                    for (var i = 0; i < videoCastList.length; i++) {
+                        var videoCast = videoCastList[i];
+                        str += "<li><a class=\"btn searchbtn\">" + videoCast.name + "</a></li>";
+                    }
+                    $(".yanyuan").parent().after(str);
+                }
+                if (data.videoGenresList.length > 0) {
+                    var videoGenresList = data.videoGenresList;
+                    var str = "";
+                    for (var i = 0; i < videoGenresList.length; i++) {
+                        var videoGenres = videoGenresList[i];
+                        str += "<li><a class=\"btn searchbtn\">" + videoGenres.name + "</a></li>";
+                    }
+                    $(".leixing").parent().after(str);
+                }
+                if (data.videoInfoPage.size > 0) {
+                    var videoInfoList = data.videoInfoPage.list;
+                    var str = "";
+                    for (var i = 0; i < videoInfoList.length; i++) {
+                        var videoInfo = videoInfoList[i];
+                        str += "<li class=\"col-lg-8 col-md-6 col-sm-4 col-xs-3\">" +
+                            "   <div class=\"myui-vodlist__box\">" +
+                            "<a class=\"myui-vodlist__thumb lazyload\" title=\"\" style=\"background-image: url(&quot;image/" + videoInfo.imgUrl + "&quot;);\">" +
+                            "           <span class=\"play hidden-xs\"></span>" +
+                            "           <span class=\"pic-tag pic-tag-top\">" +
+                            "               <span class=\"tag\" style=\"background-color: #FB7299;\">" + videoInfo.identificationCode + "</span>" +
+                            "               <span class=\"tag\" style=\"background-color: #00C0FF;\">" + videoInfo.issueDate + "</span>" +
+                            "           </span>" +
+                            "           <span class=\"pic-text text-right\">" + videoInfo.score + "</span>" +
+                            "       </a>" +
+                            "       <div class=\"myui-vodlist__detail\">" +
+                            "           <h4 class=\"title text-overflow\"><a title=\" " + videoInfo.name + " \">" + videoInfo.name + "</a></h4>" +
+                            "           <p class=\"text text-overflow text-muted hidden-xs\">直属:" + videoInfo.mainWho + "</p>" +
+                            "       </div>" +
+                            "   </div>" +
+                            "</li>";
+                    }
+                    $(".myui-vodlist").html(str);
+
+                    $(".searchbtn").click(function () {
+                        $(this).closest('ul').find(".searchbtn").removeClass("btn-warm");
+                        $(this).addClass("btn-warm");
+
+                        if ($(this).attr('order') != undefined) {
+                            var order = $(this).attr('order');
+                            if ("desc" == order) {
+                                $(this).attr("order", "asc");
+                            } else if ("asc" == order) {
+                                $(this).attr("order", "desc");
+                            }
+                        }
+
+                        $("#wd").val("");
+
+                        search(1);
+                    });
+
+                    $(".myui-page").pagination({
+                        pageSize: "10",
+                        pageNo: "1",
+                        total: data.videoInfoPage.total,
+                        callback: function (pageNo) {
+                            $("#wd").val("");
+
+                            search(pageNo);
+                        }
+                    });
+                }
+            }
+        },
+        beforeSend: function () {
+            //请求前的处理
+            $("#cover").css('display', 'block');
+        },
+        complete: function () {
+            //请求完成的处理
+            $("#cover").css('display', 'none');
+        },
+        error: function (errorData) {
+            //请求出错处理
+            alert('error:' + errorData);
+        }
+    });
+
+    $("#searchbutton").click(function () {
+        search(1);
+    });
+    $("#shaixuan").click(function (){
+        $("#wd").val("");
+
+        search(1);
+    });
+    $("#wd").keydown(function (e) {
+        if (e.keyCode == 13) {
+            search(1);
+        }
+    });
+    $(".dropdown-box").find("li").click(function (){
+        $("#bigType").text($(this).text());
+        $(".dropdown-box").attr("style", "display: none;");
+    });
+    $(".dropdown-hover").mouseover(function(){
+        $(".dropdown-box").attr("style", "display: block;");
+    });
+    $(".dropdown-hover").mouseout(function(){
+        $(".dropdown-box").attr("style", "display: none;");
+    });
+});
+
+function search(pageNo) {
+    var genres = $(".leixingul").find(".btn-warm").text().replace("全部", "");
+    var cast = $(".yanyuanul").find(".btn-warm").text().replace("全部", "");
+    var orderField = $(".paixuul").find(".btn-warm").attr("orderField");
+    var order = $(".paixuul").find(".btn-warm").attr("order");
+    var keyword = $("#wd").val();
+    $.ajax({
+        url: "videoInfo/getVideoInfoPage", //请求的url地址
+        dataType: "json", //返回格式为json
+        data: JSON.stringify({
+            "pageNo": pageNo,
+            "pageSize": 10,
+            "genres": genres,
+            "cast": cast,
+            "orderField": orderField,
+            "order": order,
+            "keyword": keyword
+        }), //参数值
+        type: "post", //请求方式
+        contentType: "application/json;charset=utf-8",
+        async: true, //请求是否异步,默认为异步,这也是ajax重要特性
+        success: function (data) {
+            //请求成功时处理
+            if (data != null && $.trim(data) != "") {
+                var videoInfoList = data.list;
+                var str = "";
+                for (var i = 0; i < videoInfoList.length; i++) {
+                    var videoInfo = videoInfoList[i];
+
+                    var date = videoInfo.issueDate;
+                    if (orderField == 'vi.modify_time') {
+                        date = videoInfo.modifyTime;
+                    }
+
+                    str += "<li class=\"col-lg-8 col-md-6 col-sm-4 col-xs-3\">" +
+                        "   <div class=\"myui-vodlist__box\">" +
+                        "<a class=\"myui-vodlist__thumb lazyload\" title=\"\" style=\"background-image: url(&quot;image/" + videoInfo.imgUrl + "&quot;);\">" +
+                        "           <span class=\"play hidden-xs\"></span>" +
+                        "           <span class=\"pic-tag pic-tag-top\">" +
+                        "               <span class=\"tag\" style=\"background-color: #FB7299;\">" + videoInfo.identificationCode + "</span>" +
+                        "               <span class=\"tag\" style=\"background-color: #00C0FF;\">" + date + "</span>" +
+                        "           </span>" +
+                        "           <span class=\"pic-text text-right\">" + videoInfo.score + "</span>" +
+                        "       </a>" +
+                        "       <div class=\"myui-vodlist__detail\">" +
+                        "           <h4 class=\"title text-overflow\"><a title=\" " + videoInfo.name + " \">" + videoInfo.name + "</a></h4>" +
+                        "           <p class=\"text text-overflow text-muted hidden-xs\">直属:" + videoInfo.mainWho + "</p>" +
+                        "       </div>" +
+                        "   </div>" +
+                        "</li>";
+                }
+                $(".myui-vodlist").html(str);
+
+                if (str == "") {
+                    $(".vodlistnone").attr("style", "padding: 50px;display: block;");
+                } else {
+                    $(".vodlistnone").attr("style", "padding: 50px;display: none;");
+                }
+
+                $(".myui-page").pagination({
+                    pageSize: "10",
+                    pageNo: pageNo,
+                    total: data.total,
+                    callback: function (pageNo) {
+                        $("#wd").val("");
+
+                        search(pageNo);
+                    }
+                });
+            }
+        },
+        beforeSend: function () {
+            //请求前的处理
+        },
+        complete: function () {
+            //请求完成的处理
+        },
+        error: function (errorData) {
+            //请求出错处理
+            alert('error:' + errorData);
+        }
+    });
+}

File diff suppressed because it is too large
+ 1775 - 0
src/main/resources/static/js/mytheme-site.js


+ 95 - 0
src/main/resources/static/js/pagination.js

@@ -0,0 +1,95 @@
+/**
+ * 使选中区域显示分页
+ *
+ * options{
+ * 	pageNo: 页码
+ * 	pageSize:页大小 (默认为10)
+ *	total: 数据总数
+ *	callback: 点击页码后执行方法
+ * }
+ */
+$.fn.pagination = function (options) {
+
+    // 默认属性
+    var opt = {pageNo: 1, pageSize: 10};
+    // 填充参数
+    $.extend(opt, options);
+    opt.pageTotal = Math.ceil(opt.total / opt.pageSize);
+    // 分页DOM
+    var container = $(this);
+
+    selectPage(opt.pageNo);
+
+    // 上一页点击事件
+    container.find("#first-page").click(function () {
+        if (Number(opt.pageNo) > 1) {
+            opt.pageNo = Number(opt.pageNo) - 1;
+        }
+
+        selectPage(opt.pageNo);
+        opt.callback(opt.pageNo);
+    });
+    // 首页点击事件
+    container.find("#firstpage").click(function () {
+        opt.pageNo = 1;
+        selectPage(opt.pageNo);
+        opt.callback(opt.pageNo);
+    });
+
+    // 下一页点击事件
+    container.find("#last-page").click(function () {
+        if (Number(opt.pageNo) < Number(opt.pageTotal)) {
+            opt.pageNo = Number(opt.pageNo) + 1;
+        }
+
+        selectPage(opt.pageNo);
+        opt.callback(opt.pageNo);
+    });
+    // 尾页点击事件
+    container.find("#lastpage").click(function () {
+        opt.pageNo = Number(opt.pageTotal);
+        selectPage(opt.pageNo);
+        opt.callback(opt.pageNo);
+    });
+
+    // 页码点击事件
+    container.find("[name='page']").click(function () {
+        opt.pageNo = parseInt($(this).text());
+        selectPage(opt.pageNo);
+        opt.callback(opt.pageNo);
+    });
+
+    // 选择页码
+    function selectPage(pageNo) {
+        container.html("");
+        var ul = container;
+
+        var str = '';
+        // 首页、上一页
+        if (opt.pageNo > 0) {
+            str += '<li><a class="btn btn-default" id="firstpage">首页</a></li>';
+            str += '<li><a class="btn btn-default" id="first-page">上一页</a></li>';
+        }
+        // 中间显示页码
+        var start = pageNo - 2 <= 1 ? 1 : pageNo - 2;
+        var end = start + 4;
+        if (end >= opt.pageTotal) {
+            end = opt.pageTotal;
+            start = end - 4 <= 1 ? 1 : end - 4;
+        }
+        if (opt.pageTotal != 0) {
+            for (var i = start; i <= end; i++) {
+                if (i == pageNo) {
+                    str += '<li class="hidden-xs"><a class="btn btn-warm" name="page">' + i + '</a></li>';
+                } else {
+                    str += '<li class="hidden-xs"><a class="btn btn-default" name="page">' + i + '</a></li>';
+                }
+            }
+
+            str += '<li><a class="btn btn-default" id="last-page">下一页</a></li>';
+            str += '<li><a class="btn btn-default" id="lastpage">尾页</a></li>';
+
+            ul.append(str);
+        }
+    }
+};

+ 109 - 0
src/main/resources/templates/ftlIndex.ftl

@@ -0,0 +1,109 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+    <title>影片列表</title>
+
+    <meta http-equiv="pragma" content="no-cache">
+    <meta http-equiv="cache-control" content="no-cache">
+    <meta http-equiv="expires" content="0">
+    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
+    <meta http-equiv="description" content="This is my page">
+    <meta http-equiv="content-type" content="text/html;charset=utf-8">
+    <link href="css/main.css?1649066400" type="text/css" rel="stylesheet">
+    <style type="text/css">
+        #waterfall-zdy{
+            display: flex;
+            flex-direction: row;
+            flex-wrap: wrap;
+            width: 100%;
+            margin: 0 auto;
+            transition: .5s;
+        }
+        #waterfall-zdy .item-b{
+            padding: 5px;
+            width: 25%;
+            transition: .5s;
+            animation: fadeInUp .5s ease-out;
+        }
+        #waterfall-zdy .item-tag {
+            display: inline-block;
+            white-space: nowrap;
+        }
+        #waterfall-zdy div{
+            box-sizing: border-box;
+        }
+        #waterfall-zdy .movie-box-b{
+            border-radius: 5px;
+            background-color: white;
+            border: 1px solid rgba(0,0,0,0.2);
+            box-shadow: 0 2px 3px 0 rgba(0,0,0,0.1);
+            overflow: hidden;
+        }
+        #waterfall-zdy .movie-box-b .photo-frame-b{
+            text-align: center;
+        }
+        #waterfall-zdy .movie-box-b a:link{
+            color: black;
+        }
+        #waterfall-zdy .movie-box-b .photo-info-b{
+            padding: 7px;
+        }
+        #waterfall-zdy .movie-box-b .photo-info-b a{
+            display: block;
+        }
+        #waterfall-zdy span.svg-span{
+            cursor: pointer;
+            opacity: .3;
+        }
+        #waterfall-zdy .copy-svg{
+            vertical-align: middle;
+            display: inline-block;
+        }
+        #waterfall-zdy .info-bottom, .info-bottom-two{
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+            flex-wrap: wrap;
+        }
+    </style>
+</head>
+
+<body>
+<div class="textbox">
+    <div class="boxtitle">筛选</div>
+    <div class="genreitem"><a href="vl_genre.php?g=amjq">极致·性高潮</a></div>
+    <div class="genreitem"><a href="vl_genre.php?g=da">出轨</a></div>
+    <div class="genreitem"><a href="vl_genre.php?g=azba">亚洲</a></div>
+    <div class="genreitem"><a href="vl_genre.php?g=ba">洗澡</a></div>
+    <div class="genreitem"><a href="vl_genre.php?g=ia">美容院</a></div>
+</div>
+<div id="rightcolumn">
+    <div class="boxtitle">最近讨论的影片</div>
+    <div class="videothumblist">
+        <div class="videos">
+            <#if videoInfoList?? && videoInfoList?size gt 0>
+            <#list videoInfoList as videoInfo>
+                <div class="video" id="vid_javme2lx4y">
+                    <a href="./?v=javme2lx4y" title="PFES-029 料理研究家の湿ったパンスト 辻井ほのか">
+                        <div class="id">${videoInfo.identificationCode}</div>
+                        <img src="image/${videoInfo.imgUrl}" width="147" height="200" border="0"
+                             onerror="ThumbError(this, 'https://t69.pixhost.to/thumbs/87/271717403_t517591.jpg');">
+                        <div class="title">${videoInfo.name}</div>
+                    </a>
+                    <div class="toolbar" style="display: none;">
+                        <a id="javme2lx4y" class="icn_want" title="我想要"></a>
+                        <a id="javme2lx4y" class="icn_seen" title="看过了"></a>
+                        <a id="javme2lx4y" class="icn_have" title="已拥有"></a>
+                    </div>
+                </div>
+            </#list>
+            </#if>
+        </div>
+    </div>
+    <div class="page_selector"><span class="page first">|&lt;&lt;</span><span class="page prev">上一页</span><span class="page current">1</span><a class="page" href="/cn/vl_mostwanted.php?&amp;mode=&amp;page=2">2</a><a class="page" href="/cn/vl_mostwanted.php?&amp;mode=&amp;page=3">3</a><a class="page" href="/cn/vl_mostwanted.php?&amp;mode=&amp;page=4">4</a><a class="page" href="/cn/vl_mostwanted.php?&amp;mode=&amp;page=5">5</a><a class="page" href="/cn/vl_mostwanted.php?&amp;mode=&amp;page=6">6</a><a class="page" href="/cn/vl_mostwanted.php?&amp;mode=&amp;page=7">7</a><a class="page" href="/cn/vl_mostwanted.php?&amp;mode=&amp;page=8">8</a><a class="page" href="/cn/vl_mostwanted.php?&amp;mode=&amp;page=9">9</a><a class="page next" href="/cn/vl_mostwanted.php?&amp;mode=&amp;page=2">下一页</a><a class="page next10" href="/cn/vl_mostwanted.php?&amp;mode=&amp;page=11">下十页</a><a class="page last" href="/cn/vl_mostwanted.php?&amp;mode=&amp;page=25">&gt;&gt;|</a></div>
+</div>
+</body>
+</html>
+
+
+

+ 45 - 0
src/test/java/Test.java

@@ -0,0 +1,45 @@
+import top.lvzhiqiang.entity.VideoInfo;
+import top.lvzhiqiang.entity.VideoInfoGenres;
+import top.lvzhiqiang.util.DateUtils;
+
+import java.io.File;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.ZoneOffset;
+import java.util.Comparator;
+import java.util.Set;
+import java.util.TreeSet;
+
+public class Test {
+    public static void main(String[] args) {
+        //String filePath = "F:\\1\\0\\2\\4\\视频\\电影\\A级(成人级)\\骑兵\\(类别)HolyWater\\";
+        //File[] files = new File(filePath).listFiles();
+        //if (files == null) {
+        //    return;
+        //}
+        //
+        //for (File file : files) {
+        //    if (file.isDirectory()) {
+        //        // 文件夹
+        //    } else {
+        //        String fileName = file.getName();
+        //        System.out.println(fileName);
+        //    }
+        //}
+
+        Set<VideoInfoGenres> videoInfoGenresSet = new TreeSet<>(Comparator.comparing(o -> (o.getIdentificationCode().concat(o.getName()))));
+        VideoInfoGenres videoInfoGenres = new VideoInfoGenres();
+        videoInfoGenres.setIdentificationCode("1");
+        videoInfoGenres.setName("2");
+        VideoInfoGenres videoInfoGenres2 = new VideoInfoGenres();
+        videoInfoGenres2.setIdentificationCode("1");
+        videoInfoGenres2.setName("3");
+        VideoInfoGenres videoInfoGenres3 = new VideoInfoGenres();
+        videoInfoGenres3.setIdentificationCode("1");
+        videoInfoGenres3.setName("3");
+        videoInfoGenresSet.add(videoInfoGenres);
+        videoInfoGenresSet.add(videoInfoGenres2);
+        videoInfoGenresSet.add(videoInfoGenres3);
+        System.out.println(videoInfoGenresSet);
+    }
+}

Some files were not shown because too many files changed in this diff