add 获取媒体豆瓣信息
This commit is contained in:
parent
302dff409e
commit
73a97a125c
@ -11,6 +11,7 @@
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"axios": "^1.4.0",
|
||||
"cheerio": "1.0.0-rc.12",
|
||||
"dayjs": "^1.11.8",
|
||||
"koa": "^2.14.2",
|
||||
"koa-body": "^6.0.1",
|
||||
|
114
pnpm-lock.yaml
generated
114
pnpm-lock.yaml
generated
@ -1,13 +1,12 @@
|
||||
lockfileVersion: '6.0'
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
dependencies:
|
||||
axios:
|
||||
specifier: ^1.4.0
|
||||
version: 1.4.0
|
||||
cheerio:
|
||||
specifier: 1.0.0-rc.12
|
||||
version: 1.0.0-rc.12
|
||||
dayjs:
|
||||
specifier: ^1.11.8
|
||||
version: 1.11.8
|
||||
@ -418,6 +417,10 @@ packages:
|
||||
readable-stream: 3.6.2
|
||||
dev: false
|
||||
|
||||
/boolbase@1.0.0:
|
||||
resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
|
||||
dev: false
|
||||
|
||||
/brace-expansion@1.1.11:
|
||||
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
|
||||
dependencies:
|
||||
@ -497,6 +500,30 @@ packages:
|
||||
supports-color: 5.5.0
|
||||
dev: false
|
||||
|
||||
/cheerio-select@2.1.0:
|
||||
resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==}
|
||||
dependencies:
|
||||
boolbase: 1.0.0
|
||||
css-select: 5.1.0
|
||||
css-what: 6.1.0
|
||||
domelementtype: 2.3.0
|
||||
domhandler: 5.0.3
|
||||
domutils: 3.1.0
|
||||
dev: false
|
||||
|
||||
/cheerio@1.0.0-rc.12:
|
||||
resolution: {integrity: sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==}
|
||||
engines: {node: '>= 6'}
|
||||
dependencies:
|
||||
cheerio-select: 2.1.0
|
||||
dom-serializer: 2.0.0
|
||||
domhandler: 5.0.3
|
||||
domutils: 3.1.0
|
||||
htmlparser2: 8.0.2
|
||||
parse5: 7.1.2
|
||||
parse5-htmlparser2-tree-adapter: 7.0.0
|
||||
dev: false
|
||||
|
||||
/chownr@1.1.4:
|
||||
resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==}
|
||||
dev: false
|
||||
@ -623,6 +650,21 @@ packages:
|
||||
- encoding
|
||||
dev: false
|
||||
|
||||
/css-select@5.1.0:
|
||||
resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==}
|
||||
dependencies:
|
||||
boolbase: 1.0.0
|
||||
css-what: 6.1.0
|
||||
domhandler: 5.0.3
|
||||
domutils: 3.1.0
|
||||
nth-check: 2.1.1
|
||||
dev: false
|
||||
|
||||
/css-what@6.1.0:
|
||||
resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==}
|
||||
engines: {node: '>= 6'}
|
||||
dev: false
|
||||
|
||||
/data-uri-to-buffer@5.0.1:
|
||||
resolution: {integrity: sha512-a9l6T1qqDogvvnw0nKlfZzqsyikEBZBClF39V3TFoKhDtGBqHu2HkuomJc02j5zft8zrUaXEuoicLeW54RkzPg==}
|
||||
engines: {node: '>= 14'}
|
||||
@ -713,6 +755,33 @@ packages:
|
||||
wrappy: 1.0.2
|
||||
dev: false
|
||||
|
||||
/dom-serializer@2.0.0:
|
||||
resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
|
||||
dependencies:
|
||||
domelementtype: 2.3.0
|
||||
domhandler: 5.0.3
|
||||
entities: 4.5.0
|
||||
dev: false
|
||||
|
||||
/domelementtype@2.3.0:
|
||||
resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==}
|
||||
dev: false
|
||||
|
||||
/domhandler@5.0.3:
|
||||
resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
|
||||
engines: {node: '>= 4'}
|
||||
dependencies:
|
||||
domelementtype: 2.3.0
|
||||
dev: false
|
||||
|
||||
/domutils@3.1.0:
|
||||
resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==}
|
||||
dependencies:
|
||||
dom-serializer: 2.0.0
|
||||
domelementtype: 2.3.0
|
||||
domhandler: 5.0.3
|
||||
dev: false
|
||||
|
||||
/ee-first@1.1.1:
|
||||
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
|
||||
dev: false
|
||||
@ -744,6 +813,11 @@ packages:
|
||||
once: 1.4.0
|
||||
dev: false
|
||||
|
||||
/entities@4.5.0:
|
||||
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
|
||||
engines: {node: '>=0.12'}
|
||||
dev: false
|
||||
|
||||
/env-paths@2.2.1:
|
||||
resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==}
|
||||
engines: {node: '>=6'}
|
||||
@ -1005,6 +1079,15 @@ packages:
|
||||
engines: {node: '>=8'}
|
||||
dev: false
|
||||
|
||||
/htmlparser2@8.0.2:
|
||||
resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==}
|
||||
dependencies:
|
||||
domelementtype: 2.3.0
|
||||
domhandler: 5.0.3
|
||||
domutils: 3.1.0
|
||||
entities: 4.5.0
|
||||
dev: false
|
||||
|
||||
/http-assert@1.5.0:
|
||||
resolution: {integrity: sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==}
|
||||
engines: {node: '>= 0.8'}
|
||||
@ -1572,6 +1655,12 @@ packages:
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/nth-check@2.1.1:
|
||||
resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
|
||||
dependencies:
|
||||
boolbase: 1.0.0
|
||||
dev: false
|
||||
|
||||
/object-assign@4.1.1:
|
||||
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@ -1659,6 +1748,19 @@ packages:
|
||||
lines-and-columns: 1.2.4
|
||||
dev: false
|
||||
|
||||
/parse5-htmlparser2-tree-adapter@7.0.0:
|
||||
resolution: {integrity: sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==}
|
||||
dependencies:
|
||||
domhandler: 5.0.3
|
||||
parse5: 7.1.2
|
||||
dev: false
|
||||
|
||||
/parse5@7.1.2:
|
||||
resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==}
|
||||
dependencies:
|
||||
entities: 4.5.0
|
||||
dev: false
|
||||
|
||||
/parseurl@1.3.3:
|
||||
resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==}
|
||||
engines: {node: '>= 0.8'}
|
||||
@ -2214,3 +2316,7 @@ packages:
|
||||
/zod@3.21.4:
|
||||
resolution: {integrity: sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==}
|
||||
dev: false
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
@ -1,6 +1,5 @@
|
||||
const Router = require("koa-router")
|
||||
const { route } = require(".")
|
||||
const { serach, getinfo } = require("../util/ptgen")
|
||||
const { serach, gen_douban } = require("../util/ptgen")
|
||||
|
||||
const router = new Router({
|
||||
prefix:"/videoInfo"
|
||||
@ -13,10 +12,28 @@ router.get("/search",async (ctx)=>{
|
||||
ctx.body = info
|
||||
})
|
||||
|
||||
router.get("/getinfo",async (ctx)=>{
|
||||
let url = ctx.query.url
|
||||
let info = await getinfo(url)
|
||||
// router.get("/getinfo",async (ctx)=>{
|
||||
// let url = ctx.query.url
|
||||
// let info = await getinfo(url)
|
||||
// ctx.body = info
|
||||
// })
|
||||
|
||||
router.get("/serchVideo",async (ctx)=>{
|
||||
let name = ctx.query.name
|
||||
let info = await serach(name)
|
||||
ctx.body = info
|
||||
|
||||
})
|
||||
|
||||
router.get("/getVideoInfo",async (ctx)=>{
|
||||
let id = ctx.query.id
|
||||
if(!id){
|
||||
ctx.body = "请传递id"
|
||||
return
|
||||
}
|
||||
let info = await gen_douban(id)
|
||||
ctx.body = info
|
||||
|
||||
})
|
||||
|
||||
module.exports = router
|
@ -1,22 +1,217 @@
|
||||
const axios = require("axios")
|
||||
const puppeteer = require("puppeteer")
|
||||
|
||||
const cheerio = require("cheerio"); // HTML页面解析
|
||||
async function serach(name) {
|
||||
const list = await axios.get(`https://pt.zmpt.cc/Ptgen?search=${name}`, {
|
||||
const list = await axios.get(`https://movie.douban.com/j/subject_suggest?q=${name}`, {
|
||||
proxy: false,
|
||||
})
|
||||
return list.data.data
|
||||
return {
|
||||
data: list.data.map(d => {
|
||||
return {
|
||||
...d,
|
||||
link: `https://movie.douban.com/subject/${d.id}/`
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 解析HTML页面
|
||||
function page_parser(responseText) {
|
||||
return cheerio.load(responseText, {
|
||||
decodeEntities: false
|
||||
});
|
||||
}
|
||||
// 解析JSONP返回
|
||||
function jsonp_parser(responseText) {
|
||||
try {
|
||||
responseText = responseText.replace(/\n/ig, '').match(/[^(]+\((.+)\)/)[1];
|
||||
return JSON.parse(responseText);
|
||||
} catch (e) {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
||||
async function getinfo(url) {
|
||||
const info = await axios.get(url,{
|
||||
proxy: false,
|
||||
})
|
||||
return info.data.format
|
||||
async function gen_douban(sid) {
|
||||
let data = {
|
||||
site: "douban",
|
||||
sid: sid
|
||||
};
|
||||
|
||||
// 下面开始正常的豆瓣处理流程
|
||||
let douban_link = `https://movie.douban.com/subject/${sid}/`; // 构造链接
|
||||
let db_page_resp = await fetch(douban_link); // 请求豆瓣对应项目主页面
|
||||
let douban_page_raw = await db_page_resp.text();
|
||||
|
||||
// 对异常进行处理
|
||||
if (douban_page_raw.match(/你想访问的页面不存在/)) {
|
||||
return Object.assign(data, {
|
||||
error: NONE_EXIST_ERROR
|
||||
});
|
||||
} else if (douban_page_raw.match(/检测到有异常请求/)) { // 真的会有这种可能吗?
|
||||
return Object.assign(data, {
|
||||
error: "GenHelp was temporary banned by Douban, Please wait...."
|
||||
});
|
||||
} else {
|
||||
let awards_page_req = fetch(`${douban_link}awards`) // 马上请求豆瓣获奖界面
|
||||
|
||||
// 解析主页面
|
||||
let $ = page_parser(douban_page_raw);
|
||||
|
||||
let title = $("title").text().replace("(豆瓣)", "").trim();
|
||||
|
||||
// 从ld+json中获取原来API返回的部分信息
|
||||
let ld_json = JSON.parse($('head > script[type="application/ld+json"]').html().replace(/(\r\n|\n|\r|\t)/gm, ''));
|
||||
|
||||
// 元素获取方法
|
||||
let fetch_anchor = function (anchor) {
|
||||
return anchor[0].nextSibling.nodeValue.trim();
|
||||
};
|
||||
|
||||
// 所有需要的元素
|
||||
let poster;
|
||||
let this_title, trans_title, aka;
|
||||
let year, region, genre, language, playdate;
|
||||
let imdb_link, imdb_id, imdb_average_rating, imdb_votes, imdb_rating;
|
||||
let douban_average_rating, douban_votes, douban_rating;
|
||||
let episodes, duration;
|
||||
let director, writer, cast;
|
||||
let tags, introduction, awards;
|
||||
|
||||
// 提前imdb相关请求
|
||||
let imdb_api_req;
|
||||
let imdb_anchor = $('#info span.pl:contains("IMDb")');
|
||||
if (imdb_anchor.length > 0) {
|
||||
data["imdb_id"] = imdb_id = fetch_anchor(imdb_anchor);
|
||||
data["imdb_link"] = imdb_link = `https://www.imdb.com/title/${imdb_id}/`
|
||||
imdb_api_req = fetch(`https://p.media-imdb.com/static-content/documents/v1/title/${imdb_id}/ratings%3Fjsonp=imdb.rating.run:imdb.api.title.ratings/data.json`);
|
||||
}
|
||||
|
||||
let chinese_title = data["chinese_title"] = title;
|
||||
let foreign_title = data["foreign_title"] = $('span[property="v:itemreviewed"]').text().replace(data["chinese_title"], "").trim();
|
||||
|
||||
let aka_anchor = $('#info span.pl:contains("又名")');
|
||||
if (aka_anchor.length > 0) {
|
||||
aka = fetch_anchor(aka_anchor).split(" / ").sort(function (a, b) { //首字(母)排序
|
||||
return a.localeCompare(b);
|
||||
}).join("/");
|
||||
data["aka"] = aka.split("/");
|
||||
}
|
||||
|
||||
if (foreign_title) {
|
||||
trans_title = chinese_title + (aka ? ("/" + aka) : "");
|
||||
this_title = foreign_title;
|
||||
} else {
|
||||
trans_title = aka ? aka : "";
|
||||
this_title = chinese_title;
|
||||
}
|
||||
|
||||
data["trans_title"] = trans_title.split("/");
|
||||
data["this_title"] = this_title.split("/");
|
||||
|
||||
let regions_anchor = $('#info span.pl:contains("制片国家/地区")'); //产地
|
||||
let language_anchor = $('#info span.pl:contains("语言")'); //语言
|
||||
let episodes_anchor = $('#info span.pl:contains("集数")'); //集数
|
||||
let duration_anchor = $('#info span.pl:contains("单集片长")'); //片长
|
||||
|
||||
data["year"] = year = " " + $("#content > h1 > span.year").text().substr(1, 4);
|
||||
data["region"] = region = regions_anchor[0] ? fetch_anchor(regions_anchor).split(" / ") : "";
|
||||
|
||||
data["genre"] = genre = $("#info span[property=\"v:genre\"]").map(function () { //类别
|
||||
return $(this).text().trim();
|
||||
}).toArray();
|
||||
|
||||
data["language"] = language = language_anchor[0] ? fetch_anchor(language_anchor).split(" / ") : "";
|
||||
|
||||
data["playdate"] = playdate = $("#info span[property=\"v:initialReleaseDate\"]").map(function () { //上映日期
|
||||
return $(this).text().trim();
|
||||
}).toArray().sort(function (a, b) { //按上映日期升序排列
|
||||
return new Date(a) - new Date(b);
|
||||
});
|
||||
|
||||
data["episodes"] = episodes = episodes_anchor[0] ? fetch_anchor(episodes_anchor) : "";
|
||||
data["duration"] = duration = duration_anchor[0] ? fetch_anchor(duration_anchor) : $("#info span[property=\"v:runtime\"]").text().trim();
|
||||
|
||||
// 简介 首先检查是不是有隐藏的,如果有,则直接使用隐藏span的内容作为简介,不然则用 span[property="v:summary"] 的内容
|
||||
// 20221201 issue#34 豆瓣将上一层div的id从 link-report 变为 link-report-intra
|
||||
let introduction_another = $('#link-report-intra > span.all.hidden, #link-report-intra > [property="v:summary"], #link-report > span.all.hidden, #link-report > [property="v:summary"]')
|
||||
data["introduction"] = introduction = (
|
||||
introduction_another.length > 0 ? introduction_another.text() : '暂无相关剧情介绍'
|
||||
).split('\n').map(a => a.trim()).filter(a => a.length > 0).join('\n'); // 处理简介缩进
|
||||
|
||||
// 从ld_json中获取信息
|
||||
data["douban_rating_average"] = douban_average_rating = ld_json['aggregateRating'] ? ld_json['aggregateRating']['ratingValue'] : 0;
|
||||
data["douban_votes"] = douban_votes = ld_json['aggregateRating'] ? ld_json['aggregateRating']['ratingCount'] : 0;
|
||||
data["douban_rating"] = douban_rating = `${douban_average_rating}/10 from ${douban_votes} users`;
|
||||
|
||||
data["poster"] = poster = ld_json['image']
|
||||
.replace(/s(_ratio_poster|pic)/g, "l$1")
|
||||
.replace("img3", "img1");
|
||||
|
||||
data["director"] = director = ld_json['director'] ? ld_json['director'] : [];
|
||||
data["writer"] = writer = ld_json['author'] ? ld_json['author'] : [];
|
||||
data["cast"] = cast = ld_json['actor'] ? ld_json['actor'] : [];
|
||||
|
||||
let tag_another = $('div.tags-body > a[href^="/tag"]');
|
||||
if (tag_another.length > 0) {
|
||||
data["tags"] = tags = tag_another.map(function () {
|
||||
return $(this).text()
|
||||
}).get();
|
||||
}
|
||||
|
||||
let awards_page_resp = await awards_page_req;
|
||||
let awards_page_raw = await awards_page_resp.text();
|
||||
let awards_page = page_parser(awards_page_raw);
|
||||
data["awards"] = awards = awards_page("#content > div > div.article").html()
|
||||
.replace(/[ \n]/g, "")
|
||||
.replace(/<\/li><li>/g, "</li> <li>")
|
||||
.replace(/<\/a><span/g, "</a> <span")
|
||||
.replace(/<(div|ul)[^>]*>/g, "\n")
|
||||
.replace(/<[^>]+>/g, "")
|
||||
.replace(/ /g, " ")
|
||||
.replace(/ +\n/g, "\n")
|
||||
.trim();
|
||||
|
||||
if (imdb_api_req) {
|
||||
let imdb_api_resp = await imdb_api_req;
|
||||
let imdb_api_raw = await imdb_api_resp.text();
|
||||
let imdb_json = jsonp_parser(imdb_api_raw);
|
||||
|
||||
if (imdb_json["resource"]) {
|
||||
data["imdb_rating_average"] = imdb_average_rating = imdb_json["resource"]["rating"] || 0;
|
||||
data["imdb_votes"] = imdb_votes = imdb_json["resource"]["ratingCount"] || 0;
|
||||
data["imdb_rating"] = imdb_rating = `${imdb_average_rating}/10 from ${imdb_votes} users`;
|
||||
}
|
||||
}
|
||||
|
||||
// 生成format
|
||||
let descr = poster ? `[img]${poster}[/img]\n\n` : "";
|
||||
descr += trans_title ? `◎译 名 ${trans_title}\n` : "";
|
||||
descr += this_title ? `◎片 名 ${this_title}\n` : "";
|
||||
descr += year ? `◎年 代 ${year.trim()}\n` : "";
|
||||
descr += region ? `◎产 地 ${region}\n` : "";
|
||||
descr += genre ? `◎类 别 ${genre.join(" / ")}\n` : "";
|
||||
descr += language ? `◎语 言 ${language}\n` : "";
|
||||
descr += playdate ? `◎上映日期 ${playdate.join(" / ")}\n` : "";
|
||||
descr += imdb_rating ? `◎IMDb评分 ${imdb_rating}\n` : "";
|
||||
descr += imdb_link ? `◎IMDb链接 ${imdb_link}\n` : "";
|
||||
descr += douban_rating ? `◎豆瓣评分 ${douban_rating}\n` : "";
|
||||
descr += douban_link ? `◎豆瓣链接 ${douban_link}\n` : "";
|
||||
descr += episodes ? `◎集 数 ${episodes}\n` : "";
|
||||
descr += duration ? `◎片 长 ${duration}\n` : "";
|
||||
descr += director && director.length > 0 ? `◎导 演 ${director.map(x => x['name']).join(" / ")}\n` : "";
|
||||
descr += writer && writer.length > 0 ? `◎编 剧 ${writer.map(x => x['name']).join(" / ")}\n` : "";
|
||||
descr += cast && cast.length > 0 ? `◎主 演 ${cast.map(x => x['name']).join("\n" + " ".repeat(4) + " ").trim()}\n` : "";
|
||||
descr += tags && tags.length > 0 ? `\n◎标 签 ${tags.join(" | ")}\n` : "";
|
||||
descr += introduction ? `\n◎简 介\n\n ${introduction.replace(/\n/g, "\n" + " ".repeat(2))}\n` : "";
|
||||
descr += awards ? `\n◎获奖情况\n\n ${awards.replace(/\n/g, "\n" + " ".repeat(2))}\n` : "";
|
||||
|
||||
data["format"] = descr.trim();
|
||||
data["success"] = true; // 更新状态为成功
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
serach,
|
||||
getinfo
|
||||
gen_douban
|
||||
}
|
@ -5,6 +5,7 @@
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Vite + Vue</title>
|
||||
<meta name="referrer" content="never">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
@ -1,8 +1,16 @@
|
||||
import { base } from "./base";
|
||||
export async function getVideoInfo(name){
|
||||
return await base.get("/videoInfo/search",{
|
||||
export async function getVideoInfo(id){
|
||||
return await base.get("/videoInfo/getVideoInfo",{
|
||||
params:{
|
||||
id
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export async function serchVideo(name){
|
||||
return await base.get("/videoInfo/serchVideo",{
|
||||
params:{
|
||||
name
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,12 @@ import {router} from "../router/index.js";
|
||||
订阅管理
|
||||
</template>
|
||||
<el-menu-item-group>
|
||||
<el-menu-item index="/addSubscribe">
|
||||
<el-icon>
|
||||
<VideoCamera/>
|
||||
</el-icon>
|
||||
添加订阅
|
||||
</el-menu-item>
|
||||
<el-menu-item index="/subscribe">
|
||||
<el-icon>
|
||||
<VideoCamera/>
|
||||
|
99
view/src/page/subscribe/addSubscribe.vue
Normal file
99
view/src/page/subscribe/addSubscribe.vue
Normal file
@ -0,0 +1,99 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-form :inline="true" :model="formInline" class="demo-form-inline">
|
||||
<el-form-item label="名称">
|
||||
<el-input v-model="formInline.name" placeholder="Approved by" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onSubmit">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="list">
|
||||
<div class="item" v-for="i in list">
|
||||
<el-card :body-style="{ padding: '0px' }">
|
||||
<img :src="i.img" class="image" />
|
||||
<div style="padding: 14px">
|
||||
<span>{{ i.title }}({{ i.year }})</span>
|
||||
<div class="bottom">
|
||||
<time class="time">类型:{{ i.type }}</time>
|
||||
<el-button text class="button" @click="getinfo(i.id)">详情</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</div>
|
||||
<el-dialog v-model="dialogFormVisible" title="详情">
|
||||
<textarea style="width: 95%;height: 400px;" v-model="info"></textarea>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="dialogFormVisible = false">Cancel</el-button>
|
||||
<el-button type="primary" @click="dialogFormVisible = false">
|
||||
Confirm
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { getVideoInfo, serchVideo } from '../../api/Video.js'
|
||||
|
||||
const formInline = ref({
|
||||
name: ""
|
||||
})
|
||||
let list = ref([])
|
||||
const info = ref("")
|
||||
async function onSubmit() {
|
||||
let res = await serchVideo(formInline.value.name)
|
||||
list.value = res.data.data
|
||||
}
|
||||
let vid = "";
|
||||
const dialogFormVisible = ref(false)
|
||||
async function getinfo(id) {
|
||||
vid = id
|
||||
let res = await getVideoInfo(id)
|
||||
info.value = res.data.format
|
||||
dialogFormVisible.value = true
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.item {
|
||||
width: 200px;
|
||||
margin: 20px;
|
||||
|
||||
& img {
|
||||
height: 300px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.time {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.bottom {
|
||||
margin-top: 13px;
|
||||
line-height: 12px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.button {
|
||||
padding: 0;
|
||||
min-height: auto;
|
||||
min-width: 40px;
|
||||
}
|
||||
|
||||
.image {
|
||||
width: 100%;
|
||||
display: block;
|
||||
}</style>
|
@ -20,14 +20,20 @@
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.list{
|
||||
.list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
.item{
|
||||
|
||||
.item {
|
||||
width: 200px;
|
||||
margin: 20px;
|
||||
|
||||
& img {
|
||||
height: 300px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.time {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
@ -51,5 +57,4 @@
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
@ -19,6 +19,11 @@ const routes = [
|
||||
path: "subscribe",
|
||||
name: "subscribe",
|
||||
component:() => import ("../page/subscribe/subscribe.vue")
|
||||
},
|
||||
{
|
||||
path: "addSubscribe",
|
||||
name: "addSubscribe",
|
||||
component:() => import ("../page/subscribe/addSubscribe.vue")
|
||||
}
|
||||
],
|
||||
component: () => import("../page/index.vue"),
|
||||
|
Loading…
Reference in New Issue
Block a user