commit 36e490a1144f10da3357b14591204ca319121526 Author: XIGE <710062962@qq.com> Date: Mon Feb 23 17:13:52 2026 +0800 1.0 diff --git a/Plugin.php b/Plugin.php new file mode 100644 index 0000000..d43accd --- /dev/null +++ b/Plugin.php @@ -0,0 +1,1861 @@ +contentEx = array('BookInfo_Plugin', 'parse'); + Typecho_Plugin::factory('Widget_Abstract_Contents')->excerptEx = array('BookInfo_Plugin', 'parse'); + Typecho_Plugin::factory('admin/write-post.php')->bottom = array('BookInfo_Plugin', 'renderButton'); + Typecho_Plugin::factory('admin/write-page.php')->bottom = array('BookInfo_Plugin', 'renderButton'); + + $cacheDir = dirname(__FILE__) . '/cache/'; + if (!file_exists($cacheDir)) mkdir($cacheDir, 0755, true); + + return '插件激活成功!'; + } + + /** + * 禁用插件 + */ + public static function deactivate() + { + return '插件已禁用'; + } + + /** + * 配置面板 + */ + public static function config(Typecho_Widget_Helper_Form $form) + { + $cacheEnable = new Typecho_Widget_Helper_Form_Element_Radio('cacheEnable', + array('1' => '启用', '0' => '禁用'), + '1', '启用缓存', '缓存图书信息,提升访问速度'); + $form->addInput($cacheEnable); + + $cacheTime = new Typecho_Widget_Helper_Form_Element_Text('cacheTime', NULL, '30', + '缓存时间(天)', '图书信息缓存保留天数'); + $cacheTime->addRule('isInteger', '请输入整数'); + $form->addInput($cacheTime); + + $imageProxy = new Typecho_Widget_Helper_Form_Element_Text('imageProxy', NULL, + 'https://images.weserv.nl/?url=', '图片代理', '用于加载豆瓣图片'); + $form->addInput($imageProxy); + + $defaultCover = new Typecho_Widget_Helper_Form_Element_Text('defaultCover', NULL, + 'https://img9.doubanio.com/f/shire/5522dd1f5b742d1e1394a17f44d590646b63871d/pics/book-default-lpic.gif', + '默认封面', '当无法获取封面时显示的图片'); + $form->addInput($defaultCover); + + $summaryLength = new Typecho_Widget_Helper_Form_Element_Text('summaryLength', NULL, '200', + '简介显示长度', '简介默认显示的最大字符数,超出部分可展开查看'); + $summaryLength->addRule('isInteger', '请输入整数'); + $form->addInput($summaryLength); + + $expandText = new Typecho_Widget_Helper_Form_Element_Text('expandText', NULL, '展开', + '"展开"文字', '点击展开完整简介的文字'); + $form->addInput($expandText); + + $collapseText = new Typecho_Widget_Helper_Form_Element_Text('collapseText', NULL, '收起', + '"收起"文字', '点击收起简介的文字'); + $form->addInput($collapseText); + + $expandColor = new Typecho_Widget_Helper_Form_Element_Text('expandColor', NULL, '#0073aa', + '展开按钮颜色', '展开/收起按钮的文字颜色'); + $form->addInput($expandColor); + + // 新增:独立页面每页显示条数设置 + $pageSize = new Typecho_Widget_Helper_Form_Element_Text('pageSize', NULL, '10', + '独立页面每页显示条数', '在独立页面中每页显示的图书数量(1-50)'); + $pageSize->addRule('isInteger', '请输入整数'); + $pageSize->addRule(array(new BookInfo_Plugin, 'validatePageSize'), '请输入1-50之间的整数'); + $form->addInput($pageSize); + } + + /** + * 验证页面显示条数 + */ + public static function validatePageSize($value) + { + $value = intval($value); + if ($value < 1 || $value > 50) { + throw new Typecho_Widget_Exception('请输入1-50之间的整数'); + } + return true; + } + + /** + * 个人配置面板 + */ + public static function personalConfig(Typecho_Widget_Helper_Form $form) + { + } + + /** + * 解析短代码 + */ + public static function parse($content, $widget, $lastResult) + { + $content = empty($lastResult) ? $content : $lastResult; + + // 如果是独立页面,且内容中包含[all_books]标记,则显示所有图书 + if ($widget instanceof Widget_Archive && $widget->is('page')) { + // 支持[all_books]和[all_books:page=1]格式 + $pattern = '/\[all_books(?::page=(\d+))?\]/i'; + if (preg_match_all($pattern, $content, $matches)) { + foreach ($matches[0] as $key => $match) { + $page = isset($matches[1][$key]) ? intval($matches[1][$key]) : 1; + $allBooksHtml = self::renderAllBooks($page); + $content = str_replace($match, $allBooksHtml, $content); + } + } + } + + // 如果是单篇文章,解析图书短代码 + if ($widget instanceof Widget_Archive && $widget->is('single')) { + // 匹配 [book:数字] 或 [book:数字:短评] 格式 + $pattern = '/\[book:(\d+)(?::([^\]]+))?\]/i'; + if (preg_match_all($pattern, $content, $matches)) { + foreach ($matches[0] as $key => $match) { + $bookId = $matches[1][$key]; + $reviewWithCustom = isset($matches[2][$key]) ? trim($matches[2][$key]) : ''; + + $review = ''; + $customData = array(); + + // 解码短评和自定义数据 + if (!empty($reviewWithCustom)) { + // 分离短评和自定义数据 + if (strpos($reviewWithCustom, '|CUSTOM:') !== false) { + list($review, $customJson) = explode('|CUSTOM:', $reviewWithCustom, 2); + + // 解码自定义数据 + if (!empty($customJson)) { + // URL解码 + $decodedJson = urldecode($customJson); + // 解析JSON + $customData = json_decode($decodedJson, true); + if (!is_array($customData)) { + $customData = array(); + } + } + } else { + // 检查是否是纯自定义数据(没有短评) + if (preg_match('/^\(自定义:(.*)\)$/', $reviewWithCustom, $customMatch)) { + // 这是旧格式的自定义数据,需要转换 + $review = ''; + $customData = self::parseLegacyCustomData($customMatch[1]); + } else { + // 重要修复:处理中文自定义数据(如:短评(自定义:开始阅读:2025.12.03)) + // 检查是否包含中文括号格式的自定义数据 + if (preg_match('/^(.*?)(自定义:(.*))$/u', $reviewWithCustom, $customMatch)) { + // 第一部分是短评 + $review = trim($customMatch[1]); + // 第二部分是自定义数据 + $customData = self::parseLegacyCustomData($customMatch[2]); + } else { + // 没有自定义数据,只有短评 + $review = $reviewWithCustom; + } + } + } + + // 解码短评(处理特殊字符)- 修复:只解码真正的短评部分 + if (!empty($review)) { + // 处理HTML实体转义 + $review = str_replace(array('[', ']'), array('[', ']'), $review); + } + } + + // 获取图书数据(包含短评和自定义数据) + $bookHtml = self::renderBook($bookId, $review, $customData); + $content = str_replace($match, $bookHtml, $content); + } + } + } + + return $content; + } + + /** + * 解析旧格式的自定义数据 + */ + private static function parseLegacyCustomData($customText) + { + $customData = array(); + + // 解析旧格式:开始阅读:2025.12.03,结束阅读:2025.12.07,阅读方法:速读,图书分类:小说,推荐指数:★★ + $pairs = explode(',', $customText); + foreach ($pairs as $pair) { + if (strpos($pair, ':') !== false) { + list($key, $value) = explode(':', $pair, 2); + switch (trim($key)) { + case '开始阅读': + $customData['startDate'] = trim($value); + break; + case '结束阅读': + $customData['readDate'] = trim($value); + break; + case '阅读方法': + $customData['readMethod'] = trim($value); + break; + case '图书分类': + $customData['bookCategory'] = trim($value); + break; + case '推荐指数': + // 计算星星数量 + $starCount = substr_count($value, '★'); + $customData['recommendation'] = $starCount; + break; + } + } + } + + return $customData; + } + + /** + * 渲染单本图书信息 + */ + private static function renderBook($bookId, $review = '', $customData = array()) + { + // 获取图书数据(包含短评和自定义数据) + $bookData = self::getBookData($bookId, $review, $customData); + + if (!$bookData || empty($bookData['title'])) { + return '
+ 获取图书信息失败,ID:' . htmlspecialchars($bookId) . ' +
'; + } + + $options = Typecho_Widget::widget('Widget_Options')->plugin('BookInfo'); + $imageProxy = isset($options->imageProxy) ? $options->imageProxy : 'https://images.weserv.nl/?url='; + $defaultCover = isset($options->defaultCover) ? $options->defaultCover : + 'https://img9.doubanio.com/f/shire/5522dd1f5b742d1e1394a17f44d590646b63871d/pics/book-default-lpic.gif'; + $summaryLength = isset($options->summaryLength) ? intval($options->summaryLength) : 200; + $expandText = isset($options->expandText) ? $options->expandText : '展开'; + $collapseText = isset($options->collapseText) ? $options->collapseText : '收起'; + $expandColor = isset($options->expandColor) ? $options->expandColor : '#0073aa'; + + $title = htmlspecialchars($bookData['title']); + $author = is_array($bookData['author']) ? implode(', ', $bookData['author']) : htmlspecialchars($bookData['author']); + $summary = isset($bookData['summary']) ? $bookData['summary'] : ''; + + // 重要修复:直接从传入的$review获取短评,确保与编辑器输入一致 + $review = htmlspecialchars($review); + + // 豆瓣抓取字段 + $publisher = isset($bookData['publisher']) ? htmlspecialchars($bookData['publisher']) : '未知'; + $pubdate = isset($bookData['pubdate']) ? htmlspecialchars($bookData['pubdate']) : '未知'; + $pages = isset($bookData['pages']) ? htmlspecialchars($bookData['pages']) : '未知'; + $rating = isset($bookData['rating']) ? floatval($bookData['rating']) : 0; + $ratingCount = isset($bookData['rating_count']) ? intval($bookData['rating_count']) : 0; + + // 自定义字段 - 修复:确保正确处理customData + $startDate = isset($customData['startDate']) ? htmlspecialchars($customData['startDate']) : ''; + $readDate = isset($customData['readDate']) ? htmlspecialchars($customData['readDate']) : ''; + $readMethod = isset($customData['readMethod']) ? htmlspecialchars($customData['readMethod']) : ''; + $bookCategory = isset($customData['bookCategory']) ? htmlspecialchars($customData['bookCategory']) : ''; + $recommendation = isset($customData['recommendation']) ? intval($customData['recommendation']) : 0; + + // 如果customData中没有,尝试从bookData中获取 + if (empty($startDate) && isset($bookData['custom_start_date']) && !empty($bookData['custom_start_date'])) { + $startDate = htmlspecialchars($bookData['custom_start_date']); + } + if (empty($readDate) && isset($bookData['custom_read_date']) && !empty($bookData['custom_read_date'])) { + $readDate = htmlspecialchars($bookData['custom_read_date']); + } + if (empty($readMethod) && isset($bookData['custom_read_method']) && !empty($bookData['custom_read_method'])) { + $readMethod = htmlspecialchars($bookData['custom_read_method']); + } + if (empty($bookCategory) && isset($bookData['custom_book_category']) && !empty($bookData['custom_book_category'])) { + $bookCategory = htmlspecialchars($bookData['custom_book_category']); + } + if ($recommendation == 0 && isset($bookData['custom_recommendation'])) { + $recommendation = intval($bookData['custom_recommendation']); + } + + // 检查简介是否超过当前设置的限制长度 + $isSummaryLong = false; + $summaryShort = $summary; + + // 移除HTML标签来计算纯文本长度 + $plainSummary = strip_tags($summary); + if (mb_strlen($plainSummary, 'UTF-8') > $summaryLength) { + $isSummaryLong = true; + // 截取纯文本 + $plainShort = mb_substr($plainSummary, 0, $summaryLength, 'UTF-8'); + // 尝试保持HTML结构,但这是一个简化的处理 + $summaryShort = $plainShort . '...'; + } + + $coverUrl = !empty($bookData['image']) ? $bookData['image'] : $defaultCover; + $coverSrc = $imageProxy . urlencode($coverUrl); + + // 生成评分显示 + $ratingHtml = ''; + if ($rating > 0) { + $ratingHtml = '
+ 豆瓣评分: + ' . number_format($rating, 1) . ''; + + if ($ratingCount > 0) { + $ratingHtml .= ' (' . number_format($ratingCount) . '人评价)'; + } + $ratingHtml .= '
'; + } + + // 生成推荐指数星星 + $recommendationHtml = ''; + if ($recommendation > 0) { + $recommendationHtml = '
+ 推荐指数:'; + + for ($i = 1; $i <= 5; $i++) { + if ($i <= $recommendation) { + $recommendationHtml .= ''; + } else { + $recommendationHtml .= ''; + } + } + $recommendationHtml .= '
'; + } + + // 生成自定义信息HTML + $customInfoHtml = ''; + $hasCustomInfo = false; + + // 生成右侧栏的自定义信息(无标题,样式与中间栏一致) + if ($startDate || $readDate || $readMethod || $bookCategory) { + $hasCustomInfo = true; + + if ($startDate) { + $customInfoHtml .= '
+ 开始阅读: + ' . $startDate . ' +
'; + } + + if ($readDate) { + $customInfoHtml .= '
+ 结束阅读: + ' . $readDate . ' +
'; + } + + if ($readMethod) { + $customInfoHtml .= '
+ 阅读方法: + ' . $readMethod . ' +
'; + } + + if ($bookCategory) { + $customInfoHtml .= '
+ 图书分类: + ' . $bookCategory . ' +
'; + } + } + + // 生成右侧栏的完整HTML + $rightColumnHtml = ''; + + if ($recommendationHtml) { + $rightColumnHtml .= $recommendationHtml; + } + + if ($customInfoHtml) { + $rightColumnHtml .= $customInfoHtml; + } else { + // 如果没有自定义信息,显示占位符 + $rightColumnHtml .= '
+ 阅读记录: + 暂无记录 +
'; + } + + // 生成简介部分HTML,包含展开/收起功能 + $summaryHtml = '
'; + + if ($isSummaryLong) { + // 长简介:显示短版本 + 展开按钮 + $summaryHtml .= ' +
+
+ ' . nl2br($summaryShort) . ' + ' + . htmlspecialchars($expandText) . ' ↓ + +
+
+ '; + } else { + // 短简介:直接显示完整内容 + $summaryHtml .= ' +
+ ' . $summary . ' +
'; + } + + $summaryHtml .= '
'; + + // 生成短评HTML(如果有短评)- 只显示纯粹的短评 + $reviewHtml = ''; + if (!empty($review)) { + $reviewHtml = '
+
💭 我的短评
+
+ ' . nl2br($review) . ' +
+
'; + } + + $html = << + + +
+
+ + + + +
+
+ +
+ +
+
+ {$title} +
+
📚
+
+
+
+ + +
+
+ 作者: + {$author} +
+
+ 出版社: + {$publisher} +
+
+ 出版年: + {$pubdate} +
+
+ 页数: + {$pages} +
+ {$ratingHtml} +
+ + +
+ {$rightColumnHtml} +
+
+
+ + +
+ +
+
+ 📖 + 内容简介 +
+
+ {$summaryHtml} +
+
+ + + {$reviewHtml} +
+
+
+HTML; + + // 添加JavaScript切换函数 + $html .= ' + '; + + return $html; + } + + /** + * 获取所有图书数据(支持分页) + */ + private static function getAllBooksData($page = 1, $pageSize = 10) + { + $cacheDir = dirname(__FILE__) . '/cache/'; + $allBooks = array(); + + // 扫描缓存目录 + if (file_exists($cacheDir)) { + $files = scandir($cacheDir); + foreach ($files as $file) { + if (pathinfo($file, PATHINFO_EXTENSION) === 'json') { + $filePath = $cacheDir . $file; + $content = file_get_contents($filePath); + if ($content) { + $data = json_decode($content, true); + if ($data && isset($data['fetched_at'])) { + // 添加文件名作为bookId + $bookId = pathinfo($file, PATHINFO_FILENAME); + $data['bookId'] = $bookId; + + // 使用文件修改时间作为添加时间(如果文件不存在,使用fetched_at) + if (file_exists($filePath)) { + $data['added_time'] = filemtime($filePath); + } else { + $data['added_time'] = isset($data['fetched_at']) ? $data['fetched_at'] : time(); + } + + $allBooks[] = $data; + } + } + } + } + } + + // 按added_time倒序排序(最新的在最前面) + usort($allBooks, function($a, $b) { + return $b['added_time'] - $a['added_time']; + }); + + $total = count($allBooks); + $totalPages = ceil($total / $pageSize); + + // 限制页码范围 + $page = max(1, min($page, $totalPages)); + + // 分页处理 + $startIndex = ($page - 1) * $pageSize; + $paginatedBooks = array_slice($allBooks, $startIndex, $pageSize); + + return array( + 'books' => $paginatedBooks, + 'total' => $total, + 'page' => $page, + 'pageSize' => $pageSize, + 'totalPages' => $totalPages, + 'startIndex' => $startIndex + 1, + 'endIndex' => min($startIndex + $pageSize, $total) + ); + } + + /** + * 生成分页HTML + */ + private static function generatePagination($currentPage, $totalPages, $baseUrl = '') + { + if ($totalPages <= 1) { + return ''; + } + + $html = '
'; + $html .= '
'; + + // 首页 + if ($currentPage > 1) { + $html .= '«'; + } else { + $html .= '«'; + } + + // 上一页 + if ($currentPage > 1) { + $html .= ''; + } else { + $html .= ''; + } + + // 页码显示 + $startPage = max(1, $currentPage - 2); + $endPage = min($totalPages, $currentPage + 2); + + for ($i = $startPage; $i <= $endPage; $i++) { + if ($i == $currentPage) { + $html .= '' . $i . ''; + } else { + $html .= '' . $i . ''; + } + } + + // 下一页 + if ($currentPage < $totalPages) { + $html .= ''; + } else { + $html .= ''; + } + + // 末页 + if ($currentPage < $totalPages) { + $html .= '»'; + } else { + $html .= '»'; + } + + $html .= '
'; + // 删除了"共几页"的显示 + $html .= '
'; + + return $html; + } + + /** + * 获取页面URL + */ + private static function getPageUrl($page, $baseUrl = '') + { + if (empty($baseUrl)) { + // 获取当前页面URL + $currentUrl = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : ''; + + // 移除现有的page参数 + $currentUrl = preg_replace('/[&?]page=\d+/', '', $currentUrl); + $currentUrl = rtrim($currentUrl, '?&'); + + // 添加分页参数 + $separator = strpos($currentUrl, '?') === false ? '?' : '&'; + return $currentUrl . $separator . 'page=' . $page; + } + + return $baseUrl . (strpos($baseUrl, '?') === false ? '?' : '&') . 'page=' . $page; + } + + /** + * 渲染所有图书列表(支持深色模式和封面显示) + */ + public static function renderAllBooks($page = 1) + { + // 从GET参数获取页码(优先级高于参数) + if (isset($_GET['page']) && is_numeric($_GET['page'])) { + $page = intval($_GET['page']); + } + + $options = Typecho_Widget::widget('Widget_Options')->plugin('BookInfo'); + $pageSize = isset($options->pageSize) ? intval($options->pageSize) : 10; + $imageProxy = isset($options->imageProxy) ? $options->imageProxy : 'https://images.weserv.nl/?url='; + $defaultCover = isset($options->defaultCover) ? $options->defaultCover : + 'https://img9.doubanio.com/f/shire/5522dd1f5b742d1e1394a17f44d590646b63871d/pics/book-default-lpic.gif'; + + // 获取分页数据 + $paginationData = self::getAllBooksData($page, $pageSize); + $allBooks = $paginationData['books']; + $total = $paginationData['total']; + $currentPage = $paginationData['page']; + $totalPages = $paginationData['totalPages']; + $startIndex = $paginationData['startIndex']; + $endIndex = $paginationData['endIndex']; + + if (empty($allBooks)) { + return '
+

暂无图书数据

+

请先在文章中使用[book:ID]短代码添加图书

+
'; + } + + $html = '
'; + + // 标题模块 + $html .= '
'; + $html .= '

我的全部已读图书

'; + $html .= '

已读' . $total . '本图书,本数据2025.12.08开始统计

'; + $html .= '
'; + + // 页码信息 + $html .= '
'; + $html .= '
'; + $html .= '
'; + $html .= '显示:'; + $html .= '' . $startIndex . '-' . $endIndex . ' / '; + $html .= '' . $total . ''; + $html .= '
'; + $html .= '
'; + $html .= '当前:'; + $html .= '第 ' . $currentPage . ' 页 / '; + $html .= '共 ' . $totalPages . ' 页'; + $html .= '
'; + $html .= '
'; + $html .= '
'; + + // 计算倒序序号(最大的序号在最前面) + $totalCount = $total; + $currentIndex = $totalCount - (($currentPage - 1) * $pageSize); + + foreach ($allBooks as $book) { + $bookId = $book['bookId']; + $title = isset($book['title']) ? htmlspecialchars($book['title']) : '未知图书'; + + // 封面图片 + $coverUrl = !empty($book['image']) ? $book['image'] : $defaultCover; + $coverSrc = $imageProxy . urlencode($coverUrl); + + // 自定义字段 + $startDate = isset($book['custom_start_date']) ? htmlspecialchars($book['custom_start_date']) : ''; + $readDate = isset($book['custom_read_date']) ? htmlspecialchars($book['custom_read_date']) : ''; + $readMethod = isset($book['custom_read_method']) ? htmlspecialchars($book['custom_read_method']) : ''; + $bookCategory = isset($book['custom_book_category']) ? htmlspecialchars($book['custom_book_category']) : ''; + + // 作者处理 + $author = '未知作者'; + if (isset($book['author'])) { + if (is_array($book['author'])) { + $author = implode(', ', $book['author']); + } else { + $author = $book['author']; + } + } + $author = htmlspecialchars($author); + + // 豆瓣信息 + $publisher = isset($book['publisher']) ? htmlspecialchars($book['publisher']) : '未知'; + $pubdate = isset($book['pubdate']) ? htmlspecialchars($book['pubdate']) : '未知'; + $pages = isset($book['pages']) ? htmlspecialchars($book['pages']) : '未知'; + + // 豆瓣评分 + $rating = isset($book['rating']) ? floatval($book['rating']) : 0; + $ratingDisplay = $rating > 0 ? number_format($rating, 1) . '分' : '暂无评分'; + + // 短评 + $review = isset($book['review']) ? htmlspecialchars($book['review']) : ''; + + // 构建日期范围显示 + $dateRange = ''; + if ($startDate && $readDate) { + $dateRange = $startDate . '-' . $readDate; + } elseif ($startDate) { + $dateRange = $startDate . '-至今'; + } elseif ($readDate) { + $dateRange = '未知-' . $readDate; + } + + // 构建图书分类显示 + $categoryDisplay = $bookCategory ? $bookCategory : '未分类'; + + // 构建阅读方法显示 + $methodDisplay = $readMethod ? $readMethod : '未知'; + + // 获取序号颜色 + $indexColor = self::getIndexColor($currentIndex); + + $html .= '
'; + + $html .= '
'; + + // 左侧:封面图片带序号 + $html .= '
'; + $html .= '
'; + $html .= ''; + $html .= '
'; + $html .= '' . $title . ''; + $html .= '
'; + + // 序号显示在封面右上角 + $html .= '
' . $currentIndex . '
'; + + $html .= '
'; + $html .= '
'; + $html .= '
'; + + // 右侧:图书信息 + $html .= '
'; + + // 第一行:书名(带豆瓣链接)/分类/日期范围/阅读方法 + $html .= '
'; + $html .= '《' . $title . '》'; + + if ($categoryDisplay || $dateRange || $methodDisplay) { + $html .= '/'; + $html .= '' . $categoryDisplay . ''; + + if ($dateRange) { + $html .= '/'; + $html .= '' . $dateRange . ''; + } + + if ($methodDisplay) { + $html .= '/'; + $html .= '' . $methodDisplay . ''; + } + } + + $html .= '
'; + + // 第二行:作者/出版社/出版年/页数/豆瓣评分 + $html .= '
'; + $html .= '作者:' . $author . ''; + $html .= '|'; + $html .= '出版社:' . $publisher . ''; + $html .= '|'; + $html .= '出版年:' . $pubdate . ''; + $html .= '|'; + $html .= '页数:' . $pages . '页'; + $html .= '|'; + // 豆瓣评分显示,如果是0分则显示"暂无评分",否则显示具体分数 + if ($rating > 0) { + $html .= '豆瓣评分:' . $ratingDisplay . ''; + } else { + $html .= '豆瓣评分:' . $ratingDisplay . ''; + } + $html .= '
'; + + // 第三行:短评 + if ($review) { + $html .= '
'; + $html .= '
📝 短评:
'; + $html .= '
'; + $html .= nl2br($review); + $html .= '
'; + $html .= '
'; + } + + $html .= '
'; + $html .= '
'; + + $html .= '
'; + + $currentIndex--; + } + + // 分页导航 + if ($totalPages > 1) { + $html .= self::generatePagination($currentPage, $totalPages); + } + + $html .= '
'; + + return $html; + } + + /** + * 获取序号颜色 + */ + private static function getIndexColor($index) + { + $colors = [ + 'linear-gradient(135deg, #0073aa, #0056b3)', // 蓝色 + 'linear-gradient(135deg, #28a745, #218838)', // 绿色 + 'linear-gradient(135deg, #e67e22, #d35400)', // 橙色 + 'linear-gradient(135deg, #9b59b6, #8e44ad)', // 紫色 + 'linear-gradient(135deg, #e74c3c, #c0392b)', // 红色 + ]; + + return $colors[($index - 1) % count($colors)]; + } + + /** + * 获取图书数据(包含短评和自定义信息) + */ + private static function getBookData($bookId, $review = '', $customData = array()) + { + if (!is_numeric($bookId)) return null; + + $cacheFile = dirname(__FILE__) . '/cache/' . $bookId . '.json'; + $options = Typecho_Widget::widget('Widget_Options')->plugin('BookInfo'); + $cacheEnable = isset($options->cacheEnable) ? $options->cacheEnable : '1'; + $cacheTime = isset($options->cacheTime) ? intval($options->cacheTime) : 7; + + $data = null; + $needUpdate = false; + + // 检查缓存 + if ($cacheEnable == '1' && file_exists($cacheFile)) { + $fileTime = filemtime($cacheFile); + $expireTime = $cacheTime * 24 * 3600; + if (time() - $fileTime < $expireTime) { + $cacheContent = file_get_contents($cacheFile); + if ($cacheContent) { + $data = json_decode($cacheContent, true); + } + } + } + + // 如果缓存不存在或已过期,从豆瓣获取基本信息 + if (!$data || empty($data['title'])) { + $data = self::fetchFromDouban($bookId); + $needUpdate = true; + } + + // 重要修复:只在$review不为空且与当前数据不同时更新 + if (!empty($review) && (!isset($data['review']) || $data['review'] !== $review)) { + $data['review'] = $review; + $data['review_updated'] = time(); + $needUpdate = true; + } + + // 更新自定义数据 - 使用传入的customData更新 + if (!empty($customData)) { + if (isset($customData['startDate']) && (!isset($data['custom_start_date']) || $data['custom_start_date'] !== $customData['startDate'])) { + $data['custom_start_date'] = $customData['startDate']; + $needUpdate = true; + } + if (isset($customData['readDate']) && (!isset($data['custom_read_date']) || $data['custom_read_date'] !== $customData['readDate'])) { + $data['custom_read_date'] = $customData['readDate']; + $needUpdate = true; + } + if (isset($customData['readMethod']) && (!isset($data['custom_read_method']) || $data['custom_read_method'] !== $customData['readMethod'])) { + $data['custom_read_method'] = $customData['readMethod']; + $needUpdate = true; + } + if (isset($customData['bookCategory']) && (!isset($data['custom_book_category']) || $data['custom_book_category'] !== $customData['bookCategory'])) { + $data['custom_book_category'] = $customData['bookCategory']; + $needUpdate = true; + } + if (isset($customData['recommendation']) && (!isset($data['custom_recommendation']) || $data['custom_recommendation'] != $customData['recommendation'])) { + $data['custom_recommendation'] = intval($customData['recommendation']); + $needUpdate = true; + } + } + + // 确保自定义字段存在 + $customFields = array( + 'custom_start_date' => '', + 'custom_read_date' => '', + 'custom_read_method' => '', + 'custom_book_category' => '', + 'custom_recommendation' => 0 + ); + + foreach ($customFields as $field => $default) { + if (!isset($data[$field])) { + $data[$field] = $default; + } + } + + // 如果需要更新缓存,保存到文件 + if ($needUpdate && $data && !empty($data['title'])) { + file_put_contents($cacheFile, json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)); + } + + return $data; + } + + /** + * 从豆瓣获取数据 - 修复:保留HTML标签的摘要抓取 + */ + private static function fetchFromDouban($bookId) + { + $url = "https://book.douban.com/subject/{$bookId}/"; + $ch = curl_init(); + curl_setopt_array($ch, array( + CURLOPT_URL => $url, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_FOLLOWLOCATION => true, + CURLOPT_TIMEOUT => 20, + CURLOPT_SSL_VERIFYPEER => false, + CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', + CURLOPT_ENCODING => 'gzip, deflate', + CURLOPT_REFERER => 'https://book.douban.com/', + CURLOPT_HTTPHEADER => array( + 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', + 'Accept-Language: zh-CN,zh;q=0.9,en;q=0.8', + 'Cache-Control: no-cache', + 'Connection: keep-alive' + ) + )); + + $html = curl_exec($ch); + if (curl_errno($ch)) { + curl_close($ch); + return null; + } + curl_close($ch); + + if (empty($html)) return null; + + $data = array(); + + // 1. 提取标题 + if (preg_match('/]*>\s*]*>([^<]+)<\/span>/', $html, $matches)) { + $data['title'] = trim(strip_tags(html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8'))); + } + + // 2. 提取封面 + if (preg_match('/]*src="([^"]+)"[^>]*id="mainpic"/', $html, $matches)) { + $data['image'] = trim($matches[1]); + } + + // 3. 提取描述(内容简介)- 修复:保留HTML标签 + $summary = ''; + + // 豆瓣页面可能有多个intro,第一个通常是内容简介 + if (preg_match_all('/]*>([\s\S]*?)<\/div>/', $html, $matches)) { + // 尝试获取第一个intro(通常是内容简介) + if (isset($matches[1][0])) { + $intro = $matches[1][0]; + + // 检查是否有展开全部链接 + if (preg_match('/]*class="[^"]*a_show_full[^"]*"[^>]*>.*?<\/a>/', $intro)) { + // 如果有展开全部链接,说明这个intro是被截断的 + // 我们需要查找完整的intro(可能在后面的div中) + foreach ($matches[1] as $introIndex => $introContent) { + // 查找不包含"a_show_full"的完整intro + if (!preg_match('/]*class="[^"]*a_show_full[^"]*"[^>]*>.*?<\/a>/', $introContent)) { + $intro = $introContent; + break; + } + } + } + + // 移除展开链接,但保留其他HTML标签(特别是

标签) + $intro = preg_replace('/]*>.*?<\/a>/', '', $intro); + + // 清理多余的空白字符但保留HTML标签 + $intro = preg_replace('/\s+/', ' ', $intro); + $intro = trim($intro); + + // 解码HTML实体,但保留HTML标签 + $intro = html_entity_decode($intro, ENT_QUOTES, 'UTF-8'); + + // 确保

标签正确闭合 + $intro = preg_replace('/

\s*<\/p>/', '', $intro); + $intro = preg_replace('/

\s+/', '

', $intro); + $intro = preg_replace('/\s+<\/p>/', '

', $intro); + + $summary = $intro; + + // 如果获取到的内容很短,可能是作者简介,尝试第二个intro + $plainText = strip_tags($intro); + if (mb_strlen($plainText, 'UTF-8') < 50 && isset($matches[1][1])) { + $intro = $matches[1][1]; + $intro = preg_replace('/]*>.*?<\/a>/', '', $intro); + $intro = preg_replace('/\s+/', ' ', $intro); + $intro = trim($intro); + $intro = html_entity_decode($intro, ENT_QUOTES, 'UTF-8'); + $summary = $intro; + } + } + } + + // 如果intro中没有,尝试从meta获取(但meta通常没有HTML标签) + if (empty($summary) && preg_match('/暂无简介

'; + + // 4. 提取作者信息 + $authors = array(); + if (preg_match('/]*class="author"[^>]*>([^<]+)<\/a>/', $html, $matches)) { + foreach ($matches[1] as $author) { + $cleanAuthor = trim(html_entity_decode(strip_tags($author), ENT_QUOTES, 'UTF-8')); + if ($cleanAuthor && !in_array($cleanAuthor, $authors)) { + $authors[] = $cleanAuthor; + } + } + } + $data['author'] = !empty($authors) ? $authors : array('未知作者'); + + // 5. 提取图书详细信息(出版社、出版年、页数等) + $infoHtml = ''; + if (preg_match('/]*id="info"[^>]*>([\s\S]*?)<\/div>/', $html, $matches)) { + $infoHtml = $matches[1]; + + // 处理换行和span标签 + $infoHtml = preg_replace('//', "\n", $infoHtml); + $infoHtml = preg_replace('/<\/span>/', "\n", $infoHtml); + $infoHtml = strip_tags($infoHtml); + + // 按行处理 + $lines = explode("\n", $infoHtml); + foreach ($lines as $line) { + $line = trim($line); + if (empty($line)) continue; + + // 使用更灵活的正则匹配各种格式 + if (preg_match('/^出版社[::]\s*(.+)$/u', $line, $match)) { + $data['publisher'] = trim($match[1]); + } + elseif (preg_match('/^出版年[::]\s*(.+)$/u', $line, $match)) { + $data['pubdate'] = trim($match[1]); + } + elseif (preg_match('/^页数[::]\s*(.+)$/u', $line, $match)) { + $data['pages'] = trim($match[1]); + } + elseif (preg_match('/^ISBN[::]\s*(.+)$/u', $line, $match)) { + $data['isbn'] = trim($match[1]); + } + elseif (preg_match('/^定价[::]\s*(.+)$/u', $line, $match)) { + $data['price'] = trim($match[1]); + } + // 处理其他可能的格式 + elseif (preg_match('/出版社[::]\s*(.+)/u', $line, $match)) { + $data['publisher'] = trim($match[1]); + } + elseif (preg_match('/出版年[::]\s*(.+)/u', $line, $match)) { + $data['pubdate'] = trim($match[1]); + } + } + } + + // 如果上面没提取到,尝试直接在整个HTML中搜索 + if (!isset($data['publisher'])) { + $publisherPatterns = array( + '/出版社[::]\s*<\/span>\s*]*>([^<]+)<\/a>/', + '/出版社[::]\s*<\/span>\s*]*>([^<]+)<\/span>/', + '/出版社[::]\s*([^<]+)/', + '/]*>出版社[::]<\/span>\s*([^<]+)/', + '/出版社[::]\s*([^\n<]+)/' + ); + + foreach ($publisherPatterns as $pattern) { + if (preg_match($pattern, $html, $matches)) { + $data['publisher'] = trim(strip_tags($matches[1])); + break; + } + } + } + + if (!isset($data['pubdate'])) { + $pubdatePatterns = array( + '/出版年[::]\s*<\/span>\s*]*>([^<]+)<\/span>/', + '/出版年[::]\s*([^<]+)/', + '/]*>出版年[::]<\/span>\s*([^<]+)/', + '/出版年[::]\s*([^\n<]+)/', + '/出版日期[::]\s*([^<]+)/' + ); + + foreach ($pubdatePatterns as $pattern) { + if (preg_match($pattern, $html, $matches)) { + $data['pubdate'] = trim(strip_tags($matches[1])); + break; + } + } + } + + if (!isset($data['pages'])) { + $pagesPatterns = array( + '/页数[::]\s*<\/span>\s*]*>([^<]+)<\/span>/', + '/页数[::]\s*([^<]+)/', + '/]*>页数[::]<\/span>\s*([^<]+)/', + '/页数[::]\s*([^\n<]+)/' + ); + + foreach ($pagesPatterns as $pattern) { + if (preg_match($pattern, $html, $matches)) { + $data['pages'] = trim(strip_tags($matches[1])); + break; + } + } + } + + // 设置默认值 + if (!isset($data['publisher'])) $data['publisher'] = '未知'; + if (!isset($data['pubdate'])) $data['pubdate'] = '未知'; + if (!isset($data['pages'])) $data['pages'] = '未知'; + if (!isset($data['isbn'])) $data['isbn'] = '未知'; + + // 6. 提取豆瓣评分 + $rating = 0; + $ratingCount = 0; + + // 从评分区域提取 + if (preg_match('/]*class="ll rating_num"[^>]*>([^<]+)<\/strong>/', $html, $matches)) { + $rating = floatval(trim($matches[1])); + } + elseif (preg_match('/]*class="[^"]*rating_num[^"]*"[^>]*>([^<]+)<\/strong>/', $html, $matches)) { + $rating = floatval(trim($matches[1])); + } + // 从property属性提取 + elseif (preg_match('/property="v:average"[^>]*>([^<]+)<\/strong>/', $html, $matches)) { + $rating = floatval(trim($matches[1])); + } + // 从评分数字提取 + elseif (preg_match('/]*>(\d+\.?\d*)<\/span>[^<]*]*>\((\d+)人评价\)/', $html, $matches)) { + $rating = floatval($matches[1]); + $ratingCount = intval($matches[2]); + } + + $data['rating'] = $rating; + + // 7. 提取评价人数 + if (preg_match('/]*property="v:votes"[^>]*>(\d+)<\/span>/', $html, $matches)) { + $data['rating_count'] = intval($matches[1]); + } elseif (preg_match('/\((\d+)人评价\)/', $html, $matches)) { + $data['rating_count'] = intval($matches[1]); + } else { + $data['rating_count'] = 0; + } + + // 如果评分人数为0但评分不为0,尝试其他方式 + if ($rating > 0 && $data['rating_count'] == 0) { + if (preg_match('/]*class="rating_people"[^>]*>(\d+)人评价<\/a>/', $html, $matches)) { + $data['rating_count'] = intval($matches[1]); + } + } + + // 8. 初始化review和自定义字段 + $data['review'] = ''; + $data['review_updated'] = 0; + + // 初始化自定义字段 + $data['custom_start_date'] = ''; + $data['custom_read_date'] = ''; + $data['custom_read_method'] = ''; + $data['custom_book_category'] = ''; + $data['custom_recommendation'] = 0; + + // 9. 添加抓取时间 + $data['fetched_at'] = time(); + + return $data; + } + + /** + * 渲染编辑器按钮 - 修复:恢复原来的编辑器预览和插入格式 + */ + public static function renderButton() + { + echo << + #bookinfo-button { + padding: 5px!important; + background:#fff; + cursor: pointer; + color: white; + border: none; + border-radius: 4px; + font-size: 16px; + line-height: 1; + display: inline-flex; + align-items: center; + justify-content: center; + min-width: 26px; + min-height: 26px; + } + #bookinfo-button:hover{background:#E9E9E6} + .dark #bookinfo-button{background:rgb(16, 25, 40);} + .dark #bookinfo-button:hover{background:#375d85;} + + /* 豆瓣插件深色模式适配 - 仅添加CSS */ + .dark #bookinfo-id, + .dark #bookinfo-review, + .dark #bookinfo-start-date, + .dark #bookinfo-read-date, + .dark #bookinfo-read-method, + .dark #bookinfo-book-category, + .dark #bookinfo-recommendation { + background: #101928 !important; + border: 1px solid #374151 !important; + color: #ffffff !important; + } + + .dark #bookinfo-id::placeholder, + .dark #bookinfo-review::placeholder, + .dark #bookinfo-start-date::placeholder, + .dark #bookinfo-read-date::placeholder, + .dark #bookinfo-read-method::placeholder, + .dark #bookinfo-book-category::placeholder { + color: #9ca3af !important; + } + + .dark #bookinfo-id:focus, + .dark #bookinfo-review:focus, + .dark #bookinfo-start-date:focus, + .dark #bookinfo-read-date:focus, + .dark #bookinfo-read-method:focus, + .dark #bookinfo-book-category:focus, + .dark #bookinfo-recommendation:focus { + border-color: #0073aa !important; + outline: none !important; + } + + .dark label[for="bookinfo-id"], + .dark label[for="bookinfo-review"], + .dark label[for="bookinfo-start-date"], + .dark label[for="bookinfo-read-date"], + .dark label[for="bookinfo-read-method"], + .dark label[for="bookinfo-book-category"], + .dark label[for="bookinfo-recommendation"], + .dark .bookinfo-modal-title { + color: #ffffff !important; + } + + .dark .bookinfo-modal-content { + background: #1f2937 !important; + border: 1px solid #374151 !important; + } + + .dark .bookinfo-modal-header { + background: #101928 !important; + border-bottom: 1px solid #374151 !important; + } + + .dark .bookinfo-modal-footer { + background: #101928 !important; + border-top: 1px solid #374151 !important; + } + + .dark .bookinfo-help-text { + color: #9ca3af !important; + } + + .dark .bookinfo-preview-box { + background: #101928 !important; + border: 1px solid #374151 !important; + } + + .dark .bookinfo-preview { + color: #d1d5db !important; + } + + .dark .bookinfo-option-group { + background: #1f2937 !important; + border: 1px solid #374151 !important; + } + + .dark .bookinfo-cancel-btn { + background: #374151 !important; + color: #d1d5db !important; + border: 1px solid #4b5563 !important; + } + + .dark .bookinfo-cancel-btn:hover { + background: #4b5563 !important; + } + + .dark .bookinfo-insert-btn { + background: #0073aa !important; + color: #ffffff !important; + border: 1px solid #0056b3 !important; + } + + .dark .bookinfo-insert-btn:hover { + background: #0056b3 !important; + } + + /* 弹窗样式适配 */ + .dark .bookinfo-modal-overlay { + background: rgba(0, 0, 0, 0.7) !important; + } + + /* 选择框选项 */ + .dark #bookinfo-recommendation option { + background: #1f2937 !important; + color: #ffffff !important; + } + + .dark #bookinfo-recommendation option:disabled { + color: #9ca3af !important; + } + + /* 信息提示框 */ + .dark .bookinfo-info-box { + background: #374151 !important; + border: 1px solid #4b5563 !important; + color: #d1d5db !important; + } + + .dark .bookinfo-info-box strong { + color: #ffffff !important; + } + + +HTML; + } +} \ No newline at end of file diff --git a/cache/22993089.json b/cache/22993089.json new file mode 100644 index 0000000..c59def7 --- /dev/null +++ b/cache/22993089.json @@ -0,0 +1,22 @@ +{ + "title": "预知梦", + "image": "https:\/\/img2.doubanio.com\/view\/subject\/l\/public\/s28391351.jpg", + "summary": "

《神探伽利略2:预知梦》深夜,陌生男子闯入16岁少女的房间中,发现有人闯入的母亲拿起猎枪开了枪。遭警方擒住的男子主张,17年前,他曾经做过一个与少女结合的梦。究其证据,便是男子念小学四年级时写下的一篇作文。这一切究竟是偶然,还是妄想?……天才物理学者——汤川出马了解这常识中不可能发生的案件。人气推理小说《神探伽利略》(第二季)!<\/p>

东野圭吾笔下最意气风发名侦探——“汤川学”系列第二作!<\/p>

《神探伽利略》(第二季)!《嫌疑人X的献身》之前传!<\/p>

首次东野圭吾授权未删节完整中译版!<\/p>

福山雅治领衔主演《神探伽利略》(第二季)登场!<\/p>

神探伽利略VS预知梦<\/p>", + "author": [ + "[日] 东野圭吾" + ], + "publisher": "化学工业出版社", + "pubdate": "2013-5-1", + "pages": "221", + "isbn": "未知", + "rating": 7.2, + "rating_count": 2393, + "review": "神秘与推理结合的杀人小说,全都比较怪异,吸引人,结局出人意料,比较推荐。", + "review_updated": 1771315138, + "custom_start_date": "2026.01.07", + "custom_read_date": "2026.01.14", + "custom_read_method": "精读", + "custom_book_category": "小说", + "custom_recommendation": 5, + "fetched_at": 1771315138 +} \ No newline at end of file diff --git a/cache/26911126.json b/cache/26911126.json new file mode 100644 index 0000000..8624ec0 --- /dev/null +++ b/cache/26911126.json @@ -0,0 +1,22 @@ +{ + "title": "那时的某人", + "image": "https:\/\/img9.doubanio.com\/view\/subject\/l\/public\/s29324836.jpg", + "summary": "

东野圭吾中短篇小说集,作者出道25年珍藏作品首次结集出版。八个故事涵盖了东野不同时期的创作风格,篇篇精巧,各具特色。女律师好心收留了一个雨夜迷路的失忆少女,却在少女的随身手帕里发现了一把带血的匕首;车祸中幸存的女儿,苏醒后居然附上了妻子的灵魂;一对夫妇幸运领养了一个刚出生的婴儿,婴儿天使般的面孔后却隐藏了一个悲凉的复仇计划……<\/p>

书中《REIKO和玲子》《再生魔术的女人》《二十年后的约定》被改编为剧集收入日本富士电视台推理悬疑剧《东野圭吾•悬疑故事》。<\/p>", + "author": [ + "[日] 东野圭吾" + ], + "publisher": "译林出版社", + "pubdate": "2017-3", + "pages": "211", + "isbn": "未知", + "rating": 6.4, + "rating_count": 3560, + "review": "八篇短篇小说,涉及多个社会热点主题,有后记记录每个故事的创作灵感。", + "review_updated": 1771513875, + "custom_start_date": "2025.12.14", + "custom_read_date": "2025.12.16", + "custom_read_method": "精读", + "custom_book_category": "小说", + "custom_recommendation": 3, + "fetched_at": 1771513875 +} \ No newline at end of file diff --git a/cache/26935572.json b/cache/26935572.json new file mode 100644 index 0000000..875121e --- /dev/null +++ b/cache/26935572.json @@ -0,0 +1,22 @@ +{ + "title": "浪花少年侦探团", + "image": "https:\/\/img1.doubanio.com\/view\/subject\/l\/public\/s29234529.jpg", + "summary": "

◇你今天的心情不好吗?<\/p>

读完东野圭吾的这本书,一定会好起来!<\/p>

◇这样元气满满的可爱女生,<\/p>

在东野圭吾的其他小说中从未见过<\/p>

◇原以为是以孩子为中心的故事而不想读,但试着读下来,发现故事节奏很棒,很有趣,读完后心情明快了起来。——日本亚马逊读者<\/p>

------------------------------------------------------------------------------<\/p>

平安夜,一个女人死在自家浴室,墙上留有“蛋糕”字样。警方判定自杀可能性很小,但现场既没有别人出入的痕迹,也没发现凶器。侦查陷入困境。<\/p>

女老师竹内忍没想到自己竟会和这个案子有关。她打算带着学生一起过圣诞节,买来了蛋糕,却在里面发现了一把刀,上面的血迹和遇害女人的血型一致。凶器究竟来自哪里?忍老师偶然看到遇害女人的一张照片,不禁眼前一亮:照片上四个人看似正常,表情却大有玄机,解谜的关键就在这里。<\/p>", + "author": [ + "[日] 东野圭吾" + ], + "publisher": "南海出版公司", + "pubdate": "2017-3", + "pages": "224", + "isbn": "未知", + "rating": 6.9, + "rating_count": 6774, + "review": "一位小学老师,带着几个调皮的孩子总是能阴差阳错的卷入杀人案,又出奇的为推理提供新的线索,甚至完成推理,很有意思的人物设置,剧情也很反转。", + "review_updated": 1770035217, + "custom_start_date": "", + "custom_read_date": "2026.01.19", + "custom_read_method": "精读", + "custom_book_category": "小说", + "custom_recommendation": 5, + "fetched_at": 1770035217 +} \ No newline at end of file diff --git a/cache/26958385.json b/cache/26958385.json new file mode 100644 index 0000000..a8176af --- /dev/null +++ b/cache/26958385.json @@ -0,0 +1,22 @@ +{ + "title": "理想的家", + "image": "https:\/\/img9.doubanio.com\/view\/subject\/l\/public\/s29293864.jpg", + "summary": "

什么样的房子是理想的家?把你对生活的爱与理解融入设计的房子,也许就是理想的家。如果你热爱旅行,如何用你从世界各地带回来的“战利品”打造你的家?如果你热爱美食与厨房,如何设计一个充满人间烟火味的家?如果你爱淘各种小玩意儿,如何布置一个杂货风的家?如果你的家就是你的办公室,如何在10秒钟之内从生活区转到工作区?你将在本书中看到来自东京脑洞大开的定制家居设计故事,探索房子与家之间的场域。<\/p>", + "author": [ + "[日] 蓝色工作室" + ], + "publisher": "化学工业出版社", + "pubdate": "2017-1-1", + "pages": "227", + "isbn": "未知", + "rating": 7.3, + "rating_count": 593, + "review": "相当精美的设计类图书,好看爱看,但是边AI写代码边看,有点断断续续,看杂志的感觉;", + "review_updated": 1771513872, + "custom_start_date": "2025.12.04", + "custom_read_date": "2025.12.08", + "custom_read_method": "精读", + "custom_book_category": "家居", + "custom_recommendation": 5, + "fetched_at": 1771513872 +} \ No newline at end of file diff --git a/cache/26981115.json b/cache/26981115.json new file mode 100644 index 0000000..651edf2 --- /dev/null +++ b/cache/26981115.json @@ -0,0 +1,22 @@ +{ + "title": "让大象飞", + "image": "https:\/\/img9.doubanio.com\/view\/subject\/l\/public\/s29389296.jpg", + "summary": "

这是一本为中国创业者量身定做的创业指南,将帮助创业者理解创新的基本方法、模式和硅谷的创业理念。作者霍夫曼频繁地穿梭于中美两地,与不同的创业者、投资人、政府负责人进行对话,积累了大量的来自中国创业者的第一手经验。在这本书里,从创业团队的人员配备到创业融资的成败再到团队的高效管理,从创业者的心理素质到创业者的独到眼光再到企业赖以生存的根本,360度无死角地呈现了一家公司从初创到惊艳到立足再到稳定的全过程,可谓《从0到1》的实践版。<\/p>

这更是来自硅谷的创业教父在创业寒冬时要对创业者说的话,当人人都在感叹创业不易、创新更难时,他却说,资本寒冬正好能让市场回归理性。霍夫曼从一个白手起家的创业者角度,也从一个资深投资人的角度,重新审视创新,有力地向我们证明了,对所有企业来说,创新不再是一种选择,而是进入商业世界的敲门砖。<\/p>

没有一本书详细解析了在硅谷孵化期内的创业公司的整个创新过程以及它们所使用的方法论,也没有任何一本书讲到了该如何将这些创新技巧应用于大到全球性的跨国公司、小到那些在车库里的初创企业,《让大象飞》做到了。<\/p>

当创业环境好的时候,风口之上,一切皆有可能;当风口没了的时候,大象还能飞吗?<\/p>

这本书是给当下创业者最好的解答。<\/p>", + "author": [ + "[美] 史蒂文·霍夫曼" + ], + "publisher": "中信出版社", + "pubdate": "2017-3", + "pages": "448", + "isbn": "未知", + "rating": 7.7, + "rating_count": 1006, + "review": "屋顶咖啡书架取读,因孩子闹腾,快速阅读,临走时还剩十几页没读。", + "review_updated": 1771513870, + "custom_start_date": "2025.12.01", + "custom_read_date": "2025.12.01", + "custom_read_method": "速读", + "custom_book_category": "创业", + "custom_recommendation": 3, + "fetched_at": 1771513870 +} \ No newline at end of file diff --git a/cache/26997273.json b/cache/26997273.json new file mode 100644 index 0000000..5a92ec0 --- /dev/null +++ b/cache/26997273.json @@ -0,0 +1,22 @@ +{ + "title": "我的宝贝", + "image": "https:\/\/img9.doubanio.com\/view\/subject\/l\/public\/s29401684.jpg", + "summary": "

她以一支笔坚持看守个人文字上的简单和朴素<\/p>

从遥远的撒哈拉到敦煌戈壁,她不随波逐流,也不诠释人生,只做生活的见证者<\/p>

她是我们心中浪漫、洒脱、真性情的永远的三毛,永恒的传奇<\/p>

《我的宝贝》一书中,三毛向读者们展示了一件件珍藏多年的宝贝,广东来的老茶壶、腓尼基人的宝瓶、小船ECHO号、第一匹白马……每一样宝贝来历的背后,都躲藏着一个不同的故事,见证了三毛经历过的爱情、亲情和友情,以及走遍世界各地的奇妙旅程。这些宝贝并非价值连城,但因为有了人的缘故,才被接纳,成了三毛生命中的印记,让她爱不释手。<\/p>", + "author": [ + "三毛" + ], + "publisher": "北京十月文艺出版社", + "pubdate": "2017-3", + "pages": "272", + "isbn": "未知", + "rating": 8.6, + "rating_count": 1737, + "review": "配图介绍作者淘到和收藏的各种物件,讲述故事及意义", + "review_updated": 1769984188, + "custom_start_date": "", + "custom_read_date": "2025.12.31", + "custom_read_method": "精读", + "custom_book_category": "散文", + "custom_recommendation": 5, + "fetched_at": 1769984188 +} \ No newline at end of file diff --git a/cache/30317423.json b/cache/30317423.json new file mode 100644 index 0000000..be4a1fd --- /dev/null +++ b/cache/30317423.json @@ -0,0 +1,22 @@ +{ + "title": "我杀了他", + "image": "https:\/\/img9.doubanio.com\/view\/subject\/l\/public\/s32313104.jpg", + "summary": "

★东野圭吾烧脑悬疑长篇,《恶意》系列作<\/p>

★读完《我杀了他》,99%的人都找不到凶手,你会不会是那1%?<\/p>

★与《白夜行》一起入选年度本格推理BEST10榜单<\/p>

★一个人究竟活成什么样,才会让身边的每个人都想杀了他?<\/p>

★《谁杀了她》难度升级,三个嫌疑人,三种犯罪视角,但真凶只有一个,答案就写在书里!<\/p>

★东野圭吾说:“《我杀了他》延续了《谁杀了她》的模式,只是这次嫌疑人增到了三个。有关《我杀了他》的推理论战愈演愈烈,身为作者,我真的很高兴。”<\/p>

----------------------<\/p>

内容简介:<\/p>

作家穗高在自己的婚礼上中毒身亡,他的经纪人、编辑和新娘的哥哥都以为是自己成功杀掉了他,并为此沾沾自喜。婚礼一周后,一封邀请函让三个嫌疑人聚到穗高家,等待着他们的是刑警加贺和新娘。案情逐渐清晰,谁把毒药混入穗高的鼻炎药是解谜的关键,但每个人为了自保而给出的证词,却出乎意料地成为另外两人无罪的证明。加贺听完证词,坚定地说“答案已经出来”,而只有凶手才能听懂他接下来要说的一番话。<\/p>", + "author": [ + "[日]东野圭吾" + ], + "publisher": "南海出版公司", + "pubdate": "2019-5", + "pages": "297", + "isbn": "未知", + "rating": 7.3, + "rating_count": 9835, + "review": "加贺探案集5,复杂的情感关系引发的复仇杀人案,从多个嫌疑人第一视角来叙述蛮有意思的,最后还留了悬念。", + "review_updated": 1771315140, + "custom_start_date": "", + "custom_read_date": "2026.01.07", + "custom_read_method": "精读", + "custom_book_category": "小说", + "custom_recommendation": 0, + "fetched_at": 1771315140 +} \ No newline at end of file diff --git a/cache/36367660.json b/cache/36367660.json new file mode 100644 index 0000000..400d689 --- /dev/null +++ b/cache/36367660.json @@ -0,0 +1,22 @@ +{ + "title": "吃透小红书文案:从模仿、创新到超越", + "image": "https:\/\/img9.doubanio.com\/view\/subject\/l\/public\/s34547196.jpg", + "summary": "

“写作太难”“我不是写作这块料”……当你看见朋友们在自媒体赚得盆满钵满时,你也曾跃跃欲试。<\/p>

当越来越多的人都在做小红书时,你也曾偷偷发过几篇笔记,可是发出来后点赞寥寥无几,涨粉更是太难,所以你就不想做了。<\/p>

其实,小红书平台对新人友爱而包容,只需要你认真运营,有一定的写作能力即可做出远超预期的成绩。<\/p>

本书从具体案例着手,详细剖析爆款背后的文案思维,创新性设计了文案吸引力模型、总结出提升笔记互动的三感一力,还以真实笔记做案例帮助你实现文案的模仿、创新和超越。<\/p>

本书从最简单实用的角度,提出了修复人设缺点的文案技巧,帮助博主打造“人设”、塑造人格魅力。<\/p>

本书从不同需求出发,结合作者独创的写作经验,实操展示提升文笔的五个技巧;<\/p>

本书从真正有用的角度出发,深度讲解了九种爆款笔记的创作技巧、优质文案的四象限法。<\/p>

本书适合想写不敢写、想提高文案写作能力、提升文笔的人员阅读,也可以作为新媒体从业者、文案从业者的参考用书。<\/p>", + "author": [ + "梁小小" + ], + "publisher": "人民邮电出版社", + "pubdate": "2023-4-1", + "pages": "224", + "isbn": "未知", + "rating": 6.6, + "rating_count": 127, + "review": "比较不错的小红书<\/a>运营书籍,作者经验丰富,写作功底不错,看似句句都在理,收获颇丰,但最好是边看边实操,不然看时感觉收获满满,但过后多数记不住,所以这本书阅读耗时较长。", + "review_updated": 1771315137, + "custom_start_date": "", + "custom_read_date": "2026.01.14", + "custom_read_method": "精读", + "custom_book_category": "自媒体", + "custom_recommendation": 5, + "fetched_at": 1771315137 +} \ No newline at end of file diff --git a/cache/36623046.json b/cache/36623046.json new file mode 100644 index 0000000..0abe992 --- /dev/null +++ b/cache/36623046.json @@ -0,0 +1,22 @@ +{ + "title": "我的母亲做保洁", + "image": "https:\/\/img3.doubanio.com\/view\/subject\/l\/public\/s34681227.jpg", + "summary": "

★★《 我的母亲做保洁》入选“2024年度中国好书”;2024年央视读书精选春季榜单,荣获中国好书2024年1-2月好书,作者张小满荣获刀锋图书奖·2023年非虚构作者,荣获豆瓣2024年度作品&豆瓣2024年度中国文学(非小说类)、LESS新世相2024年度作品;荣获2023年深圳读书月“十大劳动者文学好书·非虚构榜”年度十大好书、“南都2023年度十大好书”、搜狐文化2023年好书之选“年度好书”、亚洲周刊·2023全球華人十大好書(非小說)、《晶报·深港书评》2023年度十大好书·非虚构、腾讯好书2023年度十大好书。<\/p>

【编辑推荐】:<\/p>

★城市 巨轮运转下,保洁员群体被遮蔽的日常<\/p>

是谁在维系超级城市的“体面”与“洁净”?这是一群用体力劳作填满超长工作时间的外来务工者,他们在深圳这座包容万象的城市中寻找自己的生存空间,与污渍、垃圾为伴,支撑起城市文明对整洁细节的无限追求。作者张小满的母亲就是 城市保洁群体中的一员。他们落脚城市的初衷是如此相似,一路走来的人生又与时代发展的轨迹紧紧捆绑。他们在深圳寻找自己的生存缝隙,有自己的生活圈子,知道如何寻找机会,很清楚自己在整个阶层划分中的地位,用一种贬低自己的语气谈论着他们所做的工作。他们是一个庞大的群体,却总是处在城市生活的边缘,城市的“整洁”“舒适”“便利”几乎与他们无缘。而他们身上所承载的命运本质,其实也映照着绝大多数的我们。<\/p>

★母与女,“蓝”与“白”,两代人的隔阂与交融<\/p>

当母亲成为一名城市保洁员后,“我”与母亲重新生活在一起。母亲用批判的眼光观察“我”的生活,而“我”也激烈地回应。但“我”爱母亲,更想理解母亲。“我”试着从了解母亲在超级商场的保洁工作开始去理解她,母亲又为“我”带回非常具体而生动的保洁员群体日常素描,母女二人一起拼贴出这一群体的生存境况。母亲一辈子都是付出体力劳动的蓝领,而“我”则是看似跃入“体面阶层”的白领,母亲向来以此为荣。随着母女二人在记录保洁员群体故事的过程中,“我”得以重新回望自己的来处,越来越感到,自己很多看似努力的行为,看似接触到的圈子,其实不堪一击,“我”与母亲、与保洁员们,一样是无法豁出去的人,我们有共同的来处。而母亲也在这一过程中,颇感悲伤地意识到,苦读成材的子女,最终也不过是在城市生活中勉力维系一份螺丝钉般的工作,稍有不慎,同样会滑至“主流生活”之外。通过保洁员群体的故事,或许我们也能关照自身的处境,对自身的生活有所省视。至于“我”与母亲,两代人之间的真正理解也许永远无法抵达,但记录、书写母亲生活的这一过程,令“我”与母亲比从前任何时候都要信任对方、支持对方。<\/p>

★梁鸿、陈年喜、黄灯联袂推荐!<\/p>

【内容简介】:2020年,52岁的母亲从陕南农村来到深圳务工。独立生活十几年后,“我”与母亲在深圳相聚,重新住在一个屋檐下。我们在狭小的房间中争吵,母亲看不惯“我”的花钱方式,“我”难以忍受母亲的生活习惯。我们深陷彼此纠缠、负担和依赖的关系。然而我们彼此相爱,“我”深知母亲的软肋便是对我毫无保留的爱。于是,“我”想理解她。“我”的母亲在矿场、在建筑工地挥洒了年轻的汗水,如今在城市写字楼的几格空间中做保洁员。“我”想记录下母亲的打工史,努力穿梭过她记忆中的生命。母亲的人生为做着螺丝钉般工作的“我”建立起一块生活的“飞地”,让“我”得以喘息、回顾,珍重自己的来处。这是我们母女共同完成的一场写作。<\/p>", + "author": [ + "张小满" + ], + "publisher": "光启书局", + "pubdate": "2023-11", + "pages": "404", + "isbn": "未知", + "rating": 8.5, + "rating_count": 17093, + "review": "这是里是测试短评", + "review_updated": 1765553334, + "custom_start_date": "2025.12.03", + "custom_read_date": "2025.12.07", + "custom_read_method": "速读", + "custom_book_category": "小说", + "custom_recommendation": 2, + "fetched_at": 1765553334 +} \ No newline at end of file diff --git a/cache/36659710.json b/cache/36659710.json new file mode 100644 index 0000000..ed0da99 --- /dev/null +++ b/cache/36659710.json @@ -0,0 +1,22 @@ +{ + "title": "猫鱼", + "image": "https:\/\/img9.doubanio.com\/view\/subject\/l\/public\/s34867425.jpg", + "summary": "

★备受期待的华语重磅新书,电影人陈冲非虚构长篇作品<\/p>

——从上海童年的老房子到旧金山的家;从少女时代“小花”剧组到《末代皇帝》《太阳照常升起》的银幕背后;从祖辈的往事到父母、哥哥三代知识分子的精神历程……《猫鱼》是当代不可多得的回忆录,是知识人的心灵史,电影艺术家的传记,也是一部当代女性的成长之书、勇气之书。<\/p>

★金宇澄、罗新、姜文、许知远诚意推荐<\/p>

——“《猫鱼》是高水准的自传体散文集,既是个体生命史,又是时代大记录,一字一句,真气充盈。”(罗新)<\/p>

“陈冲建立的纸上王国,细腻、自由、直率,她的人与事,尤其几代知识分子的历史,填补了文学上海的叙事空白。”(金宇澄)<\/p>

“《猫鱼》是陈冲珍贵的个人记忆,写得鲜活、深邃。她毫不畏惧地邀请你踏入其中,经历她的人生……这种勇气,不是谁都有。”(姜文)<\/p>

★人的生命就像猫鱼,始终卑微、弱小,却坚韧地活着。在日常之中,期待奇迹发生<\/p>

——“‘猫鱼’是当年的上海话,菜场出售一种实该漏网的小鱼,用以喂猫,沪语发音‘毛鱼’。随着以后猫粮的出现,它在人们的记忆中消失了……”上海之冬,一只“猫鱼”死而复生,成了我和哥哥童年唯一的奇迹。“猫鱼”是生命里转瞬即逝的灵感,是人的本性里被遗忘或隐藏的真相,是日常生活中体验的每一个奇迹。<\/p>

★《收获》文学榜长篇非虚构获奖作品<\/p>

——“为读者展现了一个文学意义上独特又深沉的陈冲,她以克制内敛的笔法向着家族历史征进,踏进如烟的家族往事又不沉溺其中,通过众多日常的生活细节完成了对家人形象的刻写和赋形,从而与历史生活达成了深沉又动人的联系,作品呈现出的沉郁悲悯让人为之动容。”<\/p>

《猫鱼》是电影人陈冲的长篇非虚构作品。祖辈与母亲的故事、平江路老房子的岁月,“小花”摄制组大篷车的日子,独自踏上异国留学之旅,每一部电影不为人知的幕后,生命中的爱与痛楚、挣扎,经由作者的回望,跃然纸上。写家族故事,是独特的上海叙事、中国知识分子的心灵史;从《小花》到《末代皇帝》《意》《太阳照常升起》等等的银幕前后,是电影艺术家的传记;从上海童年到异国打拼,一段段人生旅程,是女性兼具激情与柔情的私语。<\/p>", + "author": [ + "陈冲" + ], + "publisher": "上海三联书店", + "pubdate": "2024-6", + "pages": "632", + "isbn": "未知", + "rating": 8.5, + "rating_count": 13858, + "review": "这里依然是短评", + "review_updated": 1765553335, + "custom_start_date": "2025.12.03", + "custom_read_date": "2025.12.07", + "custom_read_method": "速读", + "custom_book_category": "小说", + "custom_recommendation": 2, + "fetched_at": 1765553335 +} \ No newline at end of file diff --git a/cache/36661168.json b/cache/36661168.json new file mode 100644 index 0000000..ecd19aa --- /dev/null +++ b/cache/36661168.json @@ -0,0 +1,22 @@ +{ + "title": "怎么办?", + "image": "https:\/\/img9.doubanio.com\/view\/subject\/l\/public\/s35126064.jpg", + "summary": "

本书是法国哲学家阿尔都塞的重要遗稿之一。书稿仿照列宁《怎么办?》为题,写于1978年,属于阿尔都塞“自我批评”工作的巅峰时期。作者以其深厚的马克思主义理论素养,认真反思了1968年运动之后“欧洲共产主义”和民众反资本主义斗争的历史命运与革命前景,重新提出和思考了一系列具有战略意义的马克思主义政治理论问题。尤其重要的是,阿尔都塞的思考始终以葛兰西为对话者,对葛兰西的一系列理论概念做出了精彩而又深刻的解析和批评。鉴于当代人文社会科学理论中普遍出现的“葛兰西复兴”,鉴于葛兰西和阿尔都塞经常被视为西方马克思主义理论中富于活力的同一传统,这种批评就具有很高的理论价值。而对马基雅维利政治学的引人入胜的革命性解读构成这一对话和反思的学理背景,体现出阿尔都塞阅读方法的独特魅力。<\/p>", + "author": [ + "路易•阿尔都塞" + ], + "publisher": "西北大学出版社", + "pubdate": "2023-12-1", + "pages": "237", + "isbn": "未知", + "rating": 8.3, + "rating_count": 382, + "review": "测试", + "review_updated": 1765860663, + "custom_start_date": "2025.12.03", + "custom_read_date": "2025.12.07", + "custom_read_method": "速读", + "custom_book_category": "小说", + "custom_recommendation": 2, + "fetched_at": 1765860663 +} \ No newline at end of file diff --git a/cache/36672955.json b/cache/36672955.json new file mode 100644 index 0000000..2e76083 --- /dev/null +++ b/cache/36672955.json @@ -0,0 +1,22 @@ +{ + "title": "我看见的世界", + "image": "https:\/\/img9.doubanio.com\/view\/subject\/l\/public\/s34825536.jpg", + "summary": "

《我看见的世界》既是李飞飞的个人史,也是一部波澜壮阔、跌宕起伏的人工智能发展史。<\/p>

在这本书里,李飞飞回忆了自己从底层移民成长到顶尖科学家的经历。她度过了困顿艰辛的青少年时代,但对科学的热爱不断激励着她持续追寻人生的“北极星”,并最终走进科学的殿堂。<\/p>

当李飞飞和家人努力适应在美国的生活时,恰逢现代人工智能开始不断取得突破。她不断开启新的科学征程,并确立了自己在计算机视觉领域的科学使命,取得了非凡的成就。在这本书里,她详细记录了这些重大时刻的关键细节。同时,李飞飞也对未来人工智能的发展方向提出了自己的判断和警醒,核心就是“以人为本”,让人工智能真正推动人类的发展,而不是成为威胁。<\/p>

这本书既是对重大科学突破幕后的精彩窥探,也是一位女性用好奇心和勇气突破人生困境的故事。它不仅证明了即使是最技术性的学术研究也需要激情,更加表明永不停歇的好奇心可以激发无尽的科技创新。<\/p>", + "author": [ + "[美] 李飞飞" + ], + "publisher": "中信出版集团", + "pubdate": "2024-4", + "pages": "432", + "isbn": "未知", + "rating": 8.9, + "rating_count": 9706, + "review": "这里还是还是短评", + "review_updated": 1765553335, + "custom_start_date": "2025.12.03", + "custom_read_date": "2025.12.07", + "custom_read_method": "速读", + "custom_book_category": "小说", + "custom_recommendation": 2, + "fetched_at": 1765259721 +} \ No newline at end of file diff --git a/cache/36815098.json b/cache/36815098.json new file mode 100644 index 0000000..638f935 --- /dev/null +++ b/cache/36815098.json @@ -0,0 +1,22 @@ +{ + "title": "可能的世界", + "image": "https:\/\/img1.doubanio.com\/view\/subject\/l\/public\/s34850508.jpg", + "summary": "

《可能的世界》记录了杨潇2010—2019十年间前往美国、埃及、肯尼亚、缅甸、德国等十多个国家旅行、访学、短居的足迹,是一个拥抱世界的青年去现场,探寻可能性(并且认识不可能性)的历程。<\/p>

2010—2019这十年,是中国人与中国护照真正拥抱世界的十年,回过头看,这更像是历 史的一段特殊恩惠,几乎不可避免地被乡愁化地对待。作者带领我们重新回到一个又一个现场,让今日的目光照进当时当刻的记录,从时事、人文、历史、地理等多个维度,探讨了在一个转型的世界里,我们如何学会与过去相处、如何面对历史的内爆与偶然,如何探索与思考一个可能的世界。<\/p>", + "author": [ + "杨潇" + ], + "publisher": "上海文艺出版社", + "pubdate": "2024-5", + "pages": "397", + "isbn": "未知", + "rating": 8, + "rating_count": 2135, + "review": "哈哈哈", + "review_updated": 1765939064, + "custom_start_date": "2025.12.03", + "custom_read_date": "2025.12.07", + "custom_read_method": "速读", + "custom_book_category": "小说", + "custom_recommendation": 2, + "fetched_at": 1765861427 +} \ No newline at end of file diff --git a/cache/36838903.json b/cache/36838903.json new file mode 100644 index 0000000..ab83272 --- /dev/null +++ b/cache/36838903.json @@ -0,0 +1,22 @@ +{ + "title": "比山更高", + "image": "https:\/\/img3.doubanio.com\/view\/subject\/l\/public\/s34887762.jpg", + "summary": "

⛰️【内容简介】<\/p>

本书讲述了过去二十年来,中国自由攀登者用攀登书写各自的命运,在山上跨越生存和死亡的故事。自由攀登者是中国特有的一群人。他们只有寥寥几百人,却是中国死亡率最高的运动群体。遇难者的平均年龄仅有31岁。本书作者通过采访大量人物、挖掘大量碎片化资料,站在每一个年轻命运的人生十字路口上,记录中国自由攀登者的真实故事,通过他们的生命轨迹透视他们生活过的那个时代,书写了一部不为人知的登山史诗。这不只是一组登山者的群像,更是一个个不同时代的理想主义者在死亡的悬崖边追寻自由与自我的故事。他们在身体力行地告诉世界,他们甘愿用死亡的风险与代价换来可以超越一切的自由意志。<\/p>

⛰️【编辑推荐】<\/p>

🌟 一部中国自由攀登者的史诗,一群不同时代的年轻攀登者(严冬冬、马一桦、刘喜男、何川、阿左……)在山上跨越生存和死亡的故事<\/p>

🌟 记录一个个为了朴素理想行走在悬崖边缘的人,反抗主流、快乐至上的人,在世俗意义上甘愿失败的人,捕捉他们跃动的心灵和对自由的向往<\/p>

🌟 呈现人与人之间的联结和羁绊,从可见的结组、搭档,到不可言说、隐秘传承的精神共同体<\/p>

🌟 大量采访,扎实研究,严谨的事实核查,成就四十四万字长篇非虚构力作<\/p>

🌟 “挥着翅膀不再回头,纵然带着永远的伤口,至少我还拥有自由。”<\/p>

🌟 “因为喜欢所以选择去做,因为足够喜欢所以愿意承担一直做下去可能会造成的后果。”<\/p>

🌟 罗新、杨潇推荐阅读<\/p>", + "author": [ + "宋明蔚" + ], + "publisher": "上海文艺出版社", + "pubdate": "2024-6-1", + "pages": "692", + "isbn": "未知", + "rating": 9, + "rating_count": 5427, + "review": "这里还是测试短评", + "review_updated": 1765553334, + "custom_start_date": "2025.12.03", + "custom_read_date": "2025.12.07", + "custom_read_method": "速读", + "custom_book_category": "小说", + "custom_recommendation": 2, + "fetched_at": 1765255478 +} \ No newline at end of file diff --git a/cache/36897362.json b/cache/36897362.json new file mode 100644 index 0000000..ebdc1bd --- /dev/null +++ b/cache/36897362.json @@ -0,0 +1,22 @@ +{ + "title": "我用中文做了场梦", + "image": "https:\/\/img9.doubanio.com\/view\/subject\/l\/public\/s34894016.jpg", + "summary": "

🏆豆瓣2024年度图书<\/p>

🥇豆瓣2024年度外国文学(非小说类)TOP1<\/p>

🏆《南方都市报》2024年度十大好书<\/p>

✨一个意大利人用中文书写的中国六年漫游,这可能是你今年读到的最有意思的中文🌍<\/p>

“亚历的文字给人带来全新的阅读体验,在讲述上也打破了某种隔绝,这本身就是一个语言奇迹。”——陈英,意大利文学译者<\/p>

看《欢乐颂》学中文,在战争片当46号群演 | 在豆瓣上写日记,在上海创建中文写作俱乐部 | 在四川农村,把白酒当成暖气,跨越寒冬和方言的隔阂<\/p>

从2016到2022,这是一个意大利人眼中的六年,分裂、荒诞、希望和片刻的幸福,这也是我们共同的六年。<\/p>

·<\/p>

从罗马搬到北京,从零开始学中文,重新做学生。有时失业,有时居无定所,在不稳定中流动。<\/p>

在北京电影学院,跟宿管阿姨学怎么切菜;靠白酒和翻译软件交朋友,用蹩脚的普通话录播客;在国产片剧组,见证外籍群演之间为了一句台词的激烈竞争;在广州拍广告,开工前喝早茶,杀青时喝断片;在上海,把客厅当成写作沙龙,创造一个临时的家;困在海南的夏天,和偶遇的豆瓣网友一起看云。<\/p>

写这本书是为了讲我的故事,或者说,为了搞懂我这些年都是怎么过的。这不是政治学论文,也不是社会学调查,写的是我的生活,我和这片土地的复杂相处。<\/p>

·<\/p>

澎湃新闻Sixth Tone非虚构写作大赛一等奖得主作品<\/p>

一个意大利年轻人试图融入中国社会的故事,他用很短时间学会了汉语,并用中文写就了自己在这片土地生活六年的经历。亚历的文字给人带来全新的阅读体验,在讲述上也打破了某种隔绝,这本身就是一个语言奇迹,一次放下母语、全身心投入到汉语的勇敢尝试。面对过去几年任何人都无法避免触碰到的坚硬现实,一个“外人”面临的境况更加复杂,很多时候都会触碰到某种极限,但亚历用幽默和包容应对这种“生活在别处”的挑战——这是一位世界公民的生活体验,一个社会观察者眼中的中国切片,一本充满活力、记录人与人之间连接的青年手记。——陈英,意大利文学译者<\/p>

亚历的黑色幽默总让人突然爆笑,而他的局外人视角又显得冷静。当本土作者因为强烈的痛苦和使命感的压力很难落笔时,亚历却一直稳定地记录,细致,生动,讽刺,幽你一默。能遇到这样的作者是一种幸运。——熊阿姨,媒体人<\/p>

你大概很少见到一个外国人如此流畅和沉浸式的中文写作,那些意味深长的细节和故事让人忍不住会心一笑。他更关心真实的人——酒店前台的阿姨,想去山西转一转的食堂打菜的小哥,维修大叔关于一颗苹果的心愿,他们不再是“功能化”的角色,在一个意大利作者的笔下变得生动起来。——极昼工作室<\/p>

近期在简体中文世界里最好的阅读体验,来自一位意大利人。他经常能用最常见的词汇和句式营造出一种奇异的幽默感。亚历所写作的内容并非是有意寻找到的故事线索,而是一种当下的氛围。中文也不仅仅是他的观察对象,而是他表达自我的工具。亚历所记录的素材是私人的,情感与视角却是公共的。——NOWNESS现在<\/p>

亚历从零开始学习中文,也用新的视角看待和记录在中国的生活。他看《欢乐颂》,与中国朋友喝白酒,遇到外国人住宿登记的难题。他在主旋律电影中当群演,认识了一位想拿奥斯卡奖的美国群演梅森。他在隔离中仍然寻求人与人的连接,在上海办写作俱乐部,封控时与朋友互助,偶尔讨论“润不润”的问题。很多读者在亚历的故事里看到自己的生活。——正面连接<\/p>

在中国生活的六年期间,他学过电影,做过群演,拍过广告。2020年封在学校期间,他在豆瓣写自己跟宿舍保洁阿姨、维修大叔、食堂打菜小哥的日常互动,感觉大家褪下了原有的身份,都是努力活着的人类而已。在最孤独的时候,文字像一根通向外界的绳索,连接了亚历和读到他文字的人们。——一席<\/p>

亚历的写作像一片很深邃又很安静的湖,不需要任何风浪和涟漪就能让人心生神往。——棒棒,豆瓣读者<\/p>", + "author": [ + "[意] 亚历(Alessandro Ceschi)" + ], + "publisher": "文汇出版社", + "pubdate": "2024-7", + "pages": "288", + "isbn": "未知", + "rating": 8, + "rating_count": 7570, + "review": "哈哈哈", + "review_updated": 1765869491, + "custom_start_date": "2025.12.03", + "custom_read_date": "2025.12.07", + "custom_read_method": "速读", + "custom_book_category": "小说", + "custom_recommendation": 3, + "fetched_at": 1765869491 +} \ No newline at end of file diff --git a/cache/37153306.json b/cache/37153306.json new file mode 100644 index 0000000..8032205 --- /dev/null +++ b/cache/37153306.json @@ -0,0 +1,22 @@ +{ + "title": "种草", + "image": "https:\/\/img9.doubanio.com\/view\/subject\/l\/public\/s35031256.jpg", + "summary": "

♻️<\/p>

原以为是营销问题,实际上是经营问题;<\/p>

原以为是口碑问题,实际上是产品和服务问题;<\/p>

原以为是内容投放问题,实际上是用户洞察问题;<\/p>

原以为是运气问题,实际上是管理问题。<\/p>

《种草》一书完整呈现了现代营销第三类范式“种草营销”,由“现代营销学之父”菲利普·科特勒提供理论支持,小红书营销实验室和资深商业研究者于冬琪联合著作。<\/p>

种草,是有质量的商业生长。本书深度复盘 6年种草实战积累,40+企业实操案例,深度还原4个消费品牌做法,总结出“种草”的新定义:种草是面对变化的用户和未来的经营方式,通过种草,真诚地帮助人,为向往的生活找到解决方案,让企业持续成功。<\/p>

本书完整解析了“种草”底层心法:通过捕捉、理解、放大、激发四个步骤,构成一个自我增强的正循环,成为驱动企业发展的业务方法,是为初创品牌、传统企业、电商团队、平台达人量身打造的“种草秘籍”,是内卷时代的新出路。<\/p>", + "author": [ + "小红书营销实验室" + ], + "publisher": "浙江文艺出版社", + "pubdate": "2024-12", + "pages": "304", + "isbn": "未知", + "rating": 6.7, + "rating_count": 584, + "review": "多数内容涉及大企业的管理,而我需要看的是内容创作和账户运营,仅筛选了感兴趣部分精读。", + "review_updated": 1770035218, + "custom_start_date": "2026.01.19", + "custom_read_date": "2026.01.28", + "custom_read_method": "速读", + "custom_book_category": "运营", + "custom_recommendation": 3, + "fetched_at": 1770035218 +} \ No newline at end of file diff --git a/cache/4903440.json b/cache/4903440.json new file mode 100644 index 0000000..00b0f3c --- /dev/null +++ b/cache/4903440.json @@ -0,0 +1,22 @@ +{ + "title": "名侦探的诅咒", + "image": "https:\/\/img1.doubanio.com\/view\/subject\/l\/public\/s4464968.jpg", + "summary": "

“我”莫名来到一座单纯的小城,城中之人单纯得令人生疑,“我”也成了人称“天下一大五郎”的名侦探。<\/p>

第一天,一间绝对孤立的密室里,小城最强势有钱人中弹身亡。<\/p>

第二天,一位小说家额头中箭,“我”就在隔壁,凶手却消失无踪。<\/p>

第三天,与世隔绝的暴风雨山庄,四人接连离奇丧命……<\/p>

无形的阴冷诅咒在整个城市漫卷开来。<\/p>

这个诡谲的世界背后究竟暗藏什么隐痛与玄机?<\/p>", + "author": [ + "(日)东野圭吾" + ], + "publisher": "南海出版公司", + "pubdate": "2010-10", + "pages": "217", + "isbn": "未知", + "rating": 7.1, + "rating_count": 9207, + "review": "小说里的小说,穿越的推理小说哈,还行,有特色想法。", + "review_updated": 1771513874, + "custom_start_date": "", + "custom_read_date": "2025.12.10", + "custom_read_method": "精读", + "custom_book_category": "小说", + "custom_recommendation": 4, + "fetched_at": 1771513874 +} \ No newline at end of file diff --git a/cache/6429267.json b/cache/6429267.json new file mode 100644 index 0000000..a136384 --- /dev/null +++ b/cache/6429267.json @@ -0,0 +1,22 @@ +{ + "title": "美丽的凶器", + "image": "https:\/\/img2.doubanio.com\/view\/subject\/l\/public\/s6881741.jpg", + "summary": "

《美丽的凶器》具有浓郁的东野圭吾风格,从一桩扑朔迷离的事件入手舒展开去,描绘人心深处在利益与道德之间的挣扎,悬念贯串始终,场景极富画面感,结局低回婉转,一唱三叹……<\/p>

为掩盖不光彩的过去,四名退役运动员潜入医学专家仙堂的住所,企图消除证据。仙堂在冲突中身亡。<\/p>

四人纵火后逃离现场,孰料不久便惊恐地发现自己命在旦夕。一名神秘女子对他们步步紧逼、但求索命,而噩梦深处竟还暗藏着惊人的真相……<\/p>", + "author": [ + "[日] 东野圭吾" + ], + "publisher": "南海出版公司", + "pubdate": "2011-8", + "pages": "236", + "isbn": "未知", + "rating": 6.5, + "rating_count": 5467, + "review": "一场因兴奋剂引发的杀人及复仇计划,剧情有些透明,但最终还是有些出人意料。", + "review_updated": 1771513871, + "custom_start_date": "", + "custom_read_date": "2025.12.06", + "custom_read_method": "精读", + "custom_book_category": "小说", + "custom_recommendation": 4, + "fetched_at": 1771513871 +} \ No newline at end of file diff --git a/cache/6558708.json b/cache/6558708.json new file mode 100644 index 0000000..83bcfe9 --- /dev/null +++ b/cache/6558708.json @@ -0,0 +1,22 @@ +{ + "title": "稻草人手记", + "image": "https:\/\/img9.doubanio.com\/view\/subject\/l\/public\/s6565844.jpg", + "summary": "

《稻草人手记》记录的是三毛定居加纳利岛后生活中的点点滴滴,语言朴实、简单,其中的情趣与无奈,朴实而谐趣,令人笑叹。也许,正是这样简简单单的生活,才给了三毛无限的创作灵感。 《稻草人手记》主要内容为江洋大盗,平沙漠漠夜带刀,逍遥七岛游,一个陌生人的死,大胡子与我,亲爱的婆婆大人,这样的人生……<\/p>", + "author": [ + "三毛" + ], + "publisher": "北京十月文艺出版社", + "pubdate": "2011-7-1", + "pages": "217", + "isbn": "未知", + "rating": 8.9, + "rating_count": 8440, + "review": "写了不少生活趣事、杂事、烦事,家长里短的,亲情、爱情,读书。", + "review_updated": 1770035334, + "custom_start_date": "2026.01.24", + "custom_read_date": "2026.01.29", + "custom_read_method": "精读", + "custom_book_category": "散文", + "custom_recommendation": 5, + "fetched_at": 1770035219 +} \ No newline at end of file