chore: 跑一遍 auto-correct (#468)
This commit is contained in:
@@ -32,7 +32,7 @@ pub async fn get_created_favorites(
|
|||||||
let bili_favorites = me.get_created_favorites().await?;
|
let bili_favorites = me.get_created_favorites().await?;
|
||||||
|
|
||||||
let favorites = if let Some(bili_favorites) = bili_favorites {
|
let favorites = if let Some(bili_favorites) = bili_favorites {
|
||||||
// b 站收藏夹相关接口使用的所谓 “fid” 其实是该处的 id,即 fid + mid 后两位
|
// b 站收藏夹相关接口使用的所谓“fid”其实是该处的 id,即 fid + mid 后两位
|
||||||
let bili_fids: Vec<_> = bili_favorites.iter().map(|fav| fav.id).collect();
|
let bili_fids: Vec<_> = bili_favorites.iter().map(|fav| fav.id).collect();
|
||||||
|
|
||||||
let subscribed_fids: Vec<i64> = favorite::Entity::find()
|
let subscribed_fids: Vec<i64> = favorite::Entity::find()
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ pub struct DanmakuOption {
|
|||||||
pub bottom_percentage: f64,
|
pub bottom_percentage: f64,
|
||||||
/// 透明度(0-255)
|
/// 透明度(0-255)
|
||||||
pub opacity: u8,
|
pub opacity: u8,
|
||||||
/// 是否加粗,1代表是,0代表否
|
/// 是否加粗,1 代表是,0 代表否
|
||||||
pub bold: bool,
|
pub bold: bool,
|
||||||
/// 描边
|
/// 描边
|
||||||
pub outline: f64,
|
pub outline: f64,
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ pub struct Danmu {
|
|||||||
impl Danmu {
|
impl Danmu {
|
||||||
/// 计算弹幕的“像素长度”,会乘上一个缩放因子
|
/// 计算弹幕的“像素长度”,会乘上一个缩放因子
|
||||||
///
|
///
|
||||||
/// 汉字算一个全宽,英文算2/3宽
|
/// 汉字算一个全宽,英文算 2/3 宽
|
||||||
pub fn length(&self, config: &CanvasConfig<'_>) -> f64 {
|
pub fn length(&self, config: &CanvasConfig<'_>) -> f64 {
|
||||||
let pts = config.danmaku_option.font_size
|
let pts = config.danmaku_option.font_size
|
||||||
* self
|
* self
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ pub struct SubTitleItem {
|
|||||||
impl SubTitleInfo {
|
impl SubTitleInfo {
|
||||||
pub fn is_ai_sub(&self) -> bool {
|
pub fn is_ai_sub(&self) -> bool {
|
||||||
// ai: aisubtitle.hdslb.com/bfs/ai_subtitle/xxxx
|
// ai: aisubtitle.hdslb.com/bfs/ai_subtitle/xxxx
|
||||||
// 非 ai: aisubtitle.hdslb.com/bfs/subtitle/xxxx
|
// 非 ai:aisubtitle.hdslb.com/bfs/subtitle/xxxx
|
||||||
self.subtitle_url.contains("ai_subtitle")
|
self.subtitle_url.contains("ai_subtitle")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ mod tests {
|
|||||||
"test_truncate",
|
"test_truncate",
|
||||||
&json!({"title": "你说得对,但是 Rust 是由 Mozilla 自主研发的一款全新的编译期格斗游戏。\
|
&json!({"title": "你说得对,但是 Rust 是由 Mozilla 自主研发的一款全新的编译期格斗游戏。\
|
||||||
编译将发生在一个被称作「Cargo」的构建系统中。在这里,被引用的指针将被授予「生命周期」之力,导引对象安全。\
|
编译将发生在一个被称作「Cargo」的构建系统中。在这里,被引用的指针将被授予「生命周期」之力,导引对象安全。\
|
||||||
你将扮演一位名为「Rustacean」的神秘角色, 在与「Rustc」的搏斗中邂逅各种骨骼惊奇的傲娇报错。\
|
你将扮演一位名为「Rustacean」的神秘角色,在与「Rustc」的搏斗中邂逅各种骨骼惊奇的傲娇报错。\
|
||||||
征服她们、通过编译同时,逐步发掘「C++」程序崩溃的真相。"})
|
征服她们、通过编译同时,逐步发掘「C++」程序崩溃的真相。"})
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ pub async fn http_server(
|
|||||||
let listener = tokio::net::TcpListener::bind(&config.bind_address)
|
let listener = tokio::net::TcpListener::bind(&config.bind_address)
|
||||||
.await
|
.await
|
||||||
.context("bind address failed")?;
|
.context("bind address failed")?;
|
||||||
info!("开始运行管理页: http://{}", config.bind_address);
|
info!("开始运行管理页:http://{}", config.bind_address);
|
||||||
Ok(axum::serve(listener, ServiceExt::<Request>::into_make_service(app)).await?)
|
Ok(axum::serve(listener, ServiceExt::<Request>::into_make_service(app)).await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -143,14 +143,14 @@ mod tests {
|
|||||||
let test_cases = vec![
|
let test_cases = vec![
|
||||||
(
|
(
|
||||||
Rule(vec![vec![RuleTarget::Title(Condition::Contains("唐氏".to_string()))]]),
|
Rule(vec![vec![RuleTarget::Title(Condition::Contains("唐氏".to_string()))]]),
|
||||||
"「(标题包含“唐氏”)」",
|
"「(标题包含“唐氏”)」",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
Rule(vec![vec![
|
Rule(vec![vec![
|
||||||
RuleTarget::Title(Condition::Prefix("街霸".to_string())),
|
RuleTarget::Title(Condition::Prefix("街霸".to_string())),
|
||||||
RuleTarget::Tags(Condition::Contains("套路".to_string())),
|
RuleTarget::Tags(Condition::Contains("套路".to_string())),
|
||||||
]]),
|
]]),
|
||||||
"「(标题以“街霸”开头)且(标签包含“套路”)」",
|
"「(标题以“街霸”开头)且(标签包含“套路”)」",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
Rule(vec![
|
Rule(vec![
|
||||||
@@ -168,14 +168,14 @@ mod tests {
|
|||||||
)),
|
)),
|
||||||
],
|
],
|
||||||
]),
|
]),
|
||||||
"「(标题包含“Rust”)且(视频分页数量大于“5”)」或「(标签以“入门”结尾)且(发布时间大于“2023-01-01 00:00:00”)」",
|
"「(标题包含“Rust”)且(视频分页数量大于“5”)」或「(标签以“入门”结尾)且(发布时间大于“2023-01-01 00:00:00”)」",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
Rule(vec![vec![
|
Rule(vec![vec![
|
||||||
RuleTarget::Not(Box::new(RuleTarget::Title(Condition::Contains("广告".to_string())))),
|
RuleTarget::Not(Box::new(RuleTarget::Title(Condition::Contains("广告".to_string())))),
|
||||||
RuleTarget::PageCount(Condition::LessThan(10)),
|
RuleTarget::PageCount(Condition::LessThan(10)),
|
||||||
]]),
|
]]),
|
||||||
"「(标题不包含“广告”)且(视频分页数量小于“10”)」",
|
"「(标题不包含“广告”)且(视频分页数量小于“10”)」",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
Rule(vec![vec![
|
Rule(vec![vec![
|
||||||
@@ -189,12 +189,14 @@ mod tests {
|
|||||||
.and_hms_opt(23, 59, 59)
|
.and_hms_opt(23, 59, 59)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
)),
|
)),
|
||||||
|
// autocorrect-disable
|
||||||
RuleTarget::Tags(Condition::MatchesRegex(
|
RuleTarget::Tags(Condition::MatchesRegex(
|
||||||
"技术|教程".to_string(),
|
"技术|教程".to_string(),
|
||||||
regex::Regex::new("技术|教程").unwrap(),
|
regex::Regex::new("技术|教程").unwrap(),
|
||||||
)),
|
)),
|
||||||
]]),
|
]]),
|
||||||
"「(收藏时间在“2023-06-01 00:00:00”和“2023-12-31 23:59:59”之间)且(标签匹配“技术|教程”)」",
|
"「(收藏时间在“2023-06-01 00:00:00”和“2023-12-31 23:59:59”之间)且(标签匹配“技术|教程”)」",
|
||||||
|
// autocorrect-enable
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -243,7 +245,7 @@ mod tests {
|
|||||||
(
|
(
|
||||||
video::ActiveModel {
|
video::ActiveModel {
|
||||||
name: Set(
|
name: Set(
|
||||||
"万字怒扒网易《归唐》底裤!中国首款大厂买断制单机,靠谱吗?——全网最全!官方非独家幕后!关于《归唐》PV的所有秘密~都在这里了~".to_owned(),
|
"万字怒扒网易《归唐》底裤!中国首款大厂买断制单机,靠谱吗?——全网最全!官方非独家幕后!关于《归唐》PV 的所有秘密~都在这里了~".to_owned(),
|
||||||
),
|
),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -288,12 +288,12 @@ pub async fn download_video_pages(
|
|||||||
ExecutionStatus::Succeeded => info!("处理视频「{}」{}成功", &video_model.name, task_name),
|
ExecutionStatus::Succeeded => info!("处理视频「{}」{}成功", &video_model.name, task_name),
|
||||||
ExecutionStatus::Ignored(e) => {
|
ExecutionStatus::Ignored(e) => {
|
||||||
error!(
|
error!(
|
||||||
"处理视频「{}」{}出现常见错误,已忽略: {:#}",
|
"处理视频「{}」{}出现常见错误,已忽略:{:#}",
|
||||||
&video_model.name, task_name, e
|
&video_model.name, task_name, e
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ExecutionStatus::Failed(e) | ExecutionStatus::FixedFailed(_, e) => {
|
ExecutionStatus::Failed(e) | ExecutionStatus::FixedFailed(_, e) => {
|
||||||
error!("处理视频「{}」{}失败: {:#}", &video_model.name, task_name, e)
|
error!("处理视频「{}」{}失败:{:#}", &video_model.name, task_name, e)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if let ExecutionStatus::Failed(e) = results.into_iter().nth(4).context("page download result not found")?
|
if let ExecutionStatus::Failed(e) = results.into_iter().nth(4).context("page download result not found")?
|
||||||
@@ -478,12 +478,12 @@ pub async fn download_page(
|
|||||||
),
|
),
|
||||||
ExecutionStatus::Ignored(e) => {
|
ExecutionStatus::Ignored(e) => {
|
||||||
error!(
|
error!(
|
||||||
"处理视频「{}」第 {} 页{}出现常见错误,已忽略: {:#}",
|
"处理视频「{}」第 {} 页{}出现常见错误,已忽略:{:#}",
|
||||||
&video_model.name, page_model.pid, task_name, e
|
&video_model.name, page_model.pid, task_name, e
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ExecutionStatus::Failed(e) | ExecutionStatus::FixedFailed(_, e) => error!(
|
ExecutionStatus::Failed(e) | ExecutionStatus::FixedFailed(_, e) => error!(
|
||||||
"处理视频「{}」第 {} 页{}失败: {:#}",
|
"处理视频「{}」第 {} 页{}失败:{:#}",
|
||||||
&video_model.name, page_model.pid, task_name, e
|
&video_model.name, page_model.pid, task_name, e
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ impl Display for Rule {
|
|||||||
.0
|
.0
|
||||||
.iter()
|
.iter()
|
||||||
.map(|group| {
|
.map(|group| {
|
||||||
let conditions: Vec<String> = group.iter().map(|target| format!("({})", target)).collect();
|
let conditions: Vec<String> = group.iter().map(|target| format!("({})", target)).collect();
|
||||||
format!("「{}」", conditions.join("且"))
|
format!("「{}」", conditions.join("且"))
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
EMBY 的一般结构是: `媒体库 - 文件夹 - 电影/电视剧 - 分季/分集`,方便起见,我采用了如下的对应关系:
|
EMBY 的一般结构是: `媒体库 - 文件夹 - 电影/电视剧 - 分季/分集`,方便起见,我采用了如下的对应关系:
|
||||||
|
|
||||||
1. **文件夹**:对应 b 站的 video source;
|
1. **文件夹**:对应 b 站的 video source;
|
||||||
2. **电视剧**: 对应 b 站的 video;
|
2. **电视剧**:对应 b 站的 video;
|
||||||
3. **第一季的所有分集**:对应 b 站的 page。
|
3. **第一季的所有分集**:对应 b 站的 page。
|
||||||
|
|
||||||
特别的,当 video 仅有一个 page 时,为了避免过多的层级,bili-sync 会将 page 展开到第二层级,变成与电视剧同级的电影。
|
特别的,当 video 仅有一个 page 时,为了避免过多的层级,bili-sync 会将 page 展开到第二层级,变成与电视剧同级的电影。
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
在[程序发布页](https://github.com/amtoaer/bili-sync/releases)选择最新版本中对应机器架构的压缩包,解压后会获取一个名为 `bili-sync-rs` 的可执行文件,直接双击执行。
|
在[程序发布页](https://github.com/amtoaer/bili-sync/releases)选择最新版本中对应机器架构的压缩包,解压后会获取一个名为 `bili-sync-rs` 的可执行文件,直接双击执行。
|
||||||
|
|
||||||
### 其二: 使用 Docker Compose 运行
|
### 其二:使用 Docker Compose 运行
|
||||||
|
|
||||||
Linux/amd64 与 Linux/arm64 两个平台可直接使用 Docker 或 Docker Compose 运行,此处以 Compose 为例:
|
Linux/amd64 与 Linux/arm64 两个平台可直接使用 Docker 或 Docker Compose 运行,此处以 Compose 为例:
|
||||||
> 请注意其中的注释,有不清楚的地方可以先继续往下看。
|
> 请注意其中的注释,有不清楚的地方可以先继续往下看。
|
||||||
@@ -88,9 +88,9 @@ Jul 12 16:11:10 INFO 开始运行管理页: http://0.0.0.0:12345
|
|||||||
|
|
||||||
认证后会看到一系列的配置,除绑定地址外的选项**基本都会实时生效**。为避免意料外的情况,建议将配置文件一次修改完毕后再点击保存。
|
认证后会看到一系列的配置,除绑定地址外的选项**基本都会实时生效**。为避免意料外的情况,建议将配置文件一次修改完毕后再点击保存。
|
||||||
|
|
||||||
如无特殊需求,一般仅需修改“B站认证”与“视频质量”两个标签下的配置。
|
如无特殊需求,一般仅需修改“B 站认证”与“视频质量”两个标签下的配置。
|
||||||
|
|
||||||
其中“B站认证”在一次填写后即可忽略,程序会在**每日第一次运行视频下载任务**时检查认证状态,并在有必要时自动刷新。
|
其中“B 站认证”在一次填写后即可忽略,程序会在**每日第一次运行视频下载任务**时检查认证状态,并在有必要时自动刷新。
|
||||||
|
|
||||||
对于这些设置项的含义,请参考[配置说明](./configuration.md),可善用右侧导航在不同配置项间跳转。
|
对于这些设置项的含义,请参考[配置说明](./configuration.md),可善用右侧导航在不同配置项间跳转。
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ Jul 12 16:11:10 INFO 开始运行管理页: http://0.0.0.0:12345
|
|||||||
|
|
||||||
配置完毕后,我们便可以随时添加视频源订阅。
|
配置完毕后,我们便可以随时添加视频源订阅。
|
||||||
|
|
||||||
用户在正确填写“B站认证”后可以在“快捷订阅”部分查看自己创建的收藏夹、关注的合集与 UP 主一键订阅,也可以在“视频源”页手动添加并管理。
|
用户在正确填写“B 站认证”后可以在“快捷订阅”部分查看自己创建的收藏夹、关注的合集与 UP 主一键订阅,也可以在“视频源”页手动添加并管理。
|
||||||
|
|
||||||
对于手动添加的视频源,可参考如下页面获取所需的参数:
|
对于手动添加的视频源,可参考如下页面获取所需的参数:
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ from pathlib import Path
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
if len(sys.argv) <= 1:
|
if len(sys.argv) <= 1:
|
||||||
print("用法: python 2.0.3_add_fanart.py <path1> <path2> ...")
|
print("用法:python 2.0.3_add_fanart.py <path1> <path2> ...")
|
||||||
exit(1)
|
exit(1)
|
||||||
paths = [Path(path) for path in sys.argv[1:]]
|
paths = [Path(path) for path in sys.argv[1:]]
|
||||||
for path in paths:
|
for path in paths:
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ class ApiClient {
|
|||||||
clearAuthToken() {
|
clearAuthToken() {
|
||||||
delete this.defaultHeaders['Authorization'];
|
delete this.defaultHeaders['Authorization'];
|
||||||
localStorage.removeItem('authToken');
|
localStorage.removeItem('authToken');
|
||||||
// 断开WebSocket连接,因为token已经无效
|
// 断开 WebSocket 连接,因为 token 已经无效
|
||||||
wsManager.disconnect();
|
wsManager.disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
export let onsubmit: (request: UpdateVideoStatusRequest) => void;
|
export let onsubmit: (request: UpdateVideoStatusRequest) => void;
|
||||||
|
|
||||||
// 视频任务名称(与后端 VideoStatus 对应)
|
// 视频任务名称(与后端 VideoStatus 对应)
|
||||||
const videoTaskNames = ['视频封面', '视频信息', 'UP主头像', 'UP主信息', '分页下载'];
|
const videoTaskNames = ['视频封面', '视频信息', 'UP 主头像', 'UP 主信息', '分页下载'];
|
||||||
|
|
||||||
// 分页任务名称(与后端 PageStatus 对应)
|
// 分页任务名称(与后端 PageStatus 对应)
|
||||||
const pageTaskNames = ['视频封面', '视频内容', '视频信息', '视频弹幕', '视频字幕'];
|
const pageTaskNames = ['视频封面', '视频内容', '视频信息', '视频弹幕', '视频字幕'];
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
case 'collection':
|
case 'collection':
|
||||||
return '合集';
|
return '合集';
|
||||||
case 'upper':
|
case 'upper':
|
||||||
return 'UP主';
|
return 'UP 主';
|
||||||
default:
|
default:
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
let customPath = '';
|
let customPath = '';
|
||||||
let loading = false;
|
let loading = false;
|
||||||
|
|
||||||
// 根据类型和item生成默认路径
|
// 根据类型和 item 生成默认路径
|
||||||
function generateDefaultPath(): string {
|
function generateDefaultPath(): string {
|
||||||
if (!item) return '';
|
if (!item) return '';
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@
|
|||||||
}
|
}
|
||||||
case 'upper': {
|
case 'upper': {
|
||||||
const upper = item as UpperWithSubscriptionStatus;
|
const upper = item as UpperWithSubscriptionStatus;
|
||||||
return `UP主/${upper.uname}`;
|
return `UP 主/${upper.uname}`;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return '';
|
return '';
|
||||||
@@ -63,7 +63,7 @@
|
|||||||
case 'collection':
|
case 'collection':
|
||||||
return '合集';
|
return '合集';
|
||||||
case 'upper':
|
case 'upper':
|
||||||
return 'UP主';
|
return 'UP 主';
|
||||||
default:
|
default:
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
@@ -145,7 +145,7 @@
|
|||||||
open = false;
|
open = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 当对话框打开时重置path
|
// 当对话框打开时重置 path
|
||||||
$: if (open && item) {
|
$: if (open && item) {
|
||||||
customPath = generateDefaultPath();
|
customPath = generateDefaultPath();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ export interface CollectionsResponse {
|
|||||||
total: number;
|
total: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
// UP主相关类型
|
// UP 主相关类型
|
||||||
export interface UpperWithSubscriptionStatus {
|
export interface UpperWithSubscriptionStatus {
|
||||||
mid: number;
|
mid: number;
|
||||||
uname: string;
|
uname: string;
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ export class WebSocketManager {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to parse WebSocket message:', error, event.data);
|
console.error('Failed to parse WebSocket message:', error, event.data);
|
||||||
toast.error('解析 WebSocket 消息失败', {
|
toast.error('解析 WebSocket 消息失败', {
|
||||||
description: `消息内容: ${event.data}\n错误信息: ${error instanceof Error ? error.message : String(error)}`
|
description: `消息内容:${event.data}\n错误信息:${error instanceof Error ? error.message : String(error)}`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -137,7 +137,7 @@ export class WebSocketManager {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to send message:', error);
|
console.error('Failed to send message:', error);
|
||||||
toast.error('发送 WebSocket 消息失败', {
|
toast.error('发送 WebSocket 消息失败', {
|
||||||
description: `消息内容: ${JSON.stringify(message)}\n错误信息: ${error instanceof Error ? error.message : String(error)}`
|
description: `消息内容:${JSON.stringify(message)}\n错误信息:${error instanceof Error ? error.message : String(error)}`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@
|
|||||||
const response = await api.getDashboard();
|
const response = await api.getDashboard();
|
||||||
dashboardData = response.data;
|
dashboardData = response.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('加载仪表盘数据失败:', error);
|
console.error('加载仪表盘数据失败:', error);
|
||||||
toast.error('加载仪表盘数据失败', {
|
toast.error('加载仪表盘数据失败', {
|
||||||
description: (error as ApiError).message
|
description: (error as ApiError).message
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -17,11 +17,11 @@
|
|||||||
async function loadCollections(page: number = 0) {
|
async function loadCollections(page: number = 0) {
|
||||||
loading = true;
|
loading = true;
|
||||||
try {
|
try {
|
||||||
const response = await api.getFollowedCollections(page + 1, pageSize); // API使用1基索引
|
const response = await api.getFollowedCollections(page + 1, pageSize); // API 使用 1 基索引
|
||||||
collections = response.data.collections;
|
collections = response.data.collections;
|
||||||
totalCount = response.data.total;
|
totalCount = response.data.total;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('加载合集失败:', error);
|
console.error('加载合集失败:', error);
|
||||||
toast.error('加载合集失败', {
|
toast.error('加载合集失败', {
|
||||||
description: (error as ApiError).message
|
description: (error as ApiError).message
|
||||||
});
|
});
|
||||||
@@ -92,7 +92,7 @@
|
|||||||
<div class="flex items-center justify-center py-12">
|
<div class="flex items-center justify-center py-12">
|
||||||
<div class="space-y-2 text-center">
|
<div class="space-y-2 text-center">
|
||||||
<p class="text-muted-foreground">暂无合集数据</p>
|
<p class="text-muted-foreground">暂无合集数据</p>
|
||||||
<p class="text-muted-foreground text-sm">请先在B站关注一些合集,或检查账号配置</p>
|
<p class="text-muted-foreground text-sm">请先在 B 站关注一些合集,或检查账号配置</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
const response = await api.getCreatedFavorites();
|
const response = await api.getCreatedFavorites();
|
||||||
favorites = response.data.favorites;
|
favorites = response.data.favorites;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('加载收藏夹失败:', error);
|
console.error('加载收藏夹失败:', error);
|
||||||
toast.error('加载收藏夹失败', {
|
toast.error('加载收藏夹失败', {
|
||||||
description: (error as ApiError).message
|
description: (error as ApiError).message
|
||||||
});
|
});
|
||||||
@@ -73,7 +73,7 @@
|
|||||||
<div class="flex items-center justify-center py-12">
|
<div class="flex items-center justify-center py-12">
|
||||||
<div class="space-y-2 text-center">
|
<div class="space-y-2 text-center">
|
||||||
<p class="text-muted-foreground">暂无收藏夹数据</p>
|
<p class="text-muted-foreground">暂无收藏夹数据</p>
|
||||||
<p class="text-muted-foreground text-sm">请先在B站创建收藏夹,或检查账号配置</p>
|
<p class="text-muted-foreground text-sm">请先在 B 站创建收藏夹,或检查账号配置</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -17,12 +17,12 @@
|
|||||||
async function loadUppers(page: number = 0) {
|
async function loadUppers(page: number = 0) {
|
||||||
loading = true;
|
loading = true;
|
||||||
try {
|
try {
|
||||||
const response = await api.getFollowedUppers(page + 1, pageSize); // API使用1基索引
|
const response = await api.getFollowedUppers(page + 1, pageSize); // API 使用 1 基索引
|
||||||
uppers = response.data.uppers;
|
uppers = response.data.uppers;
|
||||||
totalCount = response.data.total;
|
totalCount = response.data.total;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('加载UP主失败:', error);
|
console.error('加载 UP 主失败:', error);
|
||||||
toast.error('加载UP主失败', {
|
toast.error('加载 UP 主失败', {
|
||||||
description: (error as ApiError).message
|
description: (error as ApiError).message
|
||||||
});
|
});
|
||||||
} finally {
|
} finally {
|
||||||
@@ -92,8 +92,8 @@
|
|||||||
{:else}
|
{:else}
|
||||||
<div class="flex items-center justify-center py-12">
|
<div class="flex items-center justify-center py-12">
|
||||||
<div class="space-y-2 text-center">
|
<div class="space-y-2 text-center">
|
||||||
<p class="text-muted-foreground">暂无UP主数据</p>
|
<p class="text-muted-foreground">暂无 UP 主数据</p>
|
||||||
<p class="text-muted-foreground text-sm">请先在B站关注一些UP主,或检查账号配置</p>
|
<p class="text-muted-foreground text-sm">请先在 B 站关注一些 UP 主,或检查账号配置</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -25,8 +25,8 @@
|
|||||||
async function loadVideoDetail() {
|
async function loadVideoDetail() {
|
||||||
const videoId = parseInt($page.params.id);
|
const videoId = parseInt($page.params.id);
|
||||||
if (isNaN(videoId)) {
|
if (isNaN(videoId)) {
|
||||||
error = '无效的视频ID';
|
error = '无效的视频 ID';
|
||||||
toast.error('无效的视频ID');
|
toast.error('无效的视频 ID');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
loading = true;
|
loading = true;
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
const result = await api.getVideo(videoId);
|
const result = await api.getVideo(videoId);
|
||||||
videoData = result.data;
|
videoData = result.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('加载视频详情失败:', error);
|
console.error('加载视频详情失败:', error);
|
||||||
toast.error('加载视频详情失败', {
|
toast.error('加载视频详情失败', {
|
||||||
description: (error as ApiError).message
|
description: (error as ApiError).message
|
||||||
});
|
});
|
||||||
@@ -79,7 +79,7 @@
|
|||||||
toast.error('状态更新失败');
|
toast.error('状态更新失败');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('状态更新失败:', error);
|
console.error('状态更新失败:', error);
|
||||||
toast.error('状态更新失败', {
|
toast.error('状态更新失败', {
|
||||||
description: (error as ApiError).message
|
description: (error as ApiError).message
|
||||||
});
|
});
|
||||||
@@ -161,7 +161,7 @@
|
|||||||
}}
|
}}
|
||||||
mode="detail"
|
mode="detail"
|
||||||
showActions={false}
|
showActions={false}
|
||||||
taskNames={['视频封面', '视频信息', 'UP主头像', 'UP主信息', '分页下载']}
|
taskNames={['视频封面', '视频信息', 'UP 主头像', 'UP 主信息', '分页下载']}
|
||||||
bind:resetDialogOpen
|
bind:resetDialogOpen
|
||||||
bind:resetting
|
bind:resetting
|
||||||
onReset={async (forceReset: boolean) => {
|
onReset={async (forceReset: boolean) => {
|
||||||
@@ -225,8 +225,8 @@
|
|||||||
{:else}
|
{:else}
|
||||||
<div class="py-12 text-center">
|
<div class="py-12 text-center">
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
<p class="text-muted-foreground">暂无分P数据</p>
|
<p class="text-muted-foreground">暂无分 P 数据</p>
|
||||||
<p class="text-muted-foreground text-sm">该视频可能为单P视频</p>
|
<p class="text-muted-foreground text-sm">该视频可能为单 P 视频</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -75,7 +75,7 @@
|
|||||||
const result = await api.getVideos(params);
|
const result = await api.getVideos(params);
|
||||||
videosData = result.data;
|
videosData = result.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('加载视频失败:', error);
|
console.error('加载视频失败:', error);
|
||||||
toast.error('加载视频失败', {
|
toast.error('加载视频失败', {
|
||||||
description: (error as ApiError).message
|
description: (error as ApiError).message
|
||||||
});
|
});
|
||||||
@@ -111,7 +111,7 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('重置失败:', error);
|
console.error('重置失败:', error);
|
||||||
toast.error('重置失败', {
|
toast.error('重置失败', {
|
||||||
description: (error as ApiError).message
|
description: (error as ApiError).message
|
||||||
});
|
});
|
||||||
@@ -133,7 +133,7 @@
|
|||||||
toast.info('没有需要重置的视频');
|
toast.info('没有需要重置的视频');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('重置失败:', error);
|
console.error('重置失败:', error);
|
||||||
toast.error('重置失败', {
|
toast.error('重置失败', {
|
||||||
description: (error as ApiError).message
|
description: (error as ApiError).message
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user