getVodPlayDay(Long classId, Long memberId, Date endDate);
+ double getStudyTotal();
+
+ double getSubsidyStudyTotal();
+
+ int getStudyHistoryNum();
}
diff --git a/src/main/java/com/subsidy/service/CompanyDictService.java b/src/main/java/com/subsidy/service/CompanyDictService.java
index 29b31d1..c426f53 100644
--- a/src/main/java/com/subsidy/service/CompanyDictService.java
+++ b/src/main/java/com/subsidy/service/CompanyDictService.java
@@ -1,17 +1,23 @@
package com.subsidy.service;
+import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.subsidy.dto.administer.OperatorsDTO;
import com.subsidy.dto.company.AddCompanyDTO;
+import com.subsidy.dto.company.DataOverviewDTO;
import com.subsidy.dto.company.GetCompanyMembersDTO;
import com.subsidy.model.CompanyDictDO;
import com.subsidy.model.MemberDO;
import com.subsidy.vo.administer.OperatorsVO;
+import com.subsidy.vo.company.CDNStatDetailsVO;
+import com.subsidy.vo.company.DataOverviewVO;
import com.subsidy.vo.company.GetAllCompanyVO;
import com.subsidy.vo.company.GetCompanyMembersVO;
+import com.tencentcloudapi.vod.v20180717.models.StatDataItem;
import java.util.List;
+import java.util.Map;
/**
*
@@ -35,4 +41,9 @@ public interface CompanyDictService extends IService {
IPage getCompanyMembers(GetCompanyMembersDTO getCompanyMembersDTO);
+ DataOverviewVO getCompanyDataOverview();
+
+ List getCDNBandwidthStatDetails();
+
+ List getCDNFluxStatDetails();
}
diff --git a/src/main/java/com/subsidy/service/impl/AdministerServiceImpl.java b/src/main/java/com/subsidy/service/impl/AdministerServiceImpl.java
index 7a16a08..3dd0bb7 100644
--- a/src/main/java/com/subsidy/service/impl/AdministerServiceImpl.java
+++ b/src/main/java/com/subsidy/service/impl/AdministerServiceImpl.java
@@ -44,7 +44,6 @@ import com.subsidy.model.MemberDepartmentMappingDO;
import com.subsidy.model.OprAdmDictDO;
import com.subsidy.model.PaperDictDO;
import com.subsidy.model.RoleAdministerMappingDO;
-import com.subsidy.model.RoleDictDO;
import com.subsidy.model.SignInRecordDO;
import com.subsidy.model.VodDictDO;
import com.subsidy.service.AdministerService;
@@ -86,12 +85,12 @@ import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;
-
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
@@ -115,7 +114,6 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
-
/**
*
* 管理平台用户 服务实现类
@@ -175,9 +173,6 @@ public class AdministerServiceImpl extends ServiceImpl operators(OperatorsDTO operatorsDTO) {
Page pager = new Page(operatorsDTO.getPageNum(), operatorsDTO.getPageSize());
@@ -258,5 +286,108 @@ public class CompanyDictServiceImpl extends ServiceImpl());
+ /* 机构数量 */
+ dataOverviewVO.setCompanyNum(companyNum);
+
+ List memberList = memberMapper.selectList(new QueryWrapper<>());
+ if(CollectionUtils.isNotEmpty(memberList)) {
+ int realNameNum = (int) memberList.stream().filter(m -> StringUtils.isNotBlank(m.getIdCard())).count();
+ /* 注册人数 */
+ dataOverviewVO.setRegistrantsNum(memberList.size());
+ /* 实名注册人数 */
+ dataOverviewVO.setRealNameNum(realNameNum);
+ }
+ /* 培训项目数量 */
+ int classNum = classDictMapper.getClassCount();
+ dataOverviewVO.setClassNum(classNum);
+
+ List courseList = courseDictMapper.selectList(new QueryWrapper<>());
+ if(CollectionUtils.isNotEmpty(courseList)) {
+ /* 资源数量 */
+ dataOverviewVO.setCourseNum(courseList.size());
+
+ /* 专项资源数量 */
+ int subsidyCourseNum = (int) courseList.stream().filter(courseDictDO -> StringUtils.isNotBlank(courseDictDO.getCourseType()) &&
+ courseDictDO.getCourseType().equals("补贴培训")).count();
+ dataOverviewVO.setSubsidyCourseNum(subsidyCourseNum);
+ }
+
+ /* 累计学习时长(小时) */
+ double studyTotal = vodPlayHistoryMapper.getStudyTotal();
+ if(studyTotal > 0) {
+ dataOverviewVO.setStudyTotal(new BigDecimal(studyTotal).divide(new BigDecimal(Math.pow(60, 2)), 2, BigDecimal.ROUND_UP).doubleValue());
+ }
+
+ /* 专项资源时(小时) */
+ double subsidyStudyTotal = vodPlayHistoryMapper.getSubsidyStudyTotal();
+ if(subsidyStudyTotal > 0) {
+ dataOverviewVO.setSubsidyStudyTotal(new BigDecimal(subsidyStudyTotal).divide(new BigDecimal(Math.pow(60,2)), 2, BigDecimal.ROUND_UP).doubleValue());
+ }
+
+ /* 学习过程记录人次 */
+ int studyHistoryNum = vodPlayHistoryMapper.getStudyHistoryNum();
+ dataOverviewVO.setStudyHistoryNum(studyHistoryNum);
+ return dataOverviewVO;
+ }
+
+ @Override
+ public List getCDNBandwidthStatDetails() {
+ /*
+ * 根据今天时间查询七天前的数据
+ * 先从缓存中获取数据,如果缓存中没有数据,从远程请求中获取, 避免频繁请求
+ * 缓存28800秒(8小时)失效,重新远程请求更新数据
+ */
+ List data = new ArrayList<>();
+ if(EhCacheUtil.getEhCache(VodConstant.CDN_STAT_DETAILS_CACHE_NAME, VodConstant.BANDWIDTH_CACHE_KEY) != null) {
+ return (List) EhCacheUtil.getEhCache(VodConstant.CDN_STAT_DETAILS_CACHE_NAME, VodConstant.BANDWIDTH_CACHE_KEY);
+ } else {
+ String startDate =LocalDateTime.now().minusDays(6).withNano(0)+"+08:00";
+ String endDate = LocalDateTime.now().withNano(0)+"+08:00";
+ StatDataItem[] statDataItems = VodUtil.DescribeCDNStatDetails(vodConfig, VodConstant.BANDWIDTH ,startDate, endDate);
+ for (StatDataItem statDataItem : statDataItems) {
+ CDNStatDetailsVO sd = new CDNStatDetailsVO();
+ LocalDateTime localDateTime = LocalDateTime.parse(statDataItem.getTime().replace("+08:00",""));
+ Date date = DateFormatUtil.localDateTimeToDate(localDateTime);
+ sd.setTime(DateFormatUtil.format(date, DateFormatUtil.FMT_sdf_yMd));
+ BigDecimal bigDecimal = new BigDecimal(statDataItem.getValue()).divide(new BigDecimal(1000000));
+ sd.setValue(bigDecimal.setScale(2, BigDecimal.ROUND_UP));
+ data.add(sd);
+ }
+ EhCacheUtil.putEhCache(VodConstant.CDN_STAT_DETAILS_CACHE_NAME, VodConstant.BANDWIDTH_CACHE_KEY, data);
+ return data;
+ }
+ }
+
+ @Override
+ public List getCDNFluxStatDetails() {
+ /*
+ * 根据今天时间查询七天前的数据
+ * 先从缓存中获取数据,如果缓存中没有数据,从远程请求中获取,避免频繁请求
+ * 缓存28800秒(8小时)失效,重新远程请求更新数据
+ */
+ List data = new ArrayList<>();
+ if(EhCacheUtil.getEhCache(VodConstant.CDN_STAT_DETAILS_CACHE_NAME, VodConstant.FLUX_CACHE_KEY) != null) {
+ return (List) EhCacheUtil.getEhCache(VodConstant.CDN_STAT_DETAILS_CACHE_NAME, VodConstant.FLUX_CACHE_KEY);
+ } else {
+ String startDate =LocalDateTime.now().minusDays(6).withNano(0)+"+08:00";
+ String endDate = LocalDateTime.now().withNano(0)+"+08:00";
+ StatDataItem[] statDataItems = VodUtil.DescribeCDNStatDetails(vodConfig, VodConstant.FLUX ,startDate, endDate);
+ for (StatDataItem statDataItem : statDataItems) {
+ CDNStatDetailsVO sd = new CDNStatDetailsVO();
+ LocalDateTime localDateTime = LocalDateTime.parse(statDataItem.getTime().replace("+08:00",""));
+ Date date = DateFormatUtil.localDateTimeToDate(localDateTime);
+ sd.setTime(DateFormatUtil.format(date, DateFormatUtil.FMT_sdf_yMd));
+ BigDecimal bigDecimal = new BigDecimal(statDataItem.getValue()).divide(new BigDecimal(Math.pow(1000, 3)));
+ sd.setValue(bigDecimal.setScale(2, BigDecimal.ROUND_UP));
+ data.add(sd);
+ }
+ EhCacheUtil.putEhCache(VodConstant.CDN_STAT_DETAILS_CACHE_NAME, VodConstant.FLUX_CACHE_KEY, data);
+ return data;
+ }
+ }
}
diff --git a/src/main/java/com/subsidy/service/impl/VodDictServiceImpl.java b/src/main/java/com/subsidy/service/impl/VodDictServiceImpl.java
index efa8cd4..b8168e1 100644
--- a/src/main/java/com/subsidy/service/impl/VodDictServiceImpl.java
+++ b/src/main/java/com/subsidy/service/impl/VodDictServiceImpl.java
@@ -66,9 +66,9 @@ public class VodDictServiceImpl extends ServiceImpl im
if(null == vod) {
throw new HttpException(18000);
}
- this.baseMapper.deleteById(vodDictDO.getId());
- VodUtil.deleteMedia(vodDictDO.getVodCode());
+ this.baseMapper.deleteById(vodDictDO.getId());
+ VodUtil.deleteMedia(vodConfig, vodDictDO.getVodCode());
}
@Override
@@ -85,12 +85,13 @@ public class VodDictServiceImpl extends ServiceImpl im
orderNo = vod.getOrderNo() + 1;
}
}
+
vodDictDO.setOrderNo(orderNo);
this.baseMapper.insert(vodDictDO);
//测试环境就不转码了
if (env.equals("prod")){
- VodUtil.processMedia(vodDictDO.getVodCode());
+ VodUtil.processMedia(vodConfig, vodDictDO.getVodCode());
}
}
diff --git a/src/main/java/com/subsidy/util/EhCacheUtil.java b/src/main/java/com/subsidy/util/EhCacheUtil.java
new file mode 100644
index 0000000..45dba17
--- /dev/null
+++ b/src/main/java/com/subsidy/util/EhCacheUtil.java
@@ -0,0 +1,53 @@
+package com.subsidy.util;
+
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.CacheManager;
+import net.sf.ehcache.Element;
+import org.springframework.util.ClassUtils;
+
+/**
+ *
+ * Ehcache
+ *
+ *
+ * @author DengMin
+ * @since 2022/8/1
+ */
+public class EhCacheUtil {
+
+ static CacheManager cacheManager = CacheManager.newInstance(ClassUtils.getDefaultClassLoader().getResource("").getPath()+"ehcache.xml");
+
+ /**
+ * 添加缓存
+ * @param cacheName
+ * @param key
+ * @param value
+ */
+ public static void putEhCache(String cacheName, String key, Object value) {
+ Cache cache = cacheManager.getCache(cacheName);
+ Element element = new Element(key, value);
+ cache.put(element);
+ }
+
+ /**
+ * 获取缓存数据
+ * @param cacheName
+ * @param key
+ * @return
+ */
+ public static Object getEhCache(String cacheName, String key) {
+ Cache cache = cacheManager.getCache(cacheName);
+ Element element = cache.get(key);
+ return element == null ? null : element.getObjectValue();
+ }
+
+ /**
+ * 删除缓存
+ * @param cacheName
+ * @param key
+ */
+ public static void deleteEhCache(String cacheName, String key) {
+ Cache cache = cacheManager.getCache(cacheName);
+ cache.remove(key);
+ }
+}
diff --git a/src/main/java/com/subsidy/util/VodUtil.java b/src/main/java/com/subsidy/util/VodUtil.java
index 9676482..79c3da0 100644
--- a/src/main/java/com/subsidy/util/VodUtil.java
+++ b/src/main/java/com/subsidy/util/VodUtil.java
@@ -6,21 +6,28 @@ import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
-import com.tencentcloudapi.cvm.v20170312.models.DescribeZonesResponse;
import com.tencentcloudapi.vod.v20180717.VodClient;
import com.tencentcloudapi.vod.v20180717.models.DeleteMediaRequest;
+import com.tencentcloudapi.vod.v20180717.models.DescribeCDNUsageDataRequest;
+import com.tencentcloudapi.vod.v20180717.models.DescribeCDNUsageDataResponse;
import com.tencentcloudapi.vod.v20180717.models.MediaProcessTaskInput;
import com.tencentcloudapi.vod.v20180717.models.ProcessMediaRequest;
import com.tencentcloudapi.vod.v20180717.models.ProcessMediaResponse;
+import com.tencentcloudapi.vod.v20180717.models.StatDataItem;
import com.tencentcloudapi.vod.v20180717.models.TranscodeTaskInput;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+/**
+ *
+ * 腾讯云 - 云点播API
+ *
+ *
+ * @author DengMin
+ * @since 2022/8/1
+ */
+@Component
public class VodUtil {
- @Autowired
- private static VODConfig vodConfig;
-
private static String endpoint = "vod.tencentcloudapi.com";
/**
@@ -28,7 +35,7 @@ public class VodUtil {
* @param vodCode
* @return
*/
- public static ProcessMediaResponse processMedia(String vodCode) {
+ public static ProcessMediaResponse processMedia(VODConfig vodConfig, String vodCode) {
try {
//上传后直接转码
Credential cred = new Credential(vodConfig.getSecretId(), vodConfig.getSecretKey());
@@ -59,7 +66,7 @@ public class VodUtil {
* 删除腾讯云上原视频
* @param vodCode
*/
- public static void deleteMedia(String vodCode) {
+ public static void deleteMedia(VODConfig vodConfig, String vodCode) {
try {
//删除原视频
Credential cred = new Credential(vodConfig.getSecretId(), vodConfig.getSecretKey());
@@ -76,6 +83,41 @@ public class VodUtil {
// 返回的resp是一个DeleteMediaResponse的实例,与请求对象对应
client.DeleteMedia(req);
} catch (TencentCloudSDKException e) {
+ throw new HttpException(99999, e.getMessage());
+ }
+ }
+
+ /**
+ * 云点播域名的CDN统计数据
+ * @param vodConfig
+ * @param DataType
+ * @param startTime
+ * @param endTime
+ * @return
+ */
+ public static StatDataItem[] DescribeCDNStatDetails(VODConfig vodConfig, String DataType, String startTime, String endTime) {
+ try {
+ Credential cred = new Credential(vodConfig.getSecretId(), vodConfig.getSecretKey());
+ // 实例化一个http选项,可选的,没有特殊需求可以跳过
+ HttpProfile httpProfile = new HttpProfile();
+ httpProfile.setEndpoint(endpoint);
+ // 实例化一个client选项,可选的,没有特殊需求可以跳过
+ ClientProfile clientProfile = new ClientProfile();
+ clientProfile.setHttpProfile(httpProfile);
+ // 实例化要请求产品的client对象,clientProfile是可选的
+ VodClient client = new VodClient(cred, "", clientProfile);
+ // 实例化一个请求对象,每个接口都会对应一个request对象
+ DescribeCDNUsageDataRequest req = new DescribeCDNUsageDataRequest();
+ req.setStartTime(startTime);
+ req.setEndTime(endTime);
+ req.setDataType(DataType);
+ // 返回的resp是一个DescribeCDNUsageDataResponse的实例,与请求对象对应
+ DescribeCDNUsageDataResponse resp = client.DescribeCDNUsageData(req);
+ // 返回的resp是一个DescribeCDNStatDetailsResponse的实例,与请求对象对应
+ return resp.getData();
+ } catch (TencentCloudSDKException e) {
+ e.printStackTrace();
+ throw new HttpException(99999, e.getMessage());
}
}
}
diff --git a/src/main/java/com/subsidy/vo/company/CDNStatDetailsVO.java b/src/main/java/com/subsidy/vo/company/CDNStatDetailsVO.java
new file mode 100644
index 0000000..e44bd66
--- /dev/null
+++ b/src/main/java/com/subsidy/vo/company/CDNStatDetailsVO.java
@@ -0,0 +1,13 @@
+package com.subsidy.vo.company;
+
+import lombok.Data;
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+@Data
+public class CDNStatDetailsVO implements Serializable {
+
+ private String time;
+
+ private BigDecimal value;
+}
diff --git a/src/main/java/com/subsidy/vo/company/DataOverviewVO.java b/src/main/java/com/subsidy/vo/company/DataOverviewVO.java
new file mode 100644
index 0000000..41be8a7
--- /dev/null
+++ b/src/main/java/com/subsidy/vo/company/DataOverviewVO.java
@@ -0,0 +1,53 @@
+package com.subsidy.vo.company;
+
+import lombok.Data;
+
+@Data
+public class DataOverviewVO {
+
+ /**
+ * 机构数
+ */
+ private Integer companyNum;
+
+ /**
+ * 注册人数
+ */
+ private Integer registrantsNum;
+
+ /**
+ * 实名制注册人数
+ */
+ private Integer realNameNum;
+
+ /**
+ * 培训项目数量
+ */
+ private Integer classNum;
+
+ /**
+ * 资源数量
+ */
+ private Integer courseNum;
+
+ /**
+ * 学习过程记录人次
+ */
+ private Integer studyHistoryNum;
+
+ /**
+ * 累计学习时长
+ */
+ private Double studyTotal;
+
+ /**
+ * 专项资源数量
+ */
+
+ private Integer subsidyCourseNum;
+
+ /**
+ * 专项资源时长
+ */
+ private Double subsidyStudyTotal;
+}
diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties
index eda7c57..cbbe544 100644
--- a/src/main/resources/application-dev.properties
+++ b/src/main/resources/application-dev.properties
@@ -2,7 +2,7 @@
spring.server.port=23457
# 数据源配置
-spring.datasource.url=jdbc:mysql://47.97.19.66:3306/subsidy_test?autoReconnect=true&useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
+spring.datasource.url=jdbc:mysql://116.62.57.92:3306/subsidy_test?autoReconnect=true&useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
#spring.datasource.url=jdbc:mysql://rm-uf6rab73w0qg843opxo.mysql.rds.aliyuncs.com:3306/subsidy_test?autoReconnect=true&useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index f8eae84..11f73ba 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -34,6 +34,9 @@ mybatis-plus.global-config.db-config.logic-delete-value=NOW()
mybatis-plus.global-config.db-config.logic-not-delete-value=NULL
#日志配置
logging.config=classpath:logback-spring.xml
+#ehcache缓存配置
+spring.cache.type=ehcache
+spring.cache.ehcache.config=classpath:ehcache.xml
# 阿里云短信
sms.product=Dysmsapi
sms.domain=dysmsapi.aliyuncs.com
diff --git a/src/main/resources/ehcache.xml b/src/main/resources/ehcache.xml
new file mode 100644
index 0000000..7a297bc
--- /dev/null
+++ b/src/main/resources/ehcache.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/mapper/ClassDictMapper.xml b/src/main/resources/mapper/ClassDictMapper.xml
index 5b0726d..c4599b6 100644
--- a/src/main/resources/mapper/ClassDictMapper.xml
+++ b/src/main/resources/mapper/ClassDictMapper.xml
@@ -169,4 +169,16 @@
AND cd.delete_date IS NULL
AND d.delete_date IS NULL
+
+
diff --git a/src/main/resources/mapper/VodPlayHistoryMapper.xml b/src/main/resources/mapper/VodPlayHistoryMapper.xml
index e9c63b4..c19dd46 100644
--- a/src/main/resources/mapper/VodPlayHistoryMapper.xml
+++ b/src/main/resources/mapper/VodPlayHistoryMapper.xml
@@ -398,4 +398,36 @@
t.create_date
+
+
+
+
+
+