liyuntian 10 месяцев назад
Родитель
Сommit
5f17d92b77
31 измененных файлов с 1081 добавлено и 39 удалено
  1. 40 5
      mcp/pom.xml
  2. 2 0
      mcp/src/main/java/com/chuanxia/mcp/McpApplication.java
  3. 22 0
      mcp/src/main/java/com/chuanxia/mcp/bean/dto/UaQueryDto.java
  4. 22 0
      mcp/src/main/java/com/chuanxia/mcp/bean/enums/DeviceUaLevel.java
  5. 4 0
      mcp/src/main/java/com/chuanxia/mcp/bean/model/CdnDomainOperator.java
  6. 46 0
      mcp/src/main/java/com/chuanxia/mcp/bean/model/CdnUa.java
  7. 10 0
      mcp/src/main/java/com/chuanxia/mcp/bean/vo/UserSystemVideoVo.java
  8. 29 0
      mcp/src/main/java/com/chuanxia/mcp/config/MyBatisPlusConfig.java
  9. 13 0
      mcp/src/main/java/com/chuanxia/mcp/config/ResttemplateConfig.java
  10. 11 0
      mcp/src/main/java/com/chuanxia/mcp/controller/CdnDomainController.java
  11. 13 0
      mcp/src/main/java/com/chuanxia/mcp/controller/CdnM3u8Controller.java
  12. 8 4
      mcp/src/main/java/com/chuanxia/mcp/controller/CdnTimeRuleController.java
  13. 42 0
      mcp/src/main/java/com/chuanxia/mcp/controller/CdnUaController.java
  14. 1 0
      mcp/src/main/java/com/chuanxia/mcp/exception/GlobalExceptionHandler.java
  15. 8 0
      mcp/src/main/java/com/chuanxia/mcp/mapper/CdnDomainMapper.java
  16. 2 0
      mcp/src/main/java/com/chuanxia/mcp/mapper/CdnDomainOperatorMapper.java
  17. 9 0
      mcp/src/main/java/com/chuanxia/mcp/mapper/CdnUaMapper.java
  18. 47 0
      mcp/src/main/java/com/chuanxia/mcp/sched/ScheduledService.java
  19. 4 0
      mcp/src/main/java/com/chuanxia/mcp/service/CdnDoaminService.java
  20. 2 0
      mcp/src/main/java/com/chuanxia/mcp/service/CdnTimeRuleService.java
  21. 15 0
      mcp/src/main/java/com/chuanxia/mcp/service/CdnUaService.java
  22. 177 15
      mcp/src/main/java/com/chuanxia/mcp/service/impl/CdnDoaminServiceImpl.java
  23. 7 1
      mcp/src/main/java/com/chuanxia/mcp/service/impl/CdnOperatorServiceImpl.java
  24. 7 1
      mcp/src/main/java/com/chuanxia/mcp/service/impl/CdnTimeRuleServiceImpl.java
  25. 64 0
      mcp/src/main/java/com/chuanxia/mcp/service/impl/CdnUaServiceImpl.java
  26. 115 0
      mcp/src/main/java/com/chuanxia/mcp/util/IpUtil.java
  27. 22 0
      mcp/src/main/java/com/chuanxia/mcp/util/M3U8Parser.java
  28. 269 0
      mcp/src/main/java/com/chuanxia/mcp/util/M3u8DownloadFactory.java
  29. 57 0
      mcp/src/main/resources/com/chuanxia/mcp/mapper/CdnDomainMapper.xml
  30. 13 13
      mcp/src/main/resources/com/chuanxia/mcp/mapper/CdnDomainOperatorMapper.xml
  31. BIN
      mcp/src/main/resources/ip2region.xdb

+ 40 - 5
mcp/pom.xml

@@ -61,11 +61,6 @@
             <artifactId>spring-boot-starter-jdbc</artifactId>
         </dependency>
         <!--mybatis-plus-->
-        <dependency>
-            <groupId>com.baomidou</groupId>
-            <artifactId>mybatis-plus-boot-starter</artifactId>
-            <version>3.3.2</version>
-        </dependency>
         <!--swagger2依赖-->
         <dependency>
             <groupId>com.spring4all</groupId>
@@ -82,15 +77,55 @@
             <artifactId>commons-lang3</artifactId>
             <version>3.9</version>
         </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>2.6</version>
+        </dependency>
+
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-aop</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+            <version>3.5.1</version>
+        </dependency>
+        <!--ip获取归属地util-->
+        <!-- IP定位 -->
+        <dependency>
+            <groupId>org.lionsoul</groupId>
+            <artifactId>ip2region</artifactId>
+            <version>2.6.5</version>
+        </dependency>
+        <dependency>
+            <groupId>eu.bitwalker</groupId>
+            <artifactId>UserAgentUtils</artifactId>
+            <version>1.21</version>
+        </dependency>
+        <!--m3u8文件解析工具类-->
+        <dependency>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcprov-jdk16</artifactId>
+            <version>1.46</version>
+        </dependency>
 
     </dependencies>
 
     <build>
         <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-resources-plugin</artifactId>
+                <configuration>
+                    <encoding>UTF-8</encoding>
+                    <nonFilteredFileExtensions>
+                        <nonFilteredFileExtension>xdb</nonFilteredFileExtension>
+                        <nonFilteredFileExtension>db</nonFilteredFileExtension>
+                    </nonFilteredFileExtensions>
+                </configuration>
+            </plugin>
             <plugin>
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-maven-plugin</artifactId>

+ 2 - 0
mcp/src/main/java/com/chuanxia/mcp/McpApplication.java

@@ -3,9 +3,11 @@ package com.chuanxia.mcp;
 import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableScheduling;
 
 @SpringBootApplication
 @MapperScan("com.chuanxia.mcp.mapper")
+@EnableScheduling
 public class McpApplication {
 
     public static void main(String[] args) {

+ 22 - 0
mcp/src/main/java/com/chuanxia/mcp/bean/dto/UaQueryDto.java

@@ -0,0 +1,22 @@
+package com.chuanxia.mcp.bean.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+@ApiModel("分页查询ua配置实体")
+public class UaQueryDto extends PageQueryBaseDto {
+    @ApiModelProperty("设备")
+    private String device;
+    @ApiModelProperty("设备浏览器")
+    private String browser;
+    @ApiModelProperty("浏览器版本")
+    private String browserVersion;
+    @ApiModelProperty("系统")
+    private String os;
+    @ApiModelProperty("级别:1.高,2.中,3.低")
+    private Integer level;
+}

+ 22 - 0
mcp/src/main/java/com/chuanxia/mcp/bean/enums/DeviceUaLevel.java

@@ -0,0 +1,22 @@
+package com.chuanxia.mcp.bean.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 设备ua类型枚举
+ *
+ * @author Administrator
+ */
+@Getter
+@AllArgsConstructor
+public enum DeviceUaLevel {
+    /**
+     * 浏览器ua信息对应画质枚举类说明
+     */
+    HIGH(1, "高画质"),
+    MEDIUM(2, "中"),
+    LOW(3, "低");
+    private Integer level;
+    private String desc;
+}

+ 4 - 0
mcp/src/main/java/com/chuanxia/mcp/bean/model/CdnDomainOperator.java

@@ -18,8 +18,12 @@ public class CdnDomainOperator {
     private Integer id;
     @TableField("domain_id")
     private Integer domainId;
+    @TableField("domain")
+    private String domain;
     @TableField("operator_id")
     private Integer operatorId;
+    @TableField("operator_name")
+    private String operatorName;
     @TableField("create_by")
     private Integer createBy;
     @TableField("create_time")

+ 46 - 0
mcp/src/main/java/com/chuanxia/mcp/bean/model/CdnUa.java

@@ -0,0 +1,46 @@
+package com.chuanxia.mcp.bean.model;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * @author Administrator
+ */
+@TableName("cdn_ua")
+@Data
+@ApiModel("ua")
+public class CdnUa {
+    @TableId("id")
+    @ApiModelProperty("主键")
+    private Integer id;
+
+    @TableField("browser")
+    @ApiModelProperty("设备浏览器")
+    private String browser;
+
+    @ApiModelProperty("浏览器版本")
+    @TableField("browser_version")
+    private String browserVersion;
+
+    @ApiModelProperty("操作系统")
+    @TableField("os")
+    private String os;
+    @ApiModelProperty("级别:1.高,2.中,3.低")
+    @TableField("level")
+    private Integer level;
+
+    @TableField("create_by")
+    private Integer createBy;
+    @TableField("create_time")
+    private Date createTime;
+    @TableField("update_by")
+    private Integer updateBy;
+    @TableField("update_time")
+    private Date updateTime;
+}

+ 10 - 0
mcp/src/main/java/com/chuanxia/mcp/bean/vo/UserSystemVideoVo.java

@@ -0,0 +1,10 @@
+package com.chuanxia.mcp.bean.vo;
+
+import lombok.Data;
+
+@Data
+public class UserSystemVideoVo {
+    private String videoId;
+    private String m3u8Url;
+
+}

+ 29 - 0
mcp/src/main/java/com/chuanxia/mcp/config/MyBatisPlusConfig.java

@@ -0,0 +1,29 @@
+package com.chuanxia.mcp.config;
+
+import com.baomidou.mybatisplus.annotation.DbType;
+import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class MyBatisPlusConfig {
+
+    /**
+     * 插件配置
+     *
+     * @return
+     */
+    @Bean
+    public MybatisPlusInterceptor mybatisPlusInterceptor() {
+        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
+
+        // 向MyBatis-Plus的过滤器链中添加分页拦截器,需要设置数据库类型(主要用于分页方言)
+        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
+//        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
+        // 添加乐观锁拦截器
+        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
+        return interceptor;
+    }
+}

+ 13 - 0
mcp/src/main/java/com/chuanxia/mcp/config/ResttemplateConfig.java

@@ -0,0 +1,13 @@
+package com.chuanxia.mcp.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+
+@Component
+public class ResttemplateConfig {
+    @Bean
+    public RestTemplate getResttemplate() {
+        return new RestTemplate();
+    }
+}

+ 11 - 0
mcp/src/main/java/com/chuanxia/mcp/controller/CdnDomainController.java

@@ -15,6 +15,8 @@ import io.swagger.annotations.ApiOperation;
 import lombok.RequiredArgsConstructor;
 import org.springframework.web.bind.annotation.*;
 
+import javax.servlet.http.HttpServletRequest;
+import java.math.BigDecimal;
 import java.util.List;
 
 
@@ -56,4 +58,13 @@ public class CdnDomainController {
         return doaminService.updateDomain(domain);
     }
 
+    @GetMapping("getCdnByVideoId")
+    @ApiOperation("根据VideoId,网速,运营商,获取cdn")
+    public Result getCdnByVideoId(@RequestParam("videoId") String videoId,
+                                  @RequestParam(value = "internetSpeed", required = false, defaultValue = "120") BigDecimal internetSpeed,
+                                  @RequestParam(value = "operatorName", defaultValue = "", required = false) String operatorName,
+                                  HttpServletRequest request) {
+        return doaminService.getCdnByVideoId(videoId, internetSpeed, operatorName, request);
+    }
+
 }

+ 13 - 0
mcp/src/main/java/com/chuanxia/mcp/controller/CdnM3u8Controller.java

@@ -0,0 +1,13 @@
+package com.chuanxia.mcp.controller;
+
+import io.swagger.annotations.Api;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@Api("m3u8")
+@RequestMapping("cdnDomain")
+@RequiredArgsConstructor
+public class CdnM3u8Controller {
+}

+ 8 - 4
mcp/src/main/java/com/chuanxia/mcp/controller/CdnTimeRuleController.java

@@ -11,10 +11,7 @@ import com.chuanxia.mcp.service.CdnTimeRuleService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.RequiredArgsConstructor;
-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 org.springframework.web.bind.annotation.*;
 
 @RestController
 @RequiredArgsConstructor
@@ -36,4 +33,11 @@ public class CdnTimeRuleController {
     public Result<IPage<CdnDomainTimeRuleVo>> listPage(@RequestBody DomainTimeRuleQueryDto queryDto) {
         return ruleService.listPage(queryDto);
     }
+
+    @GetMapping("deleteById")
+    @ApiOperation("删除时间规则")
+    @Login
+    public Result deleteById(@RequestParam("id") Integer id) {
+        return ruleService.deleteById(id);
+    }
 }

+ 42 - 0
mcp/src/main/java/com/chuanxia/mcp/controller/CdnUaController.java

@@ -0,0 +1,42 @@
+package com.chuanxia.mcp.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.chuanxia.mcp.bean.dto.UaQueryDto;
+import com.chuanxia.mcp.bean.model.CdnUa;
+import com.chuanxia.mcp.bean.vo.Result;
+import com.chuanxia.mcp.service.CdnUaService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+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;
+
+@RestController
+@RequiredArgsConstructor
+@Slf4j
+@RequestMapping("cdnUa")
+@Api("ua管理")
+public class CdnUaController {
+    private final CdnUaService uaService;
+
+    @PostMapping("listPage")
+    @ApiOperation("ua分页列表")
+    public Result<IPage<CdnUa>> listPage(@RequestBody UaQueryDto queryDto) {
+        return uaService.listPage(queryDto);
+    }
+
+    @PostMapping("saveUa")
+    @ApiOperation("新增ua")
+    public Result<String> saveUa(@RequestBody CdnUa ua) {
+        return uaService.saveUa(ua);
+    }
+
+    @PostMapping("updateUa")
+    @ApiOperation("修改ua")
+    public Result<String> updateUa(@RequestBody CdnUa ua) {
+        return uaService.updateUa(ua);
+    }
+}

+ 1 - 0
mcp/src/main/java/com/chuanxia/mcp/exception/GlobalExceptionHandler.java

@@ -23,6 +23,7 @@ public class GlobalExceptionHandler {
     @ResponseBody
     @ExceptionHandler(Exception.class)
     public Result exceptionCatch(Exception e) {
+        e.printStackTrace();
         log.error("系统发生异常,异常原因:{}", e.getMessage());
         return Result.error(500, "系统发生异常,原因:"+e.getMessage());
     }

+ 8 - 0
mcp/src/main/java/com/chuanxia/mcp/mapper/CdnDomainMapper.java

@@ -2,8 +2,16 @@ package com.chuanxia.mcp.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.chuanxia.mcp.bean.model.CdnDomain;
+import org.apache.ibatis.annotations.Param;
 import org.springframework.stereotype.Repository;
 
+import java.util.Date;
+
 @Repository
 public interface CdnDomainMapper extends BaseMapper<CdnDomain> {
+    CdnDomain getDomainByCityName(@Param("city") String city);
+
+    CdnDomain getDomainByOperator(@Param("operator") String operator);
+
+    CdnDomain getDomainByTimeRule(@Param("hours") Integer hours);
 }

+ 2 - 0
mcp/src/main/java/com/chuanxia/mcp/mapper/CdnDomainOperatorMapper.java

@@ -11,4 +11,6 @@ import org.springframework.stereotype.Repository;
 @Repository
 public interface CdnDomainOperatorMapper extends BaseMapper<CdnDomainOperator> {
     IPage<CdnOperatorVo> listPage(IPage<CdnOperatorVo> page, @Param("queryDto") OperatorQueryDto queryDto);
+
+    void updateDomainByDomainId(@Param("domainId") Integer id, @Param("domain") String domain);
 }

+ 9 - 0
mcp/src/main/java/com/chuanxia/mcp/mapper/CdnUaMapper.java

@@ -0,0 +1,9 @@
+package com.chuanxia.mcp.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.chuanxia.mcp.bean.model.CdnUa;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface CdnUaMapper extends BaseMapper<CdnUa> {
+}

+ 47 - 0
mcp/src/main/java/com/chuanxia/mcp/sched/ScheduledService.java

@@ -0,0 +1,47 @@
+package com.chuanxia.mcp.sched;
+
+import cn.hutool.core.collection.CollectionUtil;
+import com.alibaba.fastjson.JSON;
+import com.chuanxia.mcp.bean.vo.UserSystemVideoVo;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.http.ResponseEntity;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class ScheduledService {
+    private final RestTemplate restTemplate;
+
+    /**
+     * 增量同步
+     */
+    @Scheduled(cron = "0/5 * * * * *")
+    public void scheduled() {
+
+    }
+
+    public ArrayList<UserSystemVideoVo> getM3u8Vo(Date startTime, Date endTime) {
+        String url = "";
+        ResponseEntity<String> forEntity = restTemplate.getForEntity(url, String.class);
+        String body = forEntity.getBody();
+        if (StringUtils.isNotBlank(body)) {
+            List<UserSystemVideoVo> voList = JSON.parseArray(body, UserSystemVideoVo.class);
+            if (CollectionUtil.isNotEmpty(voList)) {
+                for (UserSystemVideoVo userSystemVideoVo : voList) {
+
+                }
+            }
+        }
+        return null;
+    }
+
+}

+ 4 - 0
mcp/src/main/java/com/chuanxia/mcp/service/CdnDoaminService.java

@@ -7,6 +7,9 @@ import com.chuanxia.mcp.bean.dto.DomainQueryDto;
 import com.chuanxia.mcp.bean.model.CdnDomain;
 import com.chuanxia.mcp.bean.vo.Result;
 
+import javax.servlet.http.HttpServletRequest;
+import java.math.BigDecimal;
+
 public interface CdnDoaminService extends IService<CdnDomain> {
     Result<IPage<CdnDomain>> listPage(DomainQueryDto queryDto);
 
@@ -16,4 +19,5 @@ public interface CdnDoaminService extends IService<CdnDomain> {
 
     Result<String> updateDomain(CdnDomain domain);
 
+    Result getCdnByVideoId(String videoId, BigDecimal internetSpeed, String operatorName, HttpServletRequest request);
 }

+ 2 - 0
mcp/src/main/java/com/chuanxia/mcp/service/CdnTimeRuleService.java

@@ -12,4 +12,6 @@ public interface CdnTimeRuleService extends IService<CdnTimeRule> {
     Result<String> bindTimeRule(DomainTimeRuleBindDto timeRule);
 
     Result<IPage<CdnDomainTimeRuleVo>> listPage(DomainTimeRuleQueryDto queryDto);
+
+    Result deleteById(Integer id);
 }

+ 15 - 0
mcp/src/main/java/com/chuanxia/mcp/service/CdnUaService.java

@@ -0,0 +1,15 @@
+package com.chuanxia.mcp.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.chuanxia.mcp.bean.dto.UaQueryDto;
+import com.chuanxia.mcp.bean.model.CdnUa;
+import com.chuanxia.mcp.bean.vo.Result;
+
+public interface CdnUaService extends IService<CdnUa> {
+    Result<IPage<CdnUa>> listPage(UaQueryDto queryDto);
+
+    Result<String> saveUa(CdnUa ua);
+
+    Result<String> updateUa(CdnUa ua);
+}

+ 177 - 15
mcp/src/main/java/com/chuanxia/mcp/service/impl/CdnDoaminServiceImpl.java

@@ -2,6 +2,7 @@ package com.chuanxia.mcp.service.impl;
 
 import cn.hutool.core.collection.CollectionUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -9,23 +10,29 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.chuanxia.mcp.bean.dto.DomainBindDto;
 import com.chuanxia.mcp.bean.dto.DomainQueryDto;
 import com.chuanxia.mcp.bean.enums.DefaultDomainEnums;
-import com.chuanxia.mcp.bean.model.CdnDomain;
-import com.chuanxia.mcp.bean.model.CdnDomainCity;
-import com.chuanxia.mcp.bean.model.SystemUser;
+import com.chuanxia.mcp.bean.enums.DeviceUaLevel;
+import com.chuanxia.mcp.bean.model.*;
 import com.chuanxia.mcp.bean.vo.Result;
 import com.chuanxia.mcp.exception.ResultException;
 import com.chuanxia.mcp.mapper.CdnDomainMapper;
+import com.chuanxia.mcp.mapper.CdnDomainOperatorMapper;
+import com.chuanxia.mcp.mapper.CdnUaMapper;
 import com.chuanxia.mcp.service.CdnDoaminService;
 import com.chuanxia.mcp.service.CdnDomainCityService;
 import com.chuanxia.mcp.service.UserService;
+import com.chuanxia.mcp.util.IpUtil;
+import eu.bitwalker.useragentutils.Browser;
+import eu.bitwalker.useragentutils.OperatingSystem;
+import eu.bitwalker.useragentutils.UserAgent;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.ArrayList;
-import java.util.List;
+import javax.servlet.http.HttpServletRequest;
+import java.math.BigDecimal;
+import java.util.*;
 
 /**
  * @author Administrator
@@ -37,6 +44,8 @@ public class CdnDoaminServiceImpl extends ServiceImpl<CdnDomainMapper, CdnDomain
     private final UserService userService;
     private final CdnDomainMapper domainMapper;
     private final CdnDomainCityService domainCityService;
+    private final CdnUaMapper cdnUaMapper;
+    private final CdnDomainOperatorMapper domainOperatorMapper;
 
     @Override
     public Result<IPage<CdnDomain>> listPage(DomainQueryDto queryDto) {
@@ -63,15 +72,11 @@ public class CdnDoaminServiceImpl extends ServiceImpl<CdnDomainMapper, CdnDomain
         if (StringUtils.isBlank(domain.getManufacturer())) {
             throw new ResultException(500, "厂商不能为空");
         }
-        Integer defaultDomain = domain.getDefaultDomain();
-        if (DefaultDomainEnums.DEFAULTDOMAIN.getStatus().equals(defaultDomain)) {
-            //判断是否已存在默认域名,存在则不允许添加了
-            LambdaQueryWrapper<CdnDomain> query = Wrappers.lambdaQuery();
-            query.eq(CdnDomain::getDefaultDomain, defaultDomain);
-            int count = this.count(query);
-            if (count >= 1) {
-                throw new ResultException(500, "已存在默认域名,不能再次添加默认域名");
-            }
+        long count = this.count();
+        if (count <= 0) {
+            domain.setDefaultDomain(1);
+        } else {
+            domain.setDefaultDomain(0);
         }
         domain.setCreateBy(loginUser.getId());
         this.save(domain);
@@ -111,12 +116,169 @@ public class CdnDoaminServiceImpl extends ServiceImpl<CdnDomainMapper, CdnDomain
             //判断是否已存在默认域名,存在则不允许添加了
             LambdaQueryWrapper<CdnDomain> query = Wrappers.lambdaQuery();
             query.eq(CdnDomain::getDefaultDomain, defaultDomain).ne(CdnDomain::getId, domain.getId());
-            int count = this.count(query);
+            long count = this.count(query);
             if (count >= 1) {
                 throw new ResultException(500, "已存在默认域名,不能再次添加默认域名");
             }
         }
         this.updateById(domain);
+        domainOperatorMapper.updateDomainByDomainId(domain.getId(),domain.getDomain());
         return Result.success("操作成功");
     }
+
+    @Override
+    public Result getCdnByVideoId(String videoId, BigDecimal internetSpeed, String operatorName, HttpServletRequest request) {
+
+        //根据ip获取归属地
+        String requestIp = IpUtil.getRequestIp(request);
+        try {
+            requestIp = "27.37.0.1";
+            String cityInfo = IpUtil.getCityInfo(requestIp);
+            CdnDomain cdnDomain = new CdnDomain();
+            if (StringUtils.isNotBlank(cityInfo)) {
+                String[] split = cityInfo.split("\\|");
+                if (split.length >= 5) {
+                    //根据城市名获取域名信息
+                    String city = split[3].replaceAll("市", "");
+                    cdnDomain = getDomainByCityName(city);
+                    if (cdnDomain == null) {
+                        String operator = split[4];
+                        if (StringUtils.isBlank(operator)) {
+                            //根据城市没有获取到域名,根据运营商获取域名信息
+                            operator = operatorName;
+                        }
+                        cdnDomain = getDomainByOperator(operator);
+                        if (cdnDomain == null) {
+                            //根据运营商没有获取到域名,根据时间区间获取域名信息
+                            cdnDomain = getDomainByTimeRule();
+                            if (cdnDomain == null) {
+                                //根据时间没有获取到域名,获取默认域名
+                                LambdaQueryWrapper<CdnDomain> query = Wrappers.lambdaQuery();
+                                query.eq(CdnDomain::getDefaultDomain, 1);
+                                cdnDomain = domainMapper.selectOne(query);
+                            }
+                        }
+                    }
+                }
+                //获取ua
+                String header = request.getHeader("user-agent");
+                UserAgent userAgent = UserAgent.parseUserAgentString(header);
+                CdnUa uaByConfig = getUaByConfig(userAgent);
+                String ratio = "1024*768";
+                if (uaByConfig != null) {
+                    //根据配置+网速,生成对应分辨率
+                    Integer level = uaByConfig.getLevel();
+                    //计算分辨率
+                    level = countLevel(level, internetSpeed);
+                    if (DeviceUaLevel.HIGH.getLevel().equals(level)) {
+
+                        ratio = "1980*1080";
+                    } else if (DeviceUaLevel.MEDIUM.getLevel().equals(level)) {
+                        ratio = "1280*720";
+                    } else if (DeviceUaLevel.LOW.getLevel().equals(level)) {
+                        ratio = "1024*768";
+                    }
+                }
+                String m3u8Url = cdnDomain.getDomain() + "/" + ratio;
+
+                return Result.success(m3u8Url);
+            } else {
+                throw new ResultException(500, "根据ip地址获取城市信息失败");
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    private Integer countLevel(Integer level, BigDecimal internetSpeed) {
+        //网速分为三个档位
+        Integer speedLevel = 1;
+        if (internetSpeed.doubleValue() <= 100) {
+            speedLevel = 3;
+        } else if (100 < internetSpeed.doubleValue() && internetSpeed.doubleValue() < 500) {
+            speedLevel = 2;
+        }
+        if (level > speedLevel) {
+            return speedLevel;
+        } else {
+            return level;
+        }
+    }
+
+    /**
+     * 根据城市信息获取cdn
+     *
+     * @param city 城市名
+     * @return cdn
+     */
+    private CdnDomain getDomainByCityName(String city) {
+        log.info("根据城市名获取cdn,当前城市:{}", city);
+        return domainMapper.getDomainByCityName(city);
+    }
+
+    /**
+     * 根据
+     *
+     * @param operator 运营商
+     * @return cdn
+     */
+    private CdnDomain getDomainByOperator(String operator) {
+        log.info("根据运营商获取cdn,当前运营商:{}", operator);
+        return domainMapper.getDomainByOperator(operator);
+    }
+
+    /**
+     * 根据当前时间获取cdn
+     *
+     * @return cdn
+     */
+    private CdnDomain getDomainByTimeRule() {
+        Calendar cal = Calendar.getInstance();
+        int hours = cal.get(Calendar.HOUR_OF_DAY);
+        log.info("根据时间获取cdn,当前小时:{}", hours);
+        return domainMapper.getDomainByTimeRule(hours);
+    }
+
+    /**
+     * 根据当前浏览器ua,获取对应配置
+     *
+     * @param userAgent
+     * @return
+     */
+    private CdnUa getUaByConfig(UserAgent userAgent) {
+        LambdaQueryWrapper<CdnUa> query = Wrappers.lambdaQuery();
+        //获取浏览器对象
+        Browser browser = userAgent.getBrowser();
+        //获取操作系统对象
+        OperatingSystem operatingSystem = userAgent.getOperatingSystem();
+        Browser group = browser.getGroup();
+        String name = group.getName();
+        if (StringUtils.isNotBlank(name)) {
+            query.eq(CdnUa::getBrowser, name);
+        }
+        String version = userAgent.getBrowserVersion().getVersion();
+        if (StringUtils.isNotBlank(version)) {
+            query.eq(CdnUa::getBrowserVersion, version);
+        }
+        String os = operatingSystem.getGroup().getName();
+        if (StringUtils.isNotBlank(os)) {
+            query.eq(CdnUa::getOs, os);
+        }
+        log.info("获取到用户浏览器:{},浏览器版本:{},操作系统:{}", name, version, os);
+        query.orderByDesc(CdnUa::getCreateTime);
+        query.last("limit 0,1");
+        System.out.println("浏览器名:" + browser.getName());
+        System.out.println("浏览器类型:" + browser.getBrowserType());
+        System.out.println("浏览器家族:" + browser.getGroup());
+        System.out.println("浏览器生产厂商:" + browser.getManufacturer());
+        System.out.println("浏览器使用的渲染引擎:" + browser.getRenderingEngine());
+        System.out.println("浏览器版本:" + userAgent.getBrowserVersion());
+        System.out.println("操作系统名:" + operatingSystem.getName());
+        System.out.println("访问设备类型:" + operatingSystem.getDeviceType());
+        System.out.println("操作系统家族:" + operatingSystem.getGroup());
+        System.out.println("操作系统生产厂商:" + operatingSystem.getManufacturer());
+
+        return cdnUaMapper.selectOne(query);
+    }
 }

+ 7 - 1
mcp/src/main/java/com/chuanxia/mcp/service/impl/CdnOperatorServiceImpl.java

@@ -72,10 +72,16 @@ public class CdnOperatorServiceImpl extends ServiceImpl<CdnOperatorMapper, CdnOp
         SystemUser loginUser = userService.getLoginUser();
         List<CdnDomainOperator> arr = new ArrayList<>(operatorIds.size());
         for (Integer operatorId : operatorIds) {
+            CdnOperator cdnOperator = operatorMapper.selectById(operatorId);
+            if (cdnOperator == null) {
+                throw new ResultException(500, "运营商不存在");
+            }
             CdnDomainOperator domainOperator = new CdnDomainOperator();
             domainOperator.setOperatorId(operatorId);
             domainOperator.setDomainId(domainId);
+            domainOperator.setDomain(domain.getDomain());
             domainOperator.setCreateBy(loginUser.getId());
+            domainOperator.setOperatorName(cdnOperator.getOperatorName());
             arr.add(domainOperator);
         }
         LambdaQueryWrapper<CdnDomainOperator> del = Wrappers.lambdaQuery();
@@ -87,7 +93,7 @@ public class CdnOperatorServiceImpl extends ServiceImpl<CdnOperatorMapper, CdnOp
 
     @Override
     public Result<IPage<CdnOperatorVo>> listPage(OperatorQueryDto queryDto) {
-        IPage<CdnOperatorVo> page = new Page<>(queryDto.getPageSize(), queryDto.getPageNum());
+        IPage<CdnOperatorVo> page = new Page<>(queryDto.getPageNum(), queryDto.getPageSize());
         page = domainOperatorService.listPage(page, queryDto);
         return Result.success(page);
     }

+ 7 - 1
mcp/src/main/java/com/chuanxia/mcp/service/impl/CdnTimeRuleServiceImpl.java

@@ -61,7 +61,13 @@ public class CdnTimeRuleServiceImpl extends ServiceImpl<CdnTimeRuleMapper, CdnTi
     @Override
     public Result<IPage<CdnDomainTimeRuleVo>> listPage(DomainTimeRuleQueryDto queryDto) {
         IPage<CdnDomainTimeRuleVo> page = new Page<>(queryDto.getPageNum(), queryDto.getPageSize());
-        page = domainTimeRuleMapper.listPage(page,queryDto);
+        page = domainTimeRuleMapper.listPage(page, queryDto);
         return Result.success(page);
     }
+
+    @Override
+    public Result deleteById(Integer id) {
+        domainTimeRuleMapper.deleteById(id);
+        return Result.success();
+    }
 }

+ 64 - 0
mcp/src/main/java/com/chuanxia/mcp/service/impl/CdnUaServiceImpl.java

@@ -0,0 +1,64 @@
+package com.chuanxia.mcp.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.chuanxia.mcp.bean.dto.UaQueryDto;
+import com.chuanxia.mcp.bean.model.CdnUa;
+import com.chuanxia.mcp.bean.vo.Result;
+import com.chuanxia.mcp.mapper.CdnUaMapper;
+import com.chuanxia.mcp.service.CdnUaService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@RequiredArgsConstructor
+@Service
+@Slf4j
+public class CdnUaServiceImpl extends ServiceImpl<CdnUaMapper, CdnUa> implements CdnUaService {
+    private final CdnUaMapper cdnUaMapper;
+
+    @Override
+    public Result<IPage<CdnUa>> listPage(UaQueryDto queryDto) {
+        IPage<CdnUa> page = new Page<>(queryDto.getPageNum(), queryDto.getPageSize());
+        LambdaQueryWrapper<CdnUa> query = Wrappers.lambdaQuery();
+        String browser = queryDto.getBrowser();
+        String browserVersion = queryDto.getBrowserVersion();
+        String device = queryDto.getDevice();
+        Integer level = queryDto.getLevel();
+        String os = queryDto.getOs();
+
+        if (StringUtils.isNotBlank(browser)) {
+            query.eq(CdnUa::getBrowser, browser);
+        }
+        if (StringUtils.isNotBlank(browserVersion)) {
+            query.eq(CdnUa::getBrowserVersion, browserVersion);
+        }
+        if (StringUtils.isNotBlank(os)) {
+            query.eq(CdnUa::getOs, os);
+        }
+        if (level != null) {
+            query.eq(CdnUa::getLevel, level);
+        }
+        page = cdnUaMapper.selectPage(page, query);
+        return Result.success(page);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public Result<String> saveUa(CdnUa ua) {
+        cdnUaMapper.insert(ua);
+        return Result.success("操作成功");
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Result<String> updateUa(CdnUa ua) {
+        cdnUaMapper.updateById(ua);
+        return Result.success("操作成功");
+    }
+}

+ 115 - 0
mcp/src/main/java/com/chuanxia/mcp/util/IpUtil.java

@@ -0,0 +1,115 @@
+package com.chuanxia.mcp.util;
+
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.util.StrUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.lionsoul.ip2region.xdb.Searcher;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.InputStream;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * 获取IP地址工具类
+ *
+ * @author geekidea
+ * @date 2018-11-08
+ */
+
+@Slf4j
+public final class IpUtil {
+
+    private static final String UNKNOWN = "unknown";
+    private static final String IPV6_LOCAL = "0:0:0:0:0:0:0:1";
+
+    private IpUtil() {
+        throw new AssertionError();
+    }
+
+    /**
+     * 获取请求用户的IP地址
+     *
+     * @return
+     */
+    public static String getRequestIp() {
+        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        HttpServletRequest request = attributes.getRequest();
+        return getRequestIp(request);
+    }
+
+    /**
+     * 获取请求用户的IP地址
+     *
+     * @param request
+     * @return
+     */
+    public static String getRequestIp(HttpServletRequest request) {
+        String ip = request.getHeader("x-forwarded-for");
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("Proxy-Client-IP");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("WL-Proxy-Client-IP");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("HTTP_CLIENT_IP");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getRemoteAddr();
+            if (ip.equals("127.0.0.1") || ip.equals("0:0:0:0:0:0:0:1")) {
+                // 根据网卡取本机配置的IP
+                InetAddress inet = null;
+                try {
+                    inet = InetAddress.getLocalHost();
+                } catch (UnknownHostException e) {
+                    e.printStackTrace();
+                }
+                ip = inet.getHostAddress();
+            }
+        }
+        // 多个代理的情况,第一个IP为客户端真实IP,多个IP按照“,”分割
+        if (ip != null && ip.length() > 15) {
+            if (ip.indexOf(",") > 0) {
+                ip = ip.substring(0, ip.indexOf(","));
+            }
+        }
+        return ip;
+    }
+
+    /**
+     * 获取城市信息(如果后面ip2region.db有更新,https://github.com/lionsoul2014/ip2region)
+     *
+     * @param ip ip
+     * @return
+     */
+    public static String getCityInfo(String ip) throws Exception {
+        // 获取ip库路径
+        ClassPathResource classPathResource = new ClassPathResource("ip2region.xdb");
+        if (classPathResource.getClassLoader() == null) {
+            log.error("存储路径发生错误,没有被发现");
+            return null;
+        }
+        InputStream inputStream = classPathResource.getInputStream();
+        byte[] bytes = IoUtil.readBytes(inputStream);
+        Searcher searcher = Searcher.newWithBuffer(bytes);
+
+        //Searcher searcher = Searcher.newWithFileOnly(dbPath);
+        String result = searcher.search(ip);
+        if (StrUtil.isEmpty(result)) {
+            log.error("获取地理位置异常 {}", ip);
+            return "XX-XX-XX";
+        }
+        searcher.close();
+        return result;
+    }
+
+
+}
+

+ 22 - 0
mcp/src/main/java/com/chuanxia/mcp/util/M3U8Parser.java

@@ -0,0 +1,22 @@
+package com.chuanxia.mcp.util;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+
+public class M3U8Parser {
+    public static void main(String[] args) {
+        String filePath = "D:\\duoma.m3u8";
+
+        try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
+            String line;
+            while ((line = reader.readLine()) != null) {
+                System.out.println(line);
+               /* if (line.startsWith("http")) {
+                }*/
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 269 - 0
mcp/src/main/java/com/chuanxia/mcp/util/M3u8DownloadFactory.java

@@ -0,0 +1,269 @@
+package com.chuanxia.mcp.util;
+
+import com.chuanxia.mcp.exception.ResultException;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.*;
+ 
+/**
+ * @Description  m3u8解析
+ * @project
+ * @author:hf
+ * @date:
+ */
+@Slf4j
+public class M3u8DownloadFactory {
+ 
+ 
+    //重试次数
+    private static int retryCount = 30;
+ 
+    //链接连接超时时间(单位:毫秒)
+    private static long timeoutMillisecond = 1000L;
+ 
+    //密钥字节
+    private static byte[] keyBytes = new byte[16];
+ 
+    //自定义请求头
+    private static Map<String, Object> requestHeaderMap = new HashMap<>();
+ 
+ 
+    /**
+     * 获取所有的ts片段下载链接
+     *
+     * @return 链接是否被加密,null为非加密
+     */
+    private static  Map getTsUrl(String url) {
+        StringBuilder content = getUrlContent(url, false);
+        //判断是否是m3u8链接
+        if (!content.toString().contains("#EXTM3U")){
+            throw new ResultException(500,url + "不是m3u8链接!");
+        }
+        String[] split = content.toString().split("\\n");
+        String keyUrl = "";
+        boolean isKey = false;
+        for (String s : split) {
+            //如果含有此字段,则说明只有一层m3u8链接
+            if (s.contains("#EXT-X-KEY") || s.contains("#EXTINF")) {
+                isKey = true;
+                keyUrl = url;
+                break;
+            }
+        }
+        if (StringUtils.isEmpty(keyUrl)){
+            throw new ResultException(500,"未发现key链接!");
+        }
+        //获取密钥
+        Map key = isKey ? getKey(keyUrl, content) : getKey(keyUrl, null);
+ 
+        return key;
+    }
+ 
+    /**
+     * @Description: 判断是否是为url链接
+     * @Author: hf
+     * @Time: 2021/7/13 16:44
+     */
+    public static boolean isUrl(String str) {
+        if (StringUtils.isEmpty(str)){
+            return false;
+        }
+        str = str.trim();
+        return str.matches("^(http|https)://.+");
+    }
+    /**
+     * @Description:
+     * @Return:
+     * @Author: hf
+     * @Time: 2021/7/13 16:44
+     */
+    private static String mergeUrl(String start, String end) {
+        if (end.startsWith("/")){
+            end = end.replaceFirst("/", "");
+        }
+        int position = 0;
+        String subEnd, tempEnd = end;
+        while ((position = end.indexOf("/", position)) != -1) {
+            subEnd = end.substring(0, position + 1);
+            if (start.endsWith(subEnd)) {
+                tempEnd = end.replaceFirst(subEnd, "");
+                break;
+            }
+            ++position;
+        }
+        return start + tempEnd;
+    }
+  /**
+   * @Description:
+   * @param url     密钥链接,如果无密钥的m3u8,则此字段可为空
+   * @param content 内容,如果有密钥,则此字段可以为空
+   * @Return:
+   * @Author: hf
+   * @Time: 2021/7/13 16:44
+   */
+    private static Map getKey(String url, StringBuilder content) {
+        Map<String,String> map=new HashMap<String,String>();
+        StringBuilder urlContent;
+        if (content == null || StringUtils.isEmpty(content.toString())){
+            urlContent = getUrlContent(url, false);
+        }else{
+            urlContent = content;
+        }
+        if (!urlContent.toString().contains("#EXTM3U")){
+            throw new ResultException(500,url + "不是m3u8链接!");
+        }
+        String method=null;
+        String keyUrl=null;
+        String iv=null;
+        String[] split = urlContent.toString().split("\\n");
+        for (String s : split) {
+            //如果含有此字段,则获取加密算法以及获取密钥的链接
+            if (s.contains("EXT-X-KEY")) {
+                String[] split1 = s.split(",");
+                for (String s1 : split1) {
+                    if (s1.contains("METHOD")) {
+                        method = s1.split("=", 2)[1];
+                        map.put("method",method);
+                        continue;
+                    }
+                    if (s1.contains("URI")) {
+                        keyUrl = s1.split("=", 2)[1];
+                        continue;
+                    }
+                    if (s1.contains("IV")){
+                        iv = s1.split("=", 2)[1];
+                        map.put("iv",iv);
+                    }
+                }
+                //只需要 key和vi 直接结束循环
+                break;
+            }
+        }
+        String aesKey=null;
+        String relativeUrl = url.substring(0, url.lastIndexOf("/") + 1);
+        if (!StringUtils.isEmpty(keyUrl)) {
+            keyUrl = keyUrl.replace("\"", "");
+            aesKey= getUrlContent(isUrl(keyUrl) ? keyUrl : mergeUrl(relativeUrl, keyUrl), true).toString().replaceAll("\\s+", "");
+            map.put("aesKey",aesKey);
+        }
+        return map;
+    }
+  /**
+   * @Description:
+   * @param urls  http链接
+   * @param isKey 这个url链接是否用于获取key
+   * @Return:
+   * @Author: hf
+   * @Time: 2021/7/13 16:43
+   */
+    private static StringBuilder getUrlContent(String urls, boolean isKey) {
+        int count = 1;
+        HttpURLConnection httpURLConnection = null;
+        StringBuilder content = new StringBuilder();
+        while (count <= retryCount) {
+            try {
+                URL url = new URL(urls);
+                httpURLConnection = (HttpURLConnection) url.openConnection();
+                httpURLConnection.setConnectTimeout((int) timeoutMillisecond);
+                httpURLConnection.setReadTimeout((int) timeoutMillisecond);
+                httpURLConnection.setUseCaches(false);
+                httpURLConnection.setDoInput(true);
+                for (Map.Entry<String, Object> entry : requestHeaderMap.entrySet()){
+                    httpURLConnection.addRequestProperty(entry.getKey(), entry.getValue().toString());
+                }
+                String line;
+                InputStream inputStream = httpURLConnection.getInputStream();
+                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
+                //这个url链接是否用于获取key
+                if (isKey) {
+                    byte[] bytes = new byte[128];
+                    int len;
+                    len = inputStream.read(bytes);
+                    if (len == 1 << 4) {
+                        keyBytes = Arrays.copyOf(bytes, 16);
+                        String aesKey= bytesTohex(keyBytes);
+                        content.append(aesKey);
+                    } else{
+                        content.append(new String(Arrays.copyOf(bytes, len)));
+                    }
+                    return content;
+                }
+                while ((line = bufferedReader.readLine()) != null){
+                    content.append(line).append("\n");
+                }
+                bufferedReader.close();
+                inputStream.close();
+                //log.info(content.toString());
+                break;
+            } catch (Exception e) {
+                log.error("第" + count + "获取链接重试!\t" + urls+";"+e.getMessage());
+                count++;
+            } finally {
+                if (httpURLConnection != null) {
+                    httpURLConnection.disconnect();
+                }
+            }
+        }
+        if (count > retryCount){
+            throw new ResultException(500,"连接超时!");
+        }
+        return content;
+     }
+    /**
+     * @Description: 转16进制
+     * @Author: hf
+     * @Time: 2021/7/13 16:35
+     */
+    public static  String bytesTohex(byte[] bytes) {
+        StringBuilder hex = new StringBuilder();
+        for (int i = 0; i < bytes.length; i++) {
+            byte b = bytes[i];
+            boolean flag = false;
+            if(b < 0){
+                flag = true;
+            }
+            int absB = Math.abs(b);
+            if(flag){
+                absB = absB | 0x80;
+            }
+           // System.out.println(absB & 0xFF);
+            String tmp = Integer.toHexString(absB & 0xFF);
+            //转化的十六进制不足两位,需要补0
+            if (tmp.length() == 1) {
+                hex.append("0");
+            }
+            hex.append(tmp.toUpperCase());
+            if(i!=bytes.length-1){
+                hex.append(" ");
+            }
+        }
+        return hex.toString();
+    }
+    public static void main(String[] args) {
+        String url="xxxx.m3u8";
+        System.out.println("getTsUrl:"+getTsUrl(url));
+    }
+    /**
+     * @Description: 获取16进制随机数
+     * @Author: hf
+     * @Time: 2021/7/13 10:49
+     */
+    public static String randomHexString(int len) {
+        try {
+            StringBuffer result = new StringBuffer();
+            for (int i = 1; i <= len; i++) {
+                result.append(Integer.toHexString(new Random().nextInt(16)));
+                if(i%2==0 && i!=len){
+                    result.append(" ");
+                }
+            }
+            return result.toString().toUpperCase();
+        } catch (Exception e) {
+            log.error(e.getMessage());
+        }
+        return null;
+    }
+}

+ 57 - 0
mcp/src/main/resources/com/chuanxia/mcp/mapper/CdnDomainMapper.xml

@@ -0,0 +1,57 @@
+<?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 namespace="com.chuanxia.mcp.mapper.CdnDomainMapper">
+
+    <select id="getDomainByCityName" resultType="com.chuanxia.mcp.bean.model.CdnDomain">
+        SELECT
+  cd.id,
+  cd.domain,
+  cd.manufacturer,
+  cd.default_domain as defaultDomain,
+  cd.create_time as createTime,
+  cd.update_time as updateTime,
+  cd.create_by as createBy,
+  cd.update_by as updateBy
+FROM
+  `cdn_city` cc
+  LEFT JOIN `cdn_domain_city` cdc
+    ON cc.`id` = cdc.`city_id`
+  LEFT JOIN `cdn_domain` cd
+    ON cdc.`domain_id` = cd.`id`
+    WHERE cc.`cname` = #{city}
+    LIMIT 0,1
+    </select>
+    <select id="getDomainByOperator" resultType="com.chuanxia.mcp.bean.model.CdnDomain">
+SELECT
+  cd.id,
+  cd.domain,
+  cd.manufacturer,
+  cd.default_domain as defaultDomain,
+  cd.create_time as createTime,
+  cd.update_time as updateTime,
+  cd.create_by as createBy,
+  cd.update_by as updateBy
+FROM
+  `cdn_operator` co
+  LEFT JOIN `cdn_domain_operator` cdo
+    ON co.`id` = cdo.`operator_id`
+  LEFT JOIN `cdn_domain` cd
+    ON cdo.`domain_id` = cd.`id`
+   WHERE co.`operator_name` = #{operator}
+   limit 0,1
+    </select>
+    <select id="getDomainByTimeRule" resultType="com.chuanxia.mcp.bean.model.CdnDomain">
+        SELECT
+        *
+        FROM
+        `cdn_time_rule` ctr
+        LEFT JOIN `cdn_domain_time_rule` cdtr
+        ON ctr.`id` = cdtr.`id`
+        LEFT JOIN `cdn_domain` cd
+        ON cdtr.`domain_id` = cd.`id`
+        WHERE ctr.`start_time` &lt;= #{hours} and ctr.`end_time` &gt;= #{hours}
+        order by end_time desc limit 0,1
+    </select>
+</mapper>

+ 13 - 13
mcp/src/main/resources/com/chuanxia/mcp/mapper/CdnDomainOperatorMapper.xml

@@ -3,26 +3,26 @@
         "-//mybatis.org//DTD Mapper 3.0//EN"
         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.chuanxia.mcp.mapper.CdnDomainOperatorMapper">
+    <update id="updateDomainByDomainId">
+        update cdn_domain_operator set `domain` = #{domain}  where domain_id = #{domainId};
+    </update>
     <select id="listPage" resultType="com.chuanxia.mcp.bean.vo.CdnOperatorVo">
         SELECT
-        cdo.`id`,
-        cdo.`domain_id` AS domainId,
-        cdo.`operator_id` AS operatorId,
-        co.`operator_name` AS operatorName,
-        cd.`domain`,
-        cdo.`create_by` AS createBy,
-        cdo.`create_time` AS createTime
+        `id`,
+        `domain_id` as domainId,
+        `operator_id` AS operatorId,
+        `operator_name` AS operatorName,
+        `domain`,
+        `create_by` AS createBy,
+        `create_time` AS createTime
         FROM
         `cdn_domain_operator` cdo
-        LEFT JOIN `cdn_operator` co
-        ON cdo.`operator_id` = co.`id`
-        LEFT JOIN `cdn_domain` cd
-        ON cdo.`domain_id` = cd.`id`
         <if test="queryDto.operatorName != null and queryDto.operatorName!='' ">
-        and co.operator_name = #{queryDto.operatorName}
+            and operator_name = #{queryDto.operatorName}
         </if>
         <if test="queryDto.domain != null and queryDto.domain!='' ">
-            and cd.domain = #{queryDto.domain}
+            and `domain` = #{queryDto.domain}
         </if>
+        order by create_time desc
     </select>
 </mapper>

BIN
mcp/src/main/resources/ip2region.xdb