diff --git a/backend/adapters/hdhive_adapter.py b/backend/adapters/hdhive_adapter.py index 8a28caf..e2386f2 100644 --- a/backend/adapters/hdhive_adapter.py +++ b/backend/adapters/hdhive_adapter.py @@ -40,6 +40,15 @@ def normalize_resource(search_data, unlock_data): resolution = (search_data or {}).get("video_resolution") source = (search_data or {}).get("source") subtitle_language = (search_data or {}).get("subtitle_language") + unlock_url = (unlock_data or {}).get("full_url") or (unlock_data or {}).get("url") or "" + media_url = (search_data or {}).get("media_url") or "" + detail_url = media_url + if not detail_url and (search_data or {}).get("media_slug"): + detail_url = f"{Config.HDHIVE_BASE_URL}/movie/{(search_data or {}).get('media_slug')}" + + validate_status = (search_data or {}).get("validate_status") + validate_message = (search_data or {}).get("validate_message") + return { "resourceTitle": (search_data or {}).get("title", ""), "quality": ", ".join(resolution) if isinstance(resolution, list) else "", @@ -50,11 +59,10 @@ def normalize_resource(search_data, unlock_data): if isinstance(subtitle_language, list) else "", "slug": (search_data or {}).get("slug", ""), - "unlockUrl": (unlock_data or {}).get("full_url") - or (unlock_data or {}).get("url") - or "", - "availability": "available" - if ((unlock_data or {}).get("full_url") or (unlock_data or {}).get("url")) - else "unknown", + "unlockUrl": unlock_url, + "detailUrl": detail_url, + "availability": "available" if unlock_url else ("index_only" if detail_url else "unknown"), + "validateStatus": validate_status, + "validateMessage": validate_message, "raw": {"searchData": search_data, "unlockData": unlock_data}, } diff --git a/frontend/src/style.css b/frontend/src/style.css index 24fef10..4fd955c 100644 --- a/frontend/src/style.css +++ b/frontend/src/style.css @@ -97,6 +97,12 @@ button:disabled { cursor: not-allowed; } +.secondary-btn { + border: 1px solid #d0d7de; + background: #fff; + color: #1f2328; +} + .grid { display: grid; grid-template-columns: 1fr 1fr; @@ -143,6 +149,16 @@ pre { color: #cf222e; } +.warning { + color: #9a6700; + background: #fff8c5; + border: 1px solid #d4a72c; + border-radius: 6px; + padding: 6px 8px; + margin: 8px 0 0; + font-size: 12px; +} + .log-time { color: #57606a; margin-left: 8px; @@ -178,6 +194,11 @@ pre { font-size: 13px; } +.poster-subtitle { + color: #57606a; + font-size: 12px; +} + .resource-list { list-style: none; margin: 0; @@ -193,8 +214,88 @@ pre { padding: 10px; } +.resource-actions { + display: flex; + flex-wrap: wrap; + gap: 10px; + align-items: center; + margin-top: 8px; +} + +.link-btn { + border: none; + background: none; + color: #1f6feb; + padding: 0; + text-decoration: underline; +} + +.link-btn:disabled { + text-decoration: none; +} + +.detail-header { + display: flex; + justify-content: space-between; + align-items: center; + gap: 12px; +} + +.detail-layout { + display: grid; + grid-template-columns: 240px 1fr; + gap: 16px; + margin-top: 12px; +} + +.detail-poster, +.detail-no-poster { + width: 100%; + height: 340px; + border-radius: 10px; + border: 1px solid #d0d7de; +} + +.detail-poster { + object-fit: cover; +} + +.detail-no-poster { + display: flex; + align-items: center; + justify-content: center; + background: #f6f8fa; + color: #57606a; +} + +.detail-content h3 { + margin-top: 2px; + margin-bottom: 8px; +} + +.detail-subtitle { + margin-top: 0; + color: #57606a; +} + +.detail-overview { + margin-top: 12px; + white-space: pre-wrap; + word-break: break-word; +} + @media (max-width: 900px) { .grid { grid-template-columns: 1fr; } + + .detail-layout { + grid-template-columns: 1fr; + } + + .detail-poster, + .detail-no-poster { + max-width: 280px; + margin: 0 auto; + } } diff --git a/frontend/src/views/MediaDetailPage.vue b/frontend/src/views/MediaDetailPage.vue index d094d01..62dc072 100644 --- a/frontend/src/views/MediaDetailPage.vue +++ b/frontend/src/views/MediaDetailPage.vue @@ -1,5 +1,5 @@ - 影视详情 + + 影视详情 + 返回搜索结果 + 加载中... {{ errorMessage }} {{ successMessage }} - {{ JSON.stringify(media, null, 2) }} + + + 暂无海报 + + {{ displayTitle }} + + 原始标题:{{ media.originalTitle }} + + + {{ media.type === "tv" ? "剧集" : "电影" }} + {{ releaseYear }} + 评分 {{ score }} + {{ genresText }} + + {{ media.overview || "暂无简介" }} + + @@ -77,13 +150,28 @@ onMounted(loadDetail); {{ res.quality || "未知画质" }} {{ res.diskType || "未知网盘" }} - - {{ - ingestingSlug === res.slug - ? "入库中..." - : res.unlockUrl || "点击该资源链接执行入库" - }} - + {{ validationHint(res) }} + + + 打开 HDHive 资源页 + + + 打开解锁直链 + + + {{ ingestingSlug === res.slug ? "入库中..." : "使用该资源入库" }} + + + 解锁失败:{{ res.unlockError }} diff --git a/frontend/src/views/SearchPage.vue b/frontend/src/views/SearchPage.vue index 70aac0f..efc5726 100644 --- a/frontend/src/views/SearchPage.vue +++ b/frontend/src/views/SearchPage.vue @@ -1,8 +1,9 @@ @@ -71,6 +94,10 @@ function goDetail(item) { /> 无海报 {{ item.title }} + + {{ item.releaseDate?.slice(0, 4) || "未知年份" }} + · 评分 {{ Number(item.voteAverage).toFixed(1) }} +
加载中...
{{ errorMessage }}
{{ successMessage }}
{{ JSON.stringify(media, null, 2) }}
+ 原始标题:{{ media.originalTitle }} +
{{ media.overview || "暂无简介" }}
{{ validationHint(res) }}
解锁失败:{{ res.unlockError }}