admin
2021-04-27 f3ff5ab043cf612e119fd90cd82e49b2cfc2ab5a
搜索引擎优化,Bilibili初步集成
31个文件已修改
12个文件已添加
2075 ■■■■■ 已修改文件
src/main/java/com/yeshi/buwan/controller/admin/ClassAdminController.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/controller/admin/HomeTypeAdminController.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/controller/admin/HotSearchAdminController.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/controller/admin/UserBannerAdminController.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/controller/admin/VideoController.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/controller/admin/VideoTypeController.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/controller/admin/api/ClassController.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/controller/admin/api/HomeTypeController.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/controller/api/VideoPlayController.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/controller/parser/HomeParser.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/controller/parser/UserParser.java 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/dao/juhe/bilibili/BilibiliEpInfoDao.java 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/dao/juhe/bilibili/BilibiliMediaInfoDao.java 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/dao/juhe/bilibili/BilibiliSearchVideoMapDao.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/dao/juhe/bilibili/BilibiliVideoDao.java 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/domain/HomeVideo.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/domain/recommend/AdRecommendRight.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/domain/video/InternetSearchVideo.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/pptv/PPTVUtil.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/service/imp/HomeTypeService.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/service/imp/LoginUserServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/service/imp/SearchService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/service/imp/UserService.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/service/imp/VideoInfoService.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/service/imp/ad/DeviceAdStrategyServiceImpl.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/service/imp/juhe/BilibiliVideoServiceImpl.java 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/service/imp/recommend/HomeVideoServiceImpl.java 130 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/service/inter/ad/DeviceAdStrategyService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/service/inter/juhe/BilibiliVideoService.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/service/inter/recommend/HomeVideoService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/util/factory/InternetSearchVideoFactory.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/videos/bilibili/BilibiliApiUtil.java 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/videos/bilibili/BilibiliUtil.java 155 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/videos/bilibili/entity/BilibiliEpInfo.java 237 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/videos/bilibili/entity/BilibiliMediaInfo.java 349 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/videos/bilibili/entity/BilibiliSearchVideoMap.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/videos/bilibili/entity/BilibiliVideo.java 240 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/domain/HomeVideo.hbm.xml 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/ehcache.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/admin/new/fenqu.html 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/admin/new/tuijian-lanmuneirong-videos.html 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/java/com/hxh/spring/test/DES.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/java/com/hxh/spring/test/GeneralTest.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/yeshi/buwan/controller/admin/ClassAdminController.java
@@ -9,6 +9,7 @@
import com.yeshi.buwan.service.imp.HomeTypeService;
import com.yeshi.buwan.service.imp.HotVideoTypeService;
import com.yeshi.buwan.service.imp.recommend.CategoryRecommendVideoService;
import com.yeshi.buwan.service.inter.recommend.HomeVideoService;
import com.yeshi.buwan.util.StringUtil;
import com.yeshi.buwan.util.SystemUtil;
import com.yeshi.buwan.web.tag.PageEntity;
@@ -40,6 +41,9 @@
    @Resource
    private HomeTypeService homeTypeService;
    @Resource
    private HomeVideoService homeVideoService;
    @Resource
    private CategoryRecommendVideoService categoryRecommendVideoService;
@@ -158,7 +162,7 @@
            String picture = req.getParameter("picture");
            HomeVideo hv = homeTypeService.getHomeVideoById(homevideid);
            hv.setPicture(picture);
            homeTypeService.updateHomeVideo(hv);
            homeVideoService.updateHomeVideo(hv);
            out.print("SUCCESS");
        }
        return "";
src/main/java/com/yeshi/buwan/controller/admin/HomeTypeAdminController.java
@@ -12,6 +12,7 @@
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.yeshi.buwan.service.inter.recommend.HomeVideoService;
import com.yeshi.buwan.util.SystemUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -49,6 +50,10 @@
    @Resource
    private HomeTypeService homeTypeService;
    @Resource
    private HomeVideoService homeVideoService;
    @Resource
    private ClassService classService;
    @Resource
@@ -415,7 +420,7 @@
            String picture = req.getParameter("picture");
            HomeVideo video = homeTypeService.getHomeVideoById(id);
            video.setPicture(picture);
            homeTypeService.updateHomeVideo(video);
            homeVideoService.updateHomeVideo(video);
            req.setAttribute("id", id);
            return "homevideo_update";
        }
src/main/java/com/yeshi/buwan/controller/admin/HotSearchAdminController.java
@@ -12,6 +12,7 @@
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.yeshi.buwan.service.inter.recommend.HomeVideoService;
import com.yeshi.buwan.util.SystemUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -58,6 +59,9 @@
    @Resource
    private HomeTypeService homeTypeService;
    @Resource
    private HomeVideoService homeVideoService;
    @Resource
    private AdService adService;
@@ -436,7 +440,7 @@
            String picture = req.getParameter("picture");
            HomeVideo video = homeTypeService.getHomeVideoById(id);
            video.setPicture(picture);
            homeTypeService.updateHomeVideo(video);
            homeVideoService.updateHomeVideo(video);
            req.setAttribute("id", id);
            return "homevideo_update";
src/main/java/com/yeshi/buwan/controller/admin/UserBannerAdminController.java
@@ -12,6 +12,7 @@
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.yeshi.buwan.service.inter.recommend.HomeVideoService;
import com.yeshi.buwan.util.SystemUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -57,6 +58,10 @@
    @Resource
    private HomeTypeService homeTypeService;
    @Resource
    private HomeVideoService homeVideoService;
    @Resource
    private HomeAdService homeAdService;
@@ -432,7 +437,7 @@
            String picture = req.getParameter("picture");
            HomeVideo video = homeTypeService.getHomeVideoById(id);
            video.setPicture(picture);
            homeTypeService.updateHomeVideo(video);
            homeVideoService.updateHomeVideo(video);
            req.setAttribute("id", id);
            return "homevideo_update";
        }
src/main/java/com/yeshi/buwan/controller/admin/VideoController.java
@@ -12,6 +12,7 @@
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.yeshi.buwan.service.inter.recommend.HomeVideoService;
import com.yeshi.buwan.util.*;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -48,6 +49,9 @@
    private VideoManager videoManager;
    @Resource
    private HomeTypeService homeTypeService;
    @Resource
    private HomeVideoService homeVideoService;
    @Resource
    private HomeAdService homeAdService;
@@ -422,7 +426,7 @@
            String picture = req.getParameter("picture");
            HomeVideo video = homeTypeService.getHomeVideoById(id);
            video.setPicture(picture);
            homeTypeService.updateHomeVideo(video);
            homeVideoService.updateHomeVideo(video);
            req.setAttribute("id", id);
            return "homevideo_update";
src/main/java/com/yeshi/buwan/controller/admin/VideoTypeController.java
@@ -12,6 +12,7 @@
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.yeshi.buwan.service.inter.recommend.HomeVideoService;
import com.yeshi.buwan.util.SystemUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -53,6 +54,11 @@
    private ClassService classService;
    @Resource
    private HomeTypeService homeTypeService;
    @Resource
    private HomeVideoService homeVideoService;
    @Resource
    private HomeAdService homeAdService;
@@ -428,7 +434,7 @@
            String picture = req.getParameter("picture");
            HomeVideo video = homeTypeService.getHomeVideoById(id);
            video.setPicture(picture);
            homeTypeService.updateHomeVideo(video);
            homeVideoService.updateHomeVideo(video);
            req.setAttribute("id", id);
            return "homevideo_update";
        }
src/main/java/com/yeshi/buwan/controller/admin/api/ClassController.java
@@ -10,6 +10,7 @@
import javax.servlet.http.HttpSession;
import com.yeshi.buwan.service.inter.recommend.HomeVideoService;
import com.yeshi.buwan.util.*;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
@@ -45,6 +46,9 @@
    @Resource
    private HomeTypeService homeTypeService;
    @Resource
    private HomeVideoService homeVideoService;
    @Resource
    private CategoryRecommendVideoService categoryRecommendVideoService;
@@ -128,10 +132,11 @@
            hv.setPicture(pictureStr[i]);
            hv.setType(new HomeType(hometypeid + ""));
            hv.setVideoId(videoStr[i]);
            hv.setFromType(0);
            hv.setBigPicture(false);
        }
        homeTypeService.addHomeTypeVideo(list);
        homeVideoService.addHomeVideo(list);
        JSONObject object = new JSONObject();
        object.put("code", 0);
        object.put("msg", "添加成功");
src/main/java/com/yeshi/buwan/controller/admin/api/HomeTypeController.java
@@ -148,7 +148,7 @@
            }
        }
        homeTypeService.addHomeTypeVideo(list);
        homeVideoService.addHomeVideo(list);
        JSONObject object = new JSONObject();
        object.put("code", 0);
        object.put("msg", "添加成功");
@@ -308,7 +308,7 @@
    public void deleteHomeVideo(String ids, PrintWriter out) {
        String[] idStrs = ids.split(",");
        for (String id : idStrs) {
            homeTypeService.deleteHomeVideo(new HomeVideo(id));
            homeVideoService.deleteHomeVideo(new HomeVideo(id));
        }
        JSONObject object = new JSONObject();
        object.put("code", 0);
@@ -353,7 +353,7 @@
            }
            hv.setOrderby(ob);
            hv.setBigPicture(bigPicture);
            homeTypeService.updateHomeVideo(hv);
            homeVideoService.updateHomeVideo(hv);
            JSONObject object = new JSONObject();
            object.put("code", 0);
            object.put("msg", "更新成功");
src/main/java/com/yeshi/buwan/controller/api/VideoPlayController.java
@@ -142,6 +142,7 @@
        //查询cid与vid的名字
        PPTVSeries pptvSeries = pptvService.selectSeriesBySeriesCode(cid);
        if (pptvSeries == null) {
//            PPTVProgram program = pptvService.selectProgramById(cid);
            try {
                pptvSeries = PPTVApiUtil.getDetail(cid);
                ThreadUtil.run(new Runnable() {
src/main/java/com/yeshi/buwan/controller/parser/HomeParser.java
@@ -800,7 +800,7 @@
        if (VersionUtil.isGraterThan390(acceptData.getPlatform(), acceptData.getVersion())) {
            String sessionId = createVideoDetailSessionId(acceptData, loginUid, info.getName(), videoId, resourceId);
            out.print(JsonUtil.loadTrueJson(StringUtil.outPutResultJson(new VideoDetailVO(Utils.convertVideo(info), deviceAdStrategyService.getVideoDetailAdStrategy(acceptData.getUtdId(), acceptData.getDetailSystem().getId(), loginUid), attention, sessionId)), array.toString(),
            out.print(JsonUtil.loadTrueJson(StringUtil.outPutResultJson(new VideoDetailVO(Utils.convertVideo(info), deviceAdStrategyService.getVideoDetailAdStrategy(acceptData.getUtdId(), acceptData.getDetailSystem().getId(), loginUid,videoId,from), attention, sessionId)), array.toString(),
                    obj.toString()));
        } else {
            out.print(JsonUtil.loadTrueJson(StringUtil.outPutResultJson(Utils.convertVideo(info)), array.toString(),
src/main/java/com/yeshi/buwan/controller/parser/UserParser.java
@@ -209,19 +209,31 @@
                }
            }
        }
        if (list == null || list.size() < 3) {
            List<String> list1 = solrInternetSearchVideoDataManager.getSuggestKeyList(key);
            if (list1 != null) {
                list.addAll(list1);
            }
        List<String> list1 = solrInternetSearchVideoDataManager.getSuggestKeyList(key);
        if (list1 != null) {
            list.addAll(list1);
        }
        //按关键词的匹配度排序
        Comparator<String> cm = new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                float s1 = CompareStrSimUtil.getSimilarityRatio(o1, key, true);
                float s2 = CompareStrSimUtil.getSimilarityRatio(o2, key, true);
                return s2 > s1 ? 1 : -1;
            }
        };
        Collections.sort(list, cm);
        JSONObject object = new JSONObject();
        object.put("count", list.size() + "");
        JSONArray array = new JSONArray();
        for (int i = 0; i < list.size(); i++) {
            array.add(StringUtil.outPutResultJson(list.get(i)));
            if (i < 10)
                array.add(StringUtil.outPutResultJson(list.get(i)));
        }
        object.put("data", array);
        out.print(JsonUtil.loadTrueJson(object.toString()));
src/main/java/com/yeshi/buwan/dao/juhe/bilibili/BilibiliEpInfoDao.java
New file
@@ -0,0 +1,93 @@
package com.yeshi.buwan.dao.juhe.bilibili;
import com.yeshi.buwan.videos.bilibili.entity.BilibiliEpInfo;
import com.yeshi.buwan.dao.base.MongodbBaseDao;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;
import java.util.Date;
import java.util.List;
@Repository
public class BilibiliEpInfoDao extends MongodbBaseDao<BilibiliEpInfo> {
    public void updateSelective(BilibiliEpInfo bean) {
        Query query = new Query();
        Update update = new Update();
        query.addCriteria(Criteria.where("id").is(bean.getId()));
        if (bean.getAid() != null) {
            update.set("aid", bean.getAid());
        }
        if (bean.getMediaId() != null) {
            update.set("mediaId", bean.getMediaId());
        }
        if (bean.getBadge() != null) {
            update.set("badge", bean.getBadge());
        }
        if (bean.getBadge_type() != null) {
            update.set("badge_type", bean.getBadge_type());
        }
        if (bean.getBvid() != null) {
            update.set("bvid", bean.getBvid());
        }
        if (bean.getCid() != null) {
            update.set("cid", bean.getCid());
        }
        if (bean.getCover() != null) {
            update.set("cover", bean.getCover());
        }
        if (bean.getLink() != null) {
            update.set("link", bean.getLink());
        }
        if (bean.getLong_title() != null) {
            update.set("long_title", bean.getLong_title());
        }
        if (bean.getPub_time() != null) {
            update.set("pub_time", bean.getPub_time());
        }
        if (bean.getPv() != null) {
            update.set("pv", bean.getPv());
        }
        if (bean.getRelease_date() != null) {
            update.set("release_date", bean.getRelease_date());
        }
        if (bean.getShare_copy() != null) {
            update.set("share_copy", bean.getShare_copy());
        }
        if (bean.getShare_url() != null) {
            update.set("share_url", bean.getShare_url());
        }
        if (bean.getShort_link() != null) {
            update.set("short_link", bean.getShort_link());
        }
        if (bean.getStatus() != null) {
            update.set("status", bean.getStatus());
        }
        if (bean.getSubtitle() != null) {
            update.set("subtitle", bean.getSubtitle());
        }
        if (bean.getTitle() != null) {
            update.set("title", bean.getTitle());
        }
        if (bean.getVid() != null) {
            update.set("vid", bean.getVid());
        }
        if (bean.getCreateTime() != null) {
            update.set("createTime", bean.getCreateTime());
        }
        update.set("updateTime", new Date());
        update(query, update);
    }
    public List<BilibiliEpInfo> listByMediaId(Long mediaId, int start, int count) {
        Query query = new Query();
        query.addCriteria(Criteria.where("mediaId").is(mediaId));
        query.with(new Sort(new Sort.Order(Sort.Direction.ASC, "pub_time")));
        query.skip(start);
        query.limit(count);
        return findList(query);
    }
}
src/main/java/com/yeshi/buwan/dao/juhe/bilibili/BilibiliMediaInfoDao.java
New file
@@ -0,0 +1,82 @@
package com.yeshi.buwan.dao.juhe.bilibili;
import com.yeshi.buwan.videos.bilibili.entity.BilibiliMediaInfo;
import com.yeshi.buwan.dao.base.MongodbBaseDao;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;
import java.util.Date;
@Repository
public class BilibiliMediaInfoDao extends MongodbBaseDao<BilibiliMediaInfo>{
  public void updateSelective(BilibiliMediaInfo bean) {
        Query query = new Query();
        Update update=new Update();
        query.addCriteria(Criteria.where("media_id").is(bean.getMedia_id()));
        if(bean.getAlias() != null) {
            update.set("alias", bean.getAlias());
        }
        if(bean.getBkg_cover() != null) {
            update.set("bkg_cover", bean.getBkg_cover());
        }
        if(bean.getCover() != null) {
            update.set("cover", bean.getCover());
        }
        if(bean.getEvaluate() != null) {
            update.set("evaluate", bean.getEvaluate());
        }
        if(bean.getJp_title() != null) {
            update.set("jp_title", bean.getJp_title());
        }
        if(bean.getLink() != null) {
            update.set("link", bean.getLink());
        }
        if(bean.getMode() != null) {
            update.set("mode", bean.getMode());
        }
        if(bean.getRecord() != null) {
            update.set("record", bean.getRecord());
        }
        if(bean.getSeason_id() != null) {
            update.set("season_id", bean.getSeason_id());
        }
        if(bean.getSeason_title() != null) {
            update.set("season_title", bean.getSeason_title());
        }
        if(bean.getSeries() != null) {
            update.set("series", bean.getSeries());
        }
        if(bean.getSquare_cover() != null) {
            update.set("square_cover", bean.getSquare_cover());
        }
        if(bean.getStatus() != null) {
            update.set("status", bean.getStatus());
        }
        if(bean.getSubtitle() != null) {
            update.set("subtitle", bean.getSubtitle());
        }
        if(bean.getTitle() != null) {
            update.set("title", bean.getTitle());
        }
        if(bean.getTotal() != null) {
            update.set("total", bean.getTotal());
        }
        if(bean.getType() != null) {
            update.set("type", bean.getType());
        }
        if(bean.getMediaRating() != null) {
            update.set("mediaRating", bean.getMediaRating());
        }
        if(bean.getNewestEp() != null) {
            update.set("newestEp", bean.getNewestEp());
        }
        if(bean.getCreateTime() != null) {
            update.set("createTime", bean.getCreateTime());
        }
        update.set("updateTime", new Date());
        update(query, update);
  }
}
src/main/java/com/yeshi/buwan/dao/juhe/bilibili/BilibiliSearchVideoMapDao.java
New file
@@ -0,0 +1,31 @@
package com.yeshi.buwan.dao.juhe.bilibili;
import com.yeshi.buwan.videos.bilibili.entity.BilibiliSearchVideoMap;
import com.yeshi.buwan.dao.base.MongodbBaseDao;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;
import java.util.Date;
@Repository
public class BilibiliSearchVideoMapDao extends MongodbBaseDao<BilibiliSearchVideoMap>{
  public void updateSelective(BilibiliSearchVideoMap bean) {
        Query query = new Query();
        Update update=new Update();
        query.addCriteria(Criteria.where("videoId").is(bean.getVideoId()));
        if(bean.getMediaId() != null) {
            update.set("mediaId", bean.getMediaId());
        }
        if(bean.getVid() != null) {
            update.set("vid", bean.getVid());
        }
        if(bean.getCreateTime() != null) {
            update.set("createTime", bean.getCreateTime());
        }
        update.set("updateTime", new Date());
        update(query, update);
  }
}
src/main/java/com/yeshi/buwan/dao/juhe/bilibili/BilibiliVideoDao.java
New file
@@ -0,0 +1,73 @@
package com.yeshi.buwan.dao.juhe.bilibili;
import com.yeshi.buwan.videos.bilibili.entity.BilibiliVideo;
import com.yeshi.buwan.dao.base.MongodbBaseDao;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;
import java.util.Date;
@Repository
public class BilibiliVideoDao extends MongodbBaseDao<BilibiliVideo>{
  public void updateSelective(BilibiliVideo bean) {
        Query query = new Query();
        Update update=new Update();
        query.addCriteria(Criteria.where("aid").is(bean.getAid()));
        if(bean.getBvid() != null) {
            update.set("bvid", bean.getBvid());
        }
        if(bean.getVideos() != null) {
            update.set("videos", bean.getVideos());
        }
        if(bean.getTid() != null) {
            update.set("tid", bean.getTid());
        }
        if(bean.getTname() != null) {
            update.set("tname", bean.getTname());
        }
        if(bean.getCopyright() != null) {
            update.set("copyright", bean.getCopyright());
        }
        if(bean.getPic() != null) {
            update.set("pic", bean.getPic());
        }
        if(bean.getTitle() != null) {
            update.set("title", bean.getTitle());
        }
        if(bean.getPubdate() != null) {
            update.set("pubdate", bean.getPubdate());
        }
        if(bean.getCtime() != null) {
            update.set("ctime", bean.getCtime());
        }
        if(bean.getDesc() != null) {
            update.set("desc", bean.getDesc());
        }
        if(bean.getState() != null) {
            update.set("state", bean.getState());
        }
        if(bean.getDuration() != null) {
            update.set("duration", bean.getDuration());
        }
        if(bean.getMission_id() != null) {
            update.set("mission_id", bean.getMission_id());
        }
        if(bean.getOwner() != null) {
            update.set("owner", bean.getOwner());
        }
        if(bean.getDynamic() != null) {
            update.set("dynamic", bean.getDynamic());
        }
        if(bean.getCid() != null) {
            update.set("cid", bean.getCid());
        }
        if(bean.getCreateTime() != null) {
            update.set("createTime", bean.getCreateTime());
        }
        update.set("updateTime", new Date());
        update(query, update);
  }
}
src/main/java/com/yeshi/buwan/domain/HomeVideo.java
@@ -1,6 +1,7 @@
package com.yeshi.buwan.domain;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.ManyToOne;
@@ -14,6 +15,11 @@
 */
@Entity
public class HomeVideo implements Serializable {
    public final static int FROM_TYPE_LOCAL = 0;
    public final static int FROM_TYPE_INTERNET = 1;
    public HomeVideo(String id) {
        this.id = id;
    }
@@ -37,6 +43,29 @@
    @Expose
    private String videoId;
    private Integer fromType;//0-本地库  1-全网搜
    private String videoName;
    private Date videoUpdateTime;
    public String getVideoName() {
        return videoName;
    }
    public void setVideoName(String videoName) {
        this.videoName = videoName;
    }
    public Date getVideoUpdateTime() {
        return videoUpdateTime;
    }
    public void setVideoUpdateTime(Date videoUpdateTime) {
        this.videoUpdateTime = videoUpdateTime;
    }
    public String getVideoId() {
        return videoId;
@@ -134,4 +163,11 @@
        this.picture = picture;
    }
    public Integer getFromType() {
        return fromType;
    }
    public void setFromType(Integer fromType) {
        this.fromType = fromType;
    }
}
src/main/java/com/yeshi/buwan/domain/recommend/AdRecommendRight.java
@@ -6,10 +6,11 @@
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;
@Entity
@Table(name = "wk_ad_recommend_right_center")
public class AdRecommendRight {
public class AdRecommendRight implements Serializable {
    
    public AdRecommendRight() {
src/main/java/com/yeshi/buwan/domain/video/InternetSearchVideo.java
@@ -7,13 +7,14 @@
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.solr.core.mapping.Indexed;
import java.io.Serializable;
import java.util.Date;
/**
 * 全网搜实体
 */
@Document(collection = "internetSearchVideo")
public class InternetSearchVideo {
public class InternetSearchVideo implements Serializable {
    @NotBlank(message = "id不能为空")
    @Id
src/main/java/com/yeshi/buwan/pptv/PPTVUtil.java
@@ -238,9 +238,9 @@
    public static String getPlayUrl(PPTVSeries series, String programCode) {
        boolean isMovie = (series.getProgramType() != null && series.getProgramType().contains("电影")) || (series.getProgramType2() != null && series.getProgramType2().contains("电影"));
        //programtype 电影-3  其他-2
        return String.format("https://acmd.api.pptv.com/2021/bwysdqmovie_thrid_h5.html?cid=%s&vid=%s&programtype=%s", series.getSeriesCode(), programCode, series.getProgramType().contains("电影") ? 3 : 2);
//        return String.format(" http://vip.pptv.com/activity/2021/pg_bwysdqmovie?cid=%s&vid=%s&programtype=%s", series.getSeriesCode(), program.getProgramCode(), series.getProgramType().contains("电影") ? 3 : 2);
        return String.format("https://acmd.api.pptv.com/2021/bwysdqmovie_thrid_h5.html?cid=%s&vid=%s&programtype=%s", isMovie ? programCode : series.getSeriesCode(), programCode, isMovie ? 3 : 2);
    }
src/main/java/com/yeshi/buwan/service/imp/HomeTypeService.java
@@ -289,11 +289,6 @@
        homeTypeDao.update(type);
    }
    public void updateHomeVideo(HomeVideo type) {
        homeVideoDao.update(type);
    }
    public List<DetailSystemSelect> getDetailSystemSelectByType(String homeType) {
        List<DetailSystemSelect> li = new ArrayList<>();
        List<DetailSystem> list = detailSystemDao
@@ -314,33 +309,6 @@
        }
        return li;
    }
    public void addHomeTypeVideo(HomeVideo video) {
        long count = homeVideoDao.getCount("select count(*) from HomeVideo h where h.type.id=? and h.video.id=?",
                new String[]{video.getType().getId(), video.getVideo().getId()});
        if (count <= 0L)
            homeVideoDao.create(video);
    }
    public void addHomeTypeVideo(List<HomeVideo> list) {
        HomeVideo info;
        for (Iterator<HomeVideo> iterator = list.iterator(); iterator.hasNext(); addHomeTypeVideo(info))
            info = (HomeVideo) iterator.next();
    }
    public void deleteHomeVideo(HomeVideo video) {
        homeVideoDao.delete(video);
    }
    public void deleteHomeTypeVideo(List<HomeVideo> list) {
        HomeVideo video;
        for (Iterator<HomeVideo> iterator = list.iterator(); iterator.hasNext(); deleteHomeVideo(video))
            video = (HomeVideo) iterator.next();
    }
    public Serializable addHomeType(HomeType type) {
src/main/java/com/yeshi/buwan/service/imp/LoginUserServiceImpl.java
@@ -76,7 +76,7 @@
            throw new LoginUserException("手机号已被其他账户绑定");
        }
        user.setPhone(phone);
        loginUserDao.update(user);
        loginUserDao.updateSelective(user);
    }
    @Override
@@ -184,7 +184,7 @@
        extra.setDevice(user.getDevice());
        extra.setPptvUid(PPTVUtil.getPPTVUid(uid));
        //TODO 初始化附加信息
        loginUserDao.update(user);
        loginUserDao.updateSelective(user);
        loginUserExtraDao.save(extra);
        return extra;
    }
src/main/java/com/yeshi/buwan/service/imp/SearchService.java
@@ -345,16 +345,18 @@
                }
            }
            //按关键词的匹配度排序
            Comparator<VideoInfo> cm = new Comparator<VideoInfo>() {
                @Override
                public int compare(VideoInfo o1, VideoInfo o2) {
            Comparator<VideoInfo> cm = (VideoInfo o1, VideoInfo o2) -> {
                if (o1.getDefinition() - o2.getDefinition() == 0) {
                    float s1 = CompareStrSimUtil.getSimilarityRatio(o1.getName(), key, true);
                    float s2 = CompareStrSimUtil.getSimilarityRatio(o2.getName(), key, true);
                    if (s1 != s2)//相似度越高越靠前
                        return s2 > s1 ? 1 : -1;
                    else
                        return o1.getDefinition() - o2.getDefinition();//高清排在前
//                        if (s1 != s2)//相似度越高越靠前
                    return s2 > s1 ? 1 : -1;
//                        else
//                            return o1.getDefinition() - o2.getDefinition();//高清排在前
                } else {
                    return o2.getDefinition() - o1.getDefinition();//高清排在前
                }
            };
            Collections.sort(localList, cm);
src/main/java/com/yeshi/buwan/service/imp/UserService.java
@@ -85,7 +85,7 @@
    }
    public void updateLoginUserInfo(LoginUser lu) {
        loginUserDao.update(lu);
        loginUserDao.updateSelective(lu);
    }
    public String getUid(String device, String system, String imei, String mac, String lat, String lng) {
@@ -243,7 +243,7 @@
        if (loginUser != null) {
            loginUser.setLoginType(dto.getLoginType());
            loginUserDao.update(loginUser);
            loginUserDao.updateSelective(loginUser);
        }
        if (loginUserExtra != null) {
@@ -407,7 +407,7 @@
            throw new Exception("账户已被注销");
        }
        user.setState(LoginUser.STATE_UNREGISTER);
        loginUserDao.update(user);
        loginUserDao.updateSelective(user);
    }
    // 邮箱注册
src/main/java/com/yeshi/buwan/service/imp/VideoInfoService.java
@@ -14,6 +14,7 @@
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.orm.hibernate4.HibernateCallback;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -51,6 +52,12 @@
        return videoInfoDao.find(VideoInfo.class, vid);
    }
    @Cacheable(value = "videoCache",key = "'getVideoInfoDetail-'+#vid")
    public VideoInfo getVideoInfoCache(String vid) {
        return videoInfoDao.find(VideoInfo.class, vid);
    }
    @SuppressWarnings("unchecked")
    public List<VideoInfo> simpleRandomVideoList(final int i) {
        return (List<VideoInfo>) videoInfoDao.excute(new HibernateCallback<List<VideoInfo>>() {
src/main/java/com/yeshi/buwan/service/imp/ad/DeviceAdStrategyServiceImpl.java
@@ -1,10 +1,13 @@
package com.yeshi.buwan.service.imp.ad;
import com.yeshi.buwan.dao.ad.DeviceAdStrategyDao;
import com.yeshi.buwan.domain.VideoInfo;
import com.yeshi.buwan.domain.ad.DeviceAdStrategy;
import com.yeshi.buwan.service.imp.VideoInfoService;
import com.yeshi.buwan.service.inter.ad.DeviceAdStrategyService;
import com.yeshi.buwan.service.inter.vip.VIPService;
import com.yeshi.buwan.util.StringUtil;
import com.yeshi.buwan.util.video.VideoConstant;
import com.yeshi.buwan.vo.video.VideoDetailVO;
import org.springframework.stereotype.Service;
@@ -19,6 +22,9 @@
    @Resource
    private VIPService vipService;
    @Resource
    private VideoInfoService videoInfoService;
    private DeviceAdStrategy init(String id, String deviceId, String detailSystemId) {
        DeviceAdStrategy strategy = new DeviceAdStrategy();
@@ -56,6 +62,22 @@
    }
    @Override
    public VideoDetailVO.VideoAdInfo getVideoDetailAdStrategy(String deviceId, String detailSystemId, String loginUid, String videoId, String from) {
        VideoDetailVO.VideoAdInfo videoAdInfo = getVideoDetailAdStrategy(deviceId, detailSystemId, loginUid);
        //从APP首页推荐而来,并且有全屏視頻廣告
        if (videoAdInfo.isFullVideo() && "recommend".equalsIgnoreCase(from)) {
            //是否为4大分类
            VideoInfo videoInfo = videoInfoService.getVideoInfoCache(videoId);
            //除开四大分类外不展示全屏视频广告
            if (videoInfo != null && videoInfo.getContentType() != null && videoInfo.getContentType() != 1) {
                videoAdInfo.setFullVideo(false);
            }
        }
        return videoAdInfo;
    }
    @Override
    public void setVideoDetailAdStrategy(String deviceId, String detailSystemId, Long fsaExpireTime, Long pvaExpireTime) {
        if (StringUtil.isNullOrEmpty(deviceId) || StringUtil.isNullOrEmpty(detailSystemId)) {
            return;
src/main/java/com/yeshi/buwan/service/imp/juhe/BilibiliVideoServiceImpl.java
New file
@@ -0,0 +1,118 @@
package com.yeshi.buwan.service.imp.juhe;
import com.yeshi.buwan.dao.juhe.bilibili.BilibiliEpInfoDao;
import com.yeshi.buwan.dao.juhe.bilibili.BilibiliMediaInfoDao;
import com.yeshi.buwan.dao.juhe.bilibili.BilibiliSearchVideoMapDao;
import com.yeshi.buwan.dao.juhe.bilibili.BilibiliVideoDao;
import com.yeshi.buwan.domain.VideoDetailInfo;
import com.yeshi.buwan.service.inter.juhe.BilibiliVideoService;
import com.yeshi.buwan.videos.bilibili.entity.BilibiliEpInfo;
import com.yeshi.buwan.videos.bilibili.entity.BilibiliMediaInfo;
import com.yeshi.buwan.videos.bilibili.entity.BilibiliSearchVideoMap;
import com.yeshi.buwan.videos.bilibili.entity.BilibiliVideo;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
@Service
public class BilibiliVideoServiceImpl implements BilibiliVideoService {
    @Resource
    private BilibiliMediaInfoDao bilibiliMediaInfoDao;
    @Resource
    private BilibiliEpInfoDao bilibiliEpInfoDao;
    @Resource
    private BilibiliVideoDao bilibiliVideoDao;
    @Resource
    private BilibiliSearchVideoMapDao bilibiliSearchVideoMapDao;
    @Override
    public void save(BilibiliMediaInfo mediaInfo) throws Exception {
        if (mediaInfo.getCreateTime() == null)
            mediaInfo.setCreateTime(new Date());
        bilibiliMediaInfoDao.save(mediaInfo);
        if (mediaInfo.getEpList() != null) {
            for (BilibiliEpInfo ep : mediaInfo.getEpList()) {
                ep.setMediaId(mediaInfo.getMedia_id());
                if (ep.getCreateTime() == null)
                    ep.setCreateTime(new Date());
                bilibiliEpInfoDao.save(ep);
            }
        }
    }
    @Override
    public void save(BilibiliVideo bilibiliVideo) throws Exception {
        if (bilibiliVideo.getCreateTime() == null)
            bilibiliVideo.setCreateTime(new Date());
        bilibiliVideoDao.save(bilibiliVideo);
    }
    @Override
    public BilibiliMediaInfo getMediaDetail(Long mediaId) {
        BilibiliMediaInfo mediaInfo = bilibiliMediaInfoDao.get(mediaId);
        if (mediaInfo != null) {
            List<BilibiliEpInfo> epInfoList = bilibiliEpInfoDao.listByMediaId(mediaId, 0, 100);
            mediaInfo.setEpList(epInfoList);
        }
        return mediaInfo;
    }
    @Override
    public BilibiliMediaInfo getSimpleMediaDetail(Long mediaId) {
        BilibiliMediaInfo mediaInfo = bilibiliMediaInfoDao.get(mediaId);
        return mediaInfo;
    }
    @Override
    public List<BilibiliEpInfo> getEPVideoList(Long mediaId, int page, int pageSize) {
        List<BilibiliEpInfo> epInfoList = bilibiliEpInfoDao.listByMediaId(mediaId, (page - 1) * pageSize, pageSize);
        return epInfoList;
    }
    @Override
    public BilibiliEpInfo selectEPInfoByPrimaryKey(Long id) {
        return bilibiliEpInfoDao.get(id);
    }
    @Override
    public BilibiliVideo selectVideoByPrimaryKey(Long id) {
        return bilibiliVideoDao.get(id);
    }
    @Override
    public long count(String category) {
        return 0;
    }
    @Override
    public List<BilibiliMediaInfo> list(String category, int page, int pageSize) {
        return null;
    }
    @Override
    public List<VideoDetailInfo> getVideoDetailList(String videoid, int page, int pageSize) {
        return null;
    }
    @Override
    public BilibiliSearchVideoMap selectMapByVideoId(String videoId) {
        return null;
    }
    @Override
    public void addToInternetSearch(BilibiliMediaInfo mediaInfo) throws Exception {
    }
    @Override
    public void addToInternetSearch(BilibiliVideo video) throws Exception {
    }
}
src/main/java/com/yeshi/buwan/service/imp/recommend/HomeVideoServiceImpl.java
@@ -4,6 +4,7 @@
import com.yeshi.buwan.domain.HomeVideo;
import com.yeshi.buwan.domain.VideoInfo;
import com.yeshi.buwan.domain.video.InternetSearchVideo;
import com.yeshi.buwan.service.imp.VideoInfoService;
import com.yeshi.buwan.service.inter.juhe.InternetSearchVideoService;
import com.yeshi.buwan.service.inter.recommend.HomeVideoService;
import com.yeshi.buwan.service.inter.video.VideoInfoExtraService;
@@ -17,6 +18,7 @@
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Service
@@ -31,9 +33,82 @@
    @Resource
    private InternetSearchVideoService internetSearchVideoService;
    @Resource
    private VideoInfoService videoInfoService;
    public void deleteHomeVideo(HomeVideo video) {
        homeVideoDao.delete(video);
    }
    public void deleteHomeTypeVideo(List<HomeVideo> list) {
        for (HomeVideo homeVideo : list) {
            deleteHomeVideo(homeVideo);
        }
    }
    public void updateHomeVideo(HomeVideo homeVideo) {
        homeVideoDao.update(homeVideo);
    }
    public void addHomeVideo(List<HomeVideo> list) {
        if (list != null)
            for (HomeVideo homeVideo : list) {
                addHomeVideo(homeVideo);
            }
    }
    public void addHomeVideo(HomeVideo video) {
        if (video.getFromType() == null)
            video.setFromType(HomeVideo.FROM_TYPE_LOCAL);
        if (video.getCreatetime() == null)
            video.setCreatetime(System.currentTimeMillis() + "");
        if (video.getVideoUpdateTime() == null) {
            video.setVideoUpdateTime(new Date());
        }
        if (video.getVideoName() == null) {
            switch (video.getFromType()) {
                case HomeVideo.FROM_TYPE_LOCAL: {
                    //取视频名称
                    VideoInfo videoInfo = videoInfoService.getVideoInfo(video.getVideoId());
                    if (videoInfo != null) {
                        video.setVideoName(videoInfo.getName());
                    }
                }
                break;
                case HomeVideo.FROM_TYPE_INTERNET: {
                    //取视频名称
                    InternetSearchVideo internetSearchVideo = internetSearchVideoService.selectByPrimaryKey(video.getVideoId());
                    if (internetSearchVideo != null) {
                        video.setVideoName(internetSearchVideo.getName());
                    }
                }
                break;
            }
        }
        long count = homeVideoDao.getCount("select count(*) from HomeVideo h where h.type.id=? and h.videoId=?",
                new String[]{video.getType().getId(), video.getVideoId()});
        if (count <= 0L)
            homeVideoDao.create(video);
    }
    private List<HomeVideo> betchInternetVideos(List<HomeVideo> homeVideoList) {
        for (HomeVideo hv : homeVideoList) {
            if (hv == null || hv.getVideo() == null || !StringUtil.isNullOrEmpty(hv.getVideoId())) {
            if (hv == null || hv.getVideo() != null || StringUtil.isNullOrEmpty(hv.getVideoId())) {
                continue;
            }
            if (NumberUtil.isNumeric(hv.getVideoId())) {
@@ -51,16 +126,12 @@
    @Override
    public List<HomeVideo> getHomeVideoList(String homeId, String key, int page) {
        List<HomeVideo> homeVideoList = homeVideoDao.list(
                "from HomeVideo h where h.type.id=? and h.video.name like ? order by h.bigPicture desc, h.video.orderby desc,h.video.watchCount desc,h.createtime desc",
                (page - 1) * Constant.pageCount, Constant.pageCount, new String[]{homeId, "%" + key + "%"});
        return betchInternetVideos(homeVideoList);
        return getHomeVideoList(homeId, null, null, null, page, Constant.pageCount);
    }
    @Override
    public long getHomeVideoListCount(String homeId, String key) {
        return homeVideoDao.getCount("select count(*)  from HomeVideo h where h.type.id=? and h.video.name like ? ",
                new String[]{homeId, "%" + key + "%"});
        return getHomeVideoListCount(homeId, null, null, null);
    }
    @Override
@@ -70,11 +141,12 @@
            List<String> rids = new ArrayList<>();
            for (Long rid : resourceIds) {
                rids.add("rv.`resourceid`=" + rid);
            }
            if (resourceIds != null)
                for (Long rid : resourceIds) {
                    rids.add("rv.`resourceid`=" + rid);
                }
            String sql = String.format("SELECT hv.* FROM wk_video_homevideo hv LEFT JOIN wk_resource_video rv ON rv.`videoid`=hv.`videoid` LEFT JOIN wk_video_video v ON v.`id`=hv.`videoid` WHERE v.show=1 and hv.`hometype`=%s AND (%s) ", homeId, org.yeshi.utils.StringUtil.concat(rids, " or "));
            String sql = String.format("SELECT hv.* FROM wk_video_homevideo hv LEFT JOIN wk_resource_video rv ON rv.`videoid`=hv.`videoid` LEFT JOIN wk_video_video v ON v.`id`=hv.`videoid` WHERE  hv.`hometype`=%s AND ( (v.show=1 AND hv.from_type=0  %s) OR hv.from_type>0 )  ", homeId, rids.size() == 0 ? "" :"AND ("+ org.yeshi.utils.StringUtil.concat(rids, " or ")+")");
            sql += " GROUP BY hv.id ORDER BY hv.`orderby` DESC,hv.`createtime` DESC";
@@ -84,31 +156,39 @@
        });
        List<VideoInfo> videoInfoList = new ArrayList<>();
        for (HomeVideo hv : homeVideos) {
            if (hv.getVideo() != null)
                videoInfoList.add(hv.getVideo());
        }
        homeVideos = betchInternetVideos(homeVideos);
        for (int i = 0; i < homeVideos.size(); i++) {
            if (homeVideos.get(i).getVideo() == null) {
                homeVideos.remove(i);
                i--;
            }
        }
        for (HomeVideo hv : homeVideos) {
            if (hv.getVideo() != null) {
                hv.getVideo().setIntroduction("");
                hv.getVideo().setVideoType(null);
                videoInfoList.add(hv.getVideo());
            }
        }
        videoInfoExtraService.batchExtra(videoInfoList, resourceIds);
        return betchInternetVideos(homeVideos);
    }
    @Override
    @Cacheable(value = "homeCache", key = "'getHomeVideoListCount-'+#homeId+'-'+#resourceKey+'-'+#bigPicture")
    public long getHomeVideoListCount(String homeId, String resourceKey, List<Long> resourceIds, Boolean bigPicture) {
    @Cacheable(value = "homeCache", key = "'getHomeVideoListCount-'+#homeId+'-'+#resourceKey+'-'+#hasBigPicture")
    public long getHomeVideoListCount(String homeId, String resourceKey, List<Long> resourceIds, Boolean hasBigPicture) {
        return (Long) homeVideoDao.excute((Session session) -> {
            List<String> rids = new ArrayList<>();
            for (Long rid : resourceIds) {
                rids.add("rv.`resourceid`=" + rid);
            }
            if (resourceIds != null)
                for (Long rid : resourceIds) {
                    rids.add("rv.`resourceid`=" + rid);
                }
            String sql = String.format("SELECT  count(distinct(hv.id)) FROM wk_video_homevideo hv LEFT JOIN wk_resource_video rv ON rv.`videoid`=hv.`videoid`  LEFT JOIN wk_video_video v ON v.`id`=hv.`videoid`  WHERE v.show=1 and hv.`hometype`=%s AND (%s)", homeId, org.yeshi.utils.StringUtil.concat(rids, " or "));
            String sql = String.format("SELECT  count(distinct(hv.id)) from wk_video_homevideo hv LEFT JOIN wk_resource_video rv ON rv.`videoid`=hv.`videoid` LEFT JOIN wk_video_video v ON v.`id`=hv.`videoid` WHERE  hv.`hometype`=%s AND ( (v.show=1 AND hv.from_type=0 %s) OR hv.from_type>0 ) ", homeId, rids.size() == 0 ? "" :"AND ("+ org.yeshi.utils.StringUtil.concat(rids, " or ")+")");
            if (bigPicture != null) {
                sql += " and hv.big_picture=" + (bigPicture ? 1 : 0);
            }
            return Long.parseLong(session.createSQLQuery(sql).uniqueResult() + "");
            return Long.parseLong(session.createSQLQuery(sql).uniqueResult() + "") + (hasBigPicture != null && hasBigPicture ? 1 : 0);
        });
    }
}
src/main/java/com/yeshi/buwan/service/inter/ad/DeviceAdStrategyService.java
@@ -13,6 +13,17 @@
     */
    public VideoDetailVO.VideoAdInfo getVideoDetailAdStrategy(String deviceId, String detailSystemId, String loginUid);
    /**
     * 获取视频详情页的广告展示策略(含单视频策略)
     * @param deviceId
     * @param detailSystemId
     * @param loginUid
     * @param videoId
     * @param from
     * @return
     */
    public VideoDetailVO.VideoAdInfo getVideoDetailAdStrategy(String deviceId, String detailSystemId, String loginUid,String videoId,String from);
    /**
     * 设置详情页广告展示策略
src/main/java/com/yeshi/buwan/service/inter/juhe/BilibiliVideoService.java
New file
@@ -0,0 +1,51 @@
package com.yeshi.buwan.service.inter.juhe;
import com.yeshi.buwan.domain.VideoDetailInfo;
import com.yeshi.buwan.videos.bilibili.entity.BilibiliEpInfo;
import com.yeshi.buwan.videos.bilibili.entity.BilibiliMediaInfo;
import com.yeshi.buwan.videos.bilibili.entity.BilibiliSearchVideoMap;
import com.yeshi.buwan.videos.bilibili.entity.BilibiliVideo;
import java.util.List;
public interface BilibiliVideoService {
    /**
     * 保存
     *
     * @param mediaInfo
     */
    public void save(BilibiliMediaInfo mediaInfo) throws Exception;
    public void save(BilibiliVideo bilibiliVideo) throws Exception;
    public BilibiliMediaInfo getMediaDetail(Long mediaId);
    public BilibiliMediaInfo getSimpleMediaDetail(Long mediaId);
    public List<BilibiliEpInfo> getEPVideoList(Long mediaId, int page, int pageSize);
    public BilibiliEpInfo selectEPInfoByPrimaryKey(Long id);
    public BilibiliVideo selectVideoByPrimaryKey(Long id);
    public long count(String category);
    public List<BilibiliMediaInfo> list(String category, int page, int pageSize);
    public List<VideoDetailInfo> getVideoDetailList(final String videoid, int page, int pageSize);
    public BilibiliSearchVideoMap selectMapByVideoId(String videoId);
    /**
     * 添加到全网搜
     *
     * @param mediaInfo
     */
    public void addToInternetSearch(BilibiliMediaInfo mediaInfo) throws Exception;
    public void addToInternetSearch(BilibiliVideo video) throws Exception;
}
src/main/java/com/yeshi/buwan/service/inter/recommend/HomeVideoService.java
@@ -6,6 +6,17 @@
public interface HomeVideoService {
    public void deleteHomeVideo(HomeVideo video);
    public void deleteHomeTypeVideo(List<HomeVideo> list);
    public void updateHomeVideo(HomeVideo homeVideo);
    public void addHomeVideo(List<HomeVideo> list);
    public void addHomeVideo(HomeVideo video);
    public List<HomeVideo> getHomeVideoList(String homeId, String key, int page);
    public long getHomeVideoListCount(String homeId, String key);
src/main/java/com/yeshi/buwan/util/factory/InternetSearchVideoFactory.java
@@ -3,9 +3,8 @@
import com.yeshi.buwan.domain.video.InternetSearchVideo;
import com.yeshi.buwan.mogotv.entity.MogoTVClipInfo;
import com.yeshi.buwan.tencent.entity.TencentCoverInfo;
import com.yeshi.buwan.tencent.entity.TencentCoverVideo;
import com.yeshi.buwan.util.TimeUtil;
import com.yeshi.buwan.util.video.VideoConstant;
import com.yeshi.buwan.videos.bilibili.entity.BilibiliMediaInfo;
import com.yeshi.buwan.youku.entity.YouKuShowDetail;
import org.yeshi.utils.StringUtil;
@@ -131,4 +130,41 @@
        return video;
    }
    public static InternetSearchVideo create(BilibiliMediaInfo info) {
        int videoCount = info.getTotal();
        InternetSearchVideo video = new InternetSearchVideo();
        video.setActors("");
        video.setArea("");
        video.setDirector("");
        video.setHpicture(null);
        video.setVpicture(info.getCover());
        video.setName(info.getTitle());
        video.setNameStr(info.getTitle());
//        video.setResourceIds(BilibiliUtil.RESOURCE_ID + "");
//        if (info.getType_name().equalsIgnoreCase("电影")) {
//            video.setRootType(VideoConstant.VIDEO_CATEGORY_DIANYING);
//        } else if (info.getType_name().equalsIgnoreCase("电视剧")) {
//            video.setRootType(VideoConstant.VIDEO_CATEGORY_DIANSHIJU);
//        } else if (info.getType_name().equalsIgnoreCase("动漫")) {
//            video.setRootType(VideoConstant.VIDEO_CATEGORY_DONGMAN);
//        } else if (info.getType_name().equalsIgnoreCase("综艺")) {
//            video.setRootType(VideoConstant.VIDEO_CATEGORY_ZONGYI);
//        }
//        if (info.getType_name().equalsIgnoreCase("电影")) {
//            video.setTag("评分:" + info.getScore().getScore());
//        } else
//            video.setTag(info.getEpisode_updated());
//        video.setUpdateTime(new Date());
//        video.setVideoCount(videoCount);
//        video.setYear(info.getYear());
        video.setId(InternetSearchVideo.createId(video.getName(), video.getRootType(), video.getYear()));
        return video;
    }
}
src/main/java/com/yeshi/buwan/videos/bilibili/BilibiliApiUtil.java
New file
@@ -0,0 +1,109 @@
package com.yeshi.buwan.videos.bilibili;
import com.google.gson.Gson;
import com.yeshi.buwan.videos.bilibili.entity.BilibiliMediaInfo;
import com.yeshi.buwan.videos.bilibili.entity.BilibiliVideo;
import net.sf.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.io.IOException;
public class BilibiliApiUtil {
    public static BilibiliVideo parseShortVideo(String url) throws Exception {
        String result = parsePageData(url);
        System.out.println(result);
        JSONObject root = JSONObject.fromObject(result);
        BilibiliVideo video = parseVideo(root);
        return video;
    }
    public static BilibiliMediaInfo parseMediaInfo(String url) throws Exception {
        String result = parsePageData(url);
        System.out.println(result);
        JSONObject root = JSONObject.fromObject(result);
        BilibiliMediaInfo mediaInfo = parseMedia(root);
        return mediaInfo;
    }
    private static String getPageData(String scriptContent) throws ScriptException, NoSuchMethodException {
        String script = "var _window={};var _document={scripts:[{parentNode:{removeChild:function(){}}}]};" + scriptContent.replace("window.", "_window.").replace("document.", "_document.");
        script += ";function getData(){return  JSON.stringify(_window.__INITIAL_STATE__);}";
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine jsEngine = manager.getEngineByName("javascript");
        try {
            jsEngine.eval(script);
        } catch (ScriptException e) {
            e.printStackTrace();
        }
        Gson gson = new Gson();
        if (jsEngine instanceof Invocable) {
            Invocable in = (Invocable) jsEngine;
            Object data = in.invokeFunction("getData");
            return data.toString();
        }
        return null;
    }
    private static BilibiliMediaInfo parseMedia(JSONObject root) {
        if (root.optJSONObject("mediaInfo") != null) {
            JSONObject mediaJson = root.optJSONObject("mediaInfo");
            mediaJson.put("mediaRating", root.optJSONObject("mediaRating"));
            mediaJson.put("newestEp", root.optJSONObject("newestEp"));
            mediaJson.put("epList", root.optJSONArray("epList"));
            return new Gson().fromJson(mediaJson.toString(), BilibiliMediaInfo.class);
        }
        return null;
    }
    private static BilibiliVideo parseVideo(JSONObject root) {
        if (root.optJSONObject("video") != null) {
            JSONObject videoJson = root.optJSONObject("video");
            if (videoJson != null) {
                videoJson = videoJson.optJSONObject("viewInfo");
            }
            return new Gson().fromJson(videoJson.toString(), BilibiliVideo.class);
        }
        return null;
    }
    private static String parsePageData(String url) throws ScriptException, NoSuchMethodException, IOException {
        Document doc = Jsoup.connect(url).userAgent("Dalvik/2.1.0 (Linux; U; Android 9; MI 8 Lite MIUI/V10.2.3.0.PDTCNXM)").timeout(30000).get();
        Elements els = doc.getElementsByTag("script");
        for (int i = 0; i < els.size(); i++) {
            if (els.get(i).html().indexOf("window.__INITIAL_STATE__") > -1) {
                String script = els.get(i).html();
                System.out.println(script);
                String result = getPageData(script);
                return result;
            }
        }
        return null;
    }
    public static void main(String[] args) throws IOException, ScriptException, NoSuchMethodException {
        String[] urls = new String[]{
                "https://www.bilibili.com/bangumi/play/ss38129?theme=movie&from_spmid=666.7", "https://www.bilibili.com/bangumi/play/ss38611?theme=movie&from_spmid=666.7"
        };
        //3-记录片 5-电视剧  4-国漫 1-番剧  2-电影
        try {
            for (String url : urls) {
                BilibiliMediaInfo mediaInfo = parseMediaInfo(url);
                System.out.println("type:" + mediaInfo.getType());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
src/main/java/com/yeshi/buwan/videos/bilibili/BilibiliUtil.java
New file
@@ -0,0 +1,155 @@
package com.yeshi.buwan.videos.bilibili;
import com.yeshi.buwan.domain.VideoDetailInfo;
import com.yeshi.buwan.domain.VideoInfo;
import com.yeshi.buwan.domain.VideoResource;
import com.yeshi.buwan.domain.entity.PlayUrl;
import com.yeshi.buwan.domain.video.InternetSearchVideo;
import com.yeshi.buwan.service.imp.VideoResourceService;
import com.yeshi.buwan.service.imp.VideoTypeService;
import com.yeshi.buwan.service.inter.juhe.BilibiliVideoService;
import com.yeshi.buwan.service.inter.juhe.InternetSearchVideoService;
import com.yeshi.buwan.util.factory.VideoInfoFactory;
import com.yeshi.buwan.util.video.VideoConstant;
import com.yeshi.buwan.videos.bilibili.entity.BilibiliEpInfo;
import com.yeshi.buwan.videos.bilibili.entity.BilibiliMediaInfo;
import com.yeshi.buwan.videos.bilibili.entity.BilibiliSearchVideoMap;
import com.yeshi.buwan.videos.bilibili.entity.BilibiliVideo;
import com.yeshi.buwan.youku.YouKuUtil;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@Component
public class BilibiliUtil {
    @Resource
    private InternetSearchVideoService internetSearchVideoService;
    @Resource
    private BilibiliVideoService bilibiliVideoService;
    @Resource
    private VideoResourceService videoResourceService;
    @Resource
    private VideoTypeService videoTypeService;
    public final static int RESOURCE_ID = 17;
    public static VideoDetailInfo convertToDetail(BilibiliEpInfo epInfo) {
        VideoDetailInfo detail = new VideoDetailInfo();
        detail.setTag(epInfo.getTitle());
        detail.setName(epInfo.getTitle());
        detail.setExtraId(epInfo.getId() + "");
        detail.setType("ep");
        return detail;
    }
    public static VideoDetailInfo convertToDetail(BilibiliVideo bilibiliVideo) {
        VideoDetailInfo detail = new VideoDetailInfo();
        detail.setTag(bilibiliVideo.getTitle());
        detail.setName(bilibiliVideo.getTitle());
        detail.setExtraId(bilibiliVideo.getAid() + "");
        detail.setType("video");
        return detail;
    }
    public VideoInfo getVideoInfo(InternetSearchVideo internetSearchVideo, Integer pageSize) throws Exception {
        BilibiliSearchVideoMap map = bilibiliVideoService.selectMapByVideoId(internetSearchVideo.getId());
        if (map == null) {
            throw new Exception("视频源不存在");
        }
        //获取资源列表
        List<String> rids = Arrays.asList(internetSearchVideo.getResourceIds().split(","));
        List<VideoResource> resourceList = videoResourceService.getResource(rids);
        for (VideoResource vr : resourceList) {
            if (vr.getId().equalsIgnoreCase(RESOURCE_ID + ""))
                vr.setChecked(true);
        }
        VideoInfo info = VideoInfoFactory.create(internetSearchVideo);
        info.setResourceList(resourceList);
        info.setShowType(YouKuUtil.getShowType(internetSearchVideo));
        info.setPlayPicture(info.getHpicture());
        //获取分类详情
        info.setVideoType(videoTypeService.getVideoType(info.getVideoType().getId()));
        info.setCommentCount(0);
        info.setVideocount((int) (Math.random() * 1000));
        if (map.getMediaId() != null) {
            BilibiliMediaInfo showDetail = bilibiliVideoService.getSimpleMediaDetail(map.getMediaId());
            showDetail.setEpList(bilibiliVideoService.getEPVideoList(showDetail.getMedia_id(), 1, pageSize));
            info.setIntroduction(showDetail.getEvaluate());
            info.setVideoDetailList(convertToDetail(showDetail.getEpList(), showDetail));
            info.setScore(showDetail.getMediaRating().getScore());
        } else {
            BilibiliVideo video = bilibiliVideoService.selectVideoByPrimaryKey(Long.parseLong(map.getVid()));
            List<VideoDetailInfo> detailList = new ArrayList<>();
            detailList.add(convertToDetail(video));
            info.setVideoDetailList(detailList);
            info.setIntroduction(video.getDesc());
            info.setScore("0.0");
        }
        return info;
    }
    public static List<VideoDetailInfo> convertToDetail(List<BilibiliEpInfo> epList, BilibiliMediaInfo coverInfo) {
        List<VideoDetailInfo> detailList = new ArrayList<>();
        for (BilibiliEpInfo video : epList) {
            detailList.add(convertToDetail(video));
        }
        return detailList;
    }
    public static int getShowType(InternetSearchVideo video) {
        if (video == null)
            return 2;
        switch (video.getRootType()) {
            case VideoConstant
                    .VIDEO_CATEGORY_DIANYING:
                return 1;
            case VideoConstant
                    .VIDEO_CATEGORY_DIANSHIJU:
            case VideoConstant
                    .VIDEO_CATEGORY_DONGMAN:
                return 2;
            case VideoConstant
                    .VIDEO_CATEGORY_ZONGYI:
                return 1;
        }
        return 2;
    }
    public PlayUrl getPlayUrl(String detailSystemId, String id, String type, int resourceid, String videoid) {
        PlayUrl playUrl = new PlayUrl();
        VideoResource videoResource = videoResourceService.getResource(resourceid + "");
        playUrl.setResource(videoResource);
        playUrl.setPlayType(1);
        playUrl.setParams("");
        if ("ep".equalsIgnoreCase(type)) {
            BilibiliEpInfo epInfo = bilibiliVideoService.selectEPInfoByPrimaryKey(Long.parseLong(id));
            if (epInfo != null) {
                playUrl.setUrl(epInfo.getLink());
            }
        } else {
            BilibiliVideo bilibiliVideo = bilibiliVideoService.selectVideoByPrimaryKey(Long.parseLong(id));
            playUrl.setUrl("https://www.bilibili.com/video/" + bilibiliVideo.getBvid());
        }
        return playUrl;
    }
}
src/main/java/com/yeshi/buwan/videos/bilibili/entity/BilibiliEpInfo.java
New file
@@ -0,0 +1,237 @@
package com.yeshi.buwan.videos.bilibili.entity;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import java.util.Date;
@Document(collection = "bilibiliEpInfo")
public class BilibiliEpInfo {
    /**
     * aid : 4569587
     * badge :
     * badge_type : 0
     * bvid : BV1us411B7nn
     * cid : 7411432
     * cover : http://i0.hdslb.com/bfs/archive/32d03b24c0f13d38daef65f6a5cf2bae707281a8.jpg
     * id : 87571
     * link : https://www.bilibili.com/bangumi/play/ep87571
     * long_title : 兄弟
     * pub_time : 1462503060
     * pv : 0
     * release_date :
     * share_copy : 《镇魂街 第一季》第2话 兄弟
     * share_url : https://www.bilibili.com/bangumi/play/ep87571
     * short_link : https://b23.tv/ep87571
     * status : 2
     * subtitle : 已观看4.6亿次
     * title : 2
     * vid : vupload_7411432
     */
    @Id
    private Long id;
    private Long aid;
    @Indexed
    private Long mediaId;
    private String badge;
    private Integer badge_type;
    private String bvid;
    private Long cid;
    private String cover;
    private String link;
    private String long_title;
    @Indexed
    private Long pub_time;
    private Integer pv;
    private String release_date;
    private String share_copy;
    private String share_url;
    private String short_link;
    private Integer status;
    private String subtitle;
    private String title;
    private String vid;
    private Date createTime;
    private Date updateTime;
    public Date getCreateTime() {
        return createTime;
    }
    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }
    public Date getUpdateTime() {
        return updateTime;
    }
    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }
    public Long getMediaId() {
        return mediaId;
    }
    public void setMediaId(Long mediaId) {
        this.mediaId = mediaId;
    }
    public Long getAid() {
        return aid;
    }
    public void setAid(Long aid) {
        this.aid = aid;
    }
    public String getBadge() {
        return badge;
    }
    public void setBadge(String badge) {
        this.badge = badge;
    }
    public Integer getBadge_type() {
        return badge_type;
    }
    public void setBadge_type(Integer badge_type) {
        this.badge_type = badge_type;
    }
    public String getBvid() {
        return bvid;
    }
    public void setBvid(String bvid) {
        this.bvid = bvid;
    }
    public Long getCid() {
        return cid;
    }
    public void setCid(Long cid) {
        this.cid = cid;
    }
    public String getCover() {
        return cover;
    }
    public void setCover(String cover) {
        this.cover = cover;
    }
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getLink() {
        return link;
    }
    public void setLink(String link) {
        this.link = link;
    }
    public String getLong_title() {
        return long_title;
    }
    public void setLong_title(String long_title) {
        this.long_title = long_title;
    }
    public Long getPub_time() {
        return pub_time;
    }
    public void setPub_time(Long pub_time) {
        this.pub_time = pub_time;
    }
    public Integer getPv() {
        return pv;
    }
    public void setPv(Integer pv) {
        this.pv = pv;
    }
    public String getRelease_date() {
        return release_date;
    }
    public void setRelease_date(String release_date) {
        this.release_date = release_date;
    }
    public String getShare_copy() {
        return share_copy;
    }
    public void setShare_copy(String share_copy) {
        this.share_copy = share_copy;
    }
    public String getShare_url() {
        return share_url;
    }
    public void setShare_url(String share_url) {
        this.share_url = share_url;
    }
    public String getShort_link() {
        return short_link;
    }
    public void setShort_link(String short_link) {
        this.short_link = short_link;
    }
    public Integer getStatus() {
        return status;
    }
    public void setStatus(Integer status) {
        this.status = status;
    }
    public String getSubtitle() {
        return subtitle;
    }
    public void setSubtitle(String subtitle) {
        this.subtitle = subtitle;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getVid() {
        return vid;
    }
    public void setVid(String vid) {
        this.vid = vid;
    }
}
src/main/java/com/yeshi/buwan/videos/bilibili/entity/BilibiliMediaInfo.java
New file
@@ -0,0 +1,349 @@
package com.yeshi.buwan.videos.bilibili.entity;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Transient;
import org.springframework.data.mongodb.core.mapping.Document;
import java.util.Date;
import java.util.List;
@Document(collection = "bilibiliMediaInfo")
public class BilibiliMediaInfo {
    /**
     * alias :
     * bkg_cover :
     * cover : http://i0.hdslb.com/bfs/bangumi/9f3c32186c0779c17808c6a70648563943655af8.jpg
     * evaluate : 普通的应届大学毕业生夏铃在求职之际,收到了一条奇怪的面试通知,因此误入罗刹街并遭到了危险,幸而被镇魂将曹焱兵搭救。然而接触中,曹焱兵却发现夏铃并非看起来那样普通,因为她的身体里也存在着灵力,并且寄宿着一位神秘的守护灵。与此同时,夏铃开始遭到不明身份刺客的追杀,曹焱兵亦被卷入其中,二人的命运从此开始了交集,而在这一切的背后,似乎还隐藏着某些更加危险的秘密……
     * jp_title :
     * link : http://www.bilibili.com/bangumi/media/md3863/
     * media_id : 3863
     * mode : 2
     * record :
     * season_id : 3863
     * season_title : 镇魂街 第一季
     * series : {"series_id":2272,"series_title":"镇魂街"}
     * square_cover : http://i0.hdslb.com/bfs/bangumi/00b419d055d6767b634008b9b64c77cb578bc5f2.jpg
     * status : 2
     * subtitle : 已观看4.6亿次
     * title : 镇魂街 第一季
     * total : 24
     * type : 4
     * mediaRating : {"count":17848,"score":9.1}
     * newestEp : {"desc":"已完结, 全24话","id":96832,"is_new":0,"title":"24"}
     */
    @Id
    private Long media_id;
    private String alias;
    private String bkg_cover;
    private String cover;
    private String evaluate;
    private String jp_title;
    private String link;
    private Integer mode;
    private String record;
    private Long season_id;
    private String season_title;
    private SeriesBean series;
    private String square_cover;
    private Integer status;
    private String subtitle;
    private String title;
    private Integer total;
    private Integer type;
    private MediaRatingBean mediaRating;
    private NewestEpBean newestEp;
    @Transient
    private List<BilibiliEpInfo> epList;
    private Date createTime;
    private Date updateTime;
    public List<BilibiliEpInfo> getEpList() {
        return epList;
    }
    public void setEpList(List<BilibiliEpInfo> epList) {
        this.epList = epList;
    }
    public String getAlias() {
        return alias;
    }
    public void setAlias(String alias) {
        this.alias = alias;
    }
    public String getBkg_cover() {
        return bkg_cover;
    }
    public void setBkg_cover(String bkg_cover) {
        this.bkg_cover = bkg_cover;
    }
    public String getCover() {
        return cover;
    }
    public void setCover(String cover) {
        this.cover = cover;
    }
    public String getEvaluate() {
        return evaluate;
    }
    public void setEvaluate(String evaluate) {
        this.evaluate = evaluate;
    }
    public String getJp_title() {
        return jp_title;
    }
    public void setJp_title(String jp_title) {
        this.jp_title = jp_title;
    }
    public String getLink() {
        return link;
    }
    public void setLink(String link) {
        this.link = link;
    }
    public Date getCreateTime() {
        return createTime;
    }
    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }
    public Date getUpdateTime() {
        return updateTime;
    }
    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }
    public Long getMedia_id() {
        return media_id;
    }
    public void setMedia_id(Long media_id) {
        this.media_id = media_id;
    }
    public Integer getMode() {
        return mode;
    }
    public void setMode(Integer mode) {
        this.mode = mode;
    }
    public String getRecord() {
        return record;
    }
    public void setRecord(String record) {
        this.record = record;
    }
    public Long getSeason_id() {
        return season_id;
    }
    public void setSeason_id(Long season_id) {
        this.season_id = season_id;
    }
    public String getSeason_title() {
        return season_title;
    }
    public void setSeason_title(String season_title) {
        this.season_title = season_title;
    }
    public SeriesBean getSeries() {
        return series;
    }
    public void setSeries(SeriesBean series) {
        this.series = series;
    }
    public String getSquare_cover() {
        return square_cover;
    }
    public void setSquare_cover(String square_cover) {
        this.square_cover = square_cover;
    }
    public Integer getStatus() {
        return status;
    }
    public void setStatus(Integer status) {
        this.status = status;
    }
    public String getSubtitle() {
        return subtitle;
    }
    public void setSubtitle(String subtitle) {
        this.subtitle = subtitle;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public Integer getTotal() {
        return total;
    }
    public void setTotal(Integer total) {
        this.total = total;
    }
    public Integer getType() {
        return type;
    }
    public void setType(Integer type) {
        this.type = type;
    }
    public MediaRatingBean getMediaRating() {
        return mediaRating;
    }
    public void setMediaRating(MediaRatingBean mediaRating) {
        this.mediaRating = mediaRating;
    }
    public NewestEpBean getNewestEp() {
        return newestEp;
    }
    public void setNewestEp(NewestEpBean newestEp) {
        this.newestEp = newestEp;
    }
    public static class SeriesBean {
        /**
         * series_id : 2272
         * series_title : 镇魂街
         */
        private Integer series_id;
        private String series_title;
        public Integer getSeries_id() {
            return series_id;
        }
        public void setSeries_id(Integer series_id) {
            this.series_id = series_id;
        }
        public String getSeries_title() {
            return series_title;
        }
        public void setSeries_title(String series_title) {
            this.series_title = series_title;
        }
    }
    public static class MediaRatingBean {
        /**
         * count : 17848
         * score : 9.1
         */
        private Integer count;
        private String score;
        public Integer getCount() {
            return count;
        }
        public void setCount(Integer count) {
            this.count = count;
        }
        public String getScore() {
            return score;
        }
        public void setScore(String score) {
            this.score = score;
        }
    }
    public static class NewestEpBean {
        /**
         * desc : 已完结, 全24话
         * id : 96832
         * is_new : 0
         * title : 24
         */
        private String desc;
        private Integer id;
        private Integer is_new;
        private String title;
        public String getDesc() {
            return desc;
        }
        public void setDesc(String desc) {
            this.desc = desc;
        }
        public Integer getId() {
            return id;
        }
        public void setId(Integer id) {
            this.id = id;
        }
        public Integer getIs_new() {
            return is_new;
        }
        public void setIs_new(Integer is_new) {
            this.is_new = is_new;
        }
        public String getTitle() {
            return title;
        }
        public void setTitle(String title) {
            this.title = title;
        }
    }
}
src/main/java/com/yeshi/buwan/videos/bilibili/entity/BilibiliSearchVideoMap.java
New file
@@ -0,0 +1,51 @@
package com.yeshi.buwan.videos.bilibili.entity;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import java.util.Date;
@Document(collection = "bilibiliSearchVideoMap")
public class BilibiliSearchVideoMap {
    @Id
    private String videoId;
    @Indexed
    private Long mediaId;
    private String vid;//bilibili的视频ID
    private Date createTime;
    public String getVideoId() {
        return videoId;
    }
    public void setVideoId(String videoId) {
        this.videoId = videoId;
    }
    public Long getMediaId() {
        return mediaId;
    }
    public void setMediaId(Long mediaId) {
        this.mediaId = mediaId;
    }
    public String getVid() {
        return vid;
    }
    public void setVid(String vid) {
        this.vid = vid;
    }
    public Date getCreateTime() {
        return createTime;
    }
    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }
}
src/main/java/com/yeshi/buwan/videos/bilibili/entity/BilibiliVideo.java
New file
@@ -0,0 +1,240 @@
package com.yeshi.buwan.videos.bilibili.entity;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import java.util.Date;
@Document(collection = "bilibiliVideo")
public class BilibiliVideo {
    /**
     * bvid : BV1fV411J7a2
     * aid : 417803044
     * videos : 1
     * tid : 176
     * tname : 汽车生活
     * copyright : 1
     * pic : http://i0.hdslb.com/bfs/archive/aaf5c488e53338dc3cd43105ad6ffec3a089972e.jpg
     * title : 8000块买台垃圾车,花一万改成神车?
     * pubdate : 1619497877
     * ctime : 1619497877
     * desc : C2赛化计划正式开始!  新款气氛组贴纸、乔T热售中!复制淘口令:¥NQntXdhX6aG¥或淘宝搜索店铺:极速拍档Speedsters  @极速拍档-Jacky @极速拍档-小乔 @极速拍档-NANA @极速拍档-Berlin  所有视频都会首发在上面三个wb或微信公众平台“极速拍档Speedsters”
     * state : 0
     * duration : 1408
     * mission_id : 18413
     * owner : {"mid":25150941,"name":"极速拍档","face":"http://i0.hdslb.com/bfs/face/e9035c3a7089ce7e11d72cb0cf15fa92064b14ef.jpg"}
     * dynamic : 花1万块,我的车能快12秒!!!
     * cid : 329845366
     */
    @Id
    private Long aid;
    private String bvid;
    private Integer videos;
    private Integer tid;
    private String tname;
    private Integer copyright;
    private String pic;
    private String title;
    private Long pubdate;
    private Long ctime;
    private String desc;
    private Integer state;
    private Integer duration;
    private Integer mission_id;
    private OwnerBean owner;
    private String dynamic;
    private Long cid;
    private Date createTime;
    private Date updateTime;
    public String getBvid() {
        return bvid;
    }
    public void setBvid(String bvid) {
        this.bvid = bvid;
    }
    public Long getAid() {
        return aid;
    }
    public void setAid(Long aid) {
        this.aid = aid;
    }
    public Integer getVideos() {
        return videos;
    }
    public void setVideos(Integer videos) {
        this.videos = videos;
    }
    public Integer getTid() {
        return tid;
    }
    public void setTid(Integer tid) {
        this.tid = tid;
    }
    public String getTname() {
        return tname;
    }
    public void setTname(String tname) {
        this.tname = tname;
    }
    public Integer getCopyright() {
        return copyright;
    }
    public void setCopyright(Integer copyright) {
        this.copyright = copyright;
    }
    public String getPic() {
        return pic;
    }
    public void setPic(String pic) {
        this.pic = pic;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public Long getPubdate() {
        return pubdate;
    }
    public void setPubdate(Long pubdate) {
        this.pubdate = pubdate;
    }
    public Long getCtime() {
        return ctime;
    }
    public void setCtime(Long ctime) {
        this.ctime = ctime;
    }
    public String getDesc() {
        return desc;
    }
    public void setDesc(String desc) {
        this.desc = desc;
    }
    public Integer getState() {
        return state;
    }
    public void setState(Integer state) {
        this.state = state;
    }
    public Integer getDuration() {
        return duration;
    }
    public void setDuration(Integer duration) {
        this.duration = duration;
    }
    public Integer getMission_id() {
        return mission_id;
    }
    public void setMission_id(Integer mission_id) {
        this.mission_id = mission_id;
    }
    public OwnerBean getOwner() {
        return owner;
    }
    public void setOwner(OwnerBean owner) {
        this.owner = owner;
    }
    public String getDynamic() {
        return dynamic;
    }
    public void setDynamic(String dynamic) {
        this.dynamic = dynamic;
    }
    public Long getCid() {
        return cid;
    }
    public void setCid(Long cid) {
        this.cid = cid;
    }
    public Date getCreateTime() {
        return createTime;
    }
    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }
    public Date getUpdateTime() {
        return updateTime;
    }
    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }
    public static class OwnerBean {
        /**
         * mid : 25150941
         * name : 极速拍档
         * face : http://i0.hdslb.com/bfs/face/e9035c3a7089ce7e11d72cb0cf15fa92064b14ef.jpg
         */
        private Integer mid;
        private String name;
        private String face;
        public Integer getMid() {
            return mid;
        }
        public void setMid(Integer mid) {
            this.mid = mid;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public String getFace() {
            return face;
        }
        public void setFace(String face) {
            this.face = face;
        }
    }
}
src/main/resources/domain/HomeVideo.hbm.xml
@@ -1,29 +1,34 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
          "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
          "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.yeshi.buwan.domain">
    <class name="HomeVideo" table="wk_video_homevideo_bak">
        <id name="id" column="Id">
            <generator class="native"></generator>
        </id>
        <property name="beizhu" type="string"></property>
        <property name="picture" type="string"></property>
        <property name="createtime" type="string"></property>
        <property name="orderby"></property>
        <property name="tag" type="string"></property>
    <class name="HomeVideo" table="wk_video_homevideo">
        <id name="id" column="Id">
            <generator class="native"></generator>
        </id>
        <property name="beizhu" type="string"></property>
        <property name="picture" type="string"></property>
        <property name="createtime" type="string"></property>
        <property name="orderby"></property>
        <property name="tag" type="string"></property>
        <property name="bigPicture" type="boolean" column="big_picture"></property>
        <property name="bigPicture" type="boolean" column="big_picture"></property>
        <property name="videoId" column="videoid" type="string"></property>
        <property name="videoId" column="videoid" type="string"></property>
        <property name="videoName" column="video_name" type="string"></property>
        <property name="videoUpdateTime" column="video_update_time" type="java.util.Date"></property>
        <property name="fromType" column="from_type" type="integer"></property>
        <many-to-one name="type" column="hometype" lazy="false" not-found="ignore"
                     unique="true"></many-to-one>
        <many-to-one name="video" column="videoid" lazy="false" not-found="ignore" update="false" insert="false"
                     unique="true"></many-to-one>
        <many-to-one name="admin" column="adminid" lazy="false"></many-to-one>
        <many-to-one name="type" column="hometype" lazy="false" not-found="ignore"
            unique="true"></many-to-one>
        <many-to-one name="video" column="videoid" lazy="false" not-found="ignore" update="false" insert="false"
            unique="true"></many-to-one>
        <many-to-one name="admin" column="adminid" lazy="false"></many-to-one>
    </class>
    </class>
</hibernate-mapping>
src/main/resources/ehcache.xml
@@ -24,6 +24,12 @@
        timeToLiveSeconds="120" overflowToDisk="true"
        memoryStoreEvictionPolicy="LRU" />
    <!-- 視頻缓存 -->
    <cache name="videoCache" maxElementsInMemory="1000"
           maxElementsOnDisk="10000" eternal="false" timeToIdleSeconds="1200"
           timeToLiveSeconds="1200" overflowToDisk="true"
           memoryStoreEvictionPolicy="LRU" />
    <!-- 配置文件缓存 -->
    <cache name="configCache" maxElementsInMemory="1000"
           maxElementsOnDisk="10000" eternal="false" timeToIdleSeconds="120"
src/main/webapp/admin/new/fenqu.html
@@ -189,7 +189,7 @@
            </div>
            <button class="btn btn-warning pl-del" type="button" v-on:click="deleteItems">批量删除</button>
            <button class="btn btn-primary pl-addrecommend" type="button" v-on:click="addToRecommends">添加推荐</button>
            <button class="btn btn-primary pl-addspecial" type="button" v-on:click="addToSpecials"  >添加到合辑</button>
            <button class="btn btn-primary pl-addspecial" type="button" v-on:click="addToSpecials">添加到合辑</button>
            <button class="btn btn-primary pl-addtop" type="button" v-on:click="addToTops">添加到榜首</button>
            <div class="page">
                <ul class="pagination">
@@ -255,7 +255,10 @@
                            <div class="bianhao videoid">{{item.id}}</div>
                        </td>
                        <td width="12%">
                            <img v-bind:src="item.hpicture" class="cover-h">
                            <div style="position: relative">
                                <img v-bind:src="item.hpicture" class="cover-h">
                                <img v-if="item.freeType>0" src="image/icon_vip.png" style="position: absolute;right: 0;bottom: 0;height: 20px;">
                            </div>
                        </td>
                        <td width="8%">
                            <img v-bind:src="item.vpicture" class="cover-v">
src/main/webapp/admin/new/tuijian-lanmuneirong-videos.html
@@ -81,6 +81,7 @@
                    <th width="7%">编号</th>
                    <th width="15%">名称</th>
                    <th width="27%">封面</th>
                    <th width="15%">来源类型</th>
                    <th width="15%">简要介绍</th>
                    <th width="15%">创建时间</th>
                    <th width="7%">删除</th>
@@ -111,6 +112,7 @@
                                <img style="width: 80%;"/>
                            </div>
                        </td>
                        <td style="text-align:center;line-height:105px;" class="fromType"></td>
                        <td style="text-align:center;line-height:105px;" class="tag"></td>
                        <td style="text-align:center;line-height:105px;" class="createtime"></td>
                        <td>
@@ -220,6 +222,7 @@
                    var pic = (da.picture == null || da.picture.length == 0) ? da.video.hpicture : da.picture;
                    fk.find(".picture img").attr("src", pic);
                    //fk.find(".picture img").attr("src", (da.picture.length < 8 ? da.juhe.hpicture : da.picture));
                    fk.find(".fromType").html(da.fromType==0?'自有库':"全网搜");
                    fk.find(".tag").html(da.tag);
                    fk.find(".createtime").html(getCommonTime(da.createtime));
                    fk.find(".edit").attr("key", da.id);
src/test/java/com/hxh/spring/test/DES.java
@@ -1,10 +1,22 @@
package com.hxh.spring.test;
import com.yeshi.buwan.util.DESUtil;
import com.yeshi.buwan.util.FileUtil;
import org.junit.Test;
import java.io.IOException;
public class DES {
    @org.junit.Test
    public void test1() {
        System.out.println(DESUtil.decode("iDp+mknN2uptRUo51EW28wcdP2q0yp6iJqknxtZcx/k="));
        System.out.println(DESUtil.decode("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"));
    }
    @Test
    public void test2() throws IOException {
        String text = FileUtil.readTxt("C:\\Users\\Administrator\\Desktop\\切片缓存\\新建文本文档.txt");
        System.out.println(DESUtil.decode(text));
    }
}
src/test/java/com/hxh/spring/test/GeneralTest.java
@@ -9,6 +9,10 @@
import com.yeshi.buwan.domain.video.VideoResourceVersionMap;
import com.yeshi.buwan.domain.vip.VideoBuyRecord;
import com.yeshi.buwan.service.inter.video.VideoResourceVersionMapService;
import com.yeshi.buwan.videos.bilibili.entity.BilibiliEpInfo;
import com.yeshi.buwan.videos.bilibili.entity.BilibiliMediaInfo;
import com.yeshi.buwan.videos.bilibili.entity.BilibiliSearchVideoMap;
import com.yeshi.buwan.videos.bilibili.entity.BilibiliVideo;
import org.yeshi.utils.generater.SpringComponentGenerater;
import org.yeshi.utils.generater.entity.MongoDBDaoData;
import org.yeshi.utils.generater.entity.ServiceData;
@@ -18,7 +22,7 @@
    @org.junit.Test
    public void createDao() {
        try {
            SpringComponentGenerater.createMongoDao(new MongoDBDaoData.Builder().setBaseDaoClass(MongodbBaseDao.class).setDaoPackageName("com.yeshi.buwan.dao.tb").setEntityClass(YouZhiHaoHuoGoods.class).create(), "D:\\workspace\\BuWan\\src\\main\\java\\com\\yeshi\\buwan\\dao\\tb\\");
            SpringComponentGenerater.createMongoDao(new MongoDBDaoData.Builder().setBaseDaoClass(MongodbBaseDao.class).setDaoPackageName("com.yeshi.buwan.dao.juhe.bilibili").setEntityClass(BilibiliSearchVideoMap.class).create(), "D:\\workspace\\BuWan\\src\\main\\java\\com\\yeshi\\buwan\\dao\\juhe\\bilibili\\");
        } catch (Exception e) {
            e.printStackTrace();
        }