Merge pull request #3091 from qixing-jk/feat-aisummary-wordcount

Feat aisummary wordcount
This commit is contained in:
tangly1024
2025-01-01 15:39:50 +08:00
committed by GitHub
26 changed files with 418 additions and 395 deletions

View File

@@ -31,9 +31,8 @@ export default function PostHeader({ post, siteInfo, isDarkMode }) {
height: 100%;
top: 0;
left: 0;
box-shadow: 110px -130px 500px 100px ${isDarkMode
? '#CA8A04'
: '#0060e0'} inset;
box-shadow: 110px -130px 500px 100px
${isDarkMode ? '#CA8A04' : '#0060e0'} inset;
}
`}</style>
@@ -105,7 +104,10 @@ export default function PostHeader({ post, siteInfo, isDarkMode }) {
<section className='flex-wrap dark:text-gray-200 text-opacity-70 shadow-text-md flex text-sm justify-center md:justify-start mt-4 text-white font-light leading-8'>
<div className='flex justify-center '>
<div className='mr-2'>
<WordCount />
<WordCount
wordCount={post.wordCount}
readTime={post.readTime}
/>
</div>
{post?.type !== 'Page' && (
<>

View File

@@ -42,6 +42,7 @@ import SearchNav from './components/SearchNav'
import SideRight from './components/SideRight'
import CONFIG from './config'
import { Style } from './style'
import AISummary from '@/components/AISummary'
/**
* 基础布局 采用上中下布局,移动端使用顶部侧边导航栏
@@ -306,6 +307,7 @@ const LayoutSlug = props => {
<section
className='wow fadeInUp p-5 justify-center mx-auto'
data-wow-delay='.2s'>
<AISummary aiSummary={post.aiSummary}/>
<WWAds orientation='horizontal' className='w-full' />
{post && <NotionPage post={post} />}
<WWAds orientation='horizontal' className='w-full' />

View File

@@ -1,46 +1,48 @@
import Link from 'next/link'
import { useGlobal } from '@/lib/global'
import TagItemMiddle from './TagItemMiddle'
import WordCount from './WordCount'
import { formatDateFmt } from '@/lib/utils/formatDate'
import WordCount from '@/components/WordCount'
export const ArticleInfo = (props) => {
export const ArticleInfo = props => {
const { post } = props
const { locale } = useGlobal()
return (
<section className='mb-3 dark:text-gray-200'>
<div className='my-3'>
{post.tagItems && (
<div className="flex flex-nowrap overflow-x-auto">
{post.tagItems.map(tag => (
<TagItemMiddle key={tag.name} tag={tag} />
))}
</div>
)}
</div>
<section className='mb-3 dark:text-gray-200'>
<div className='my-3'>
{post.tagItems && (
<div className='flex flex-nowrap overflow-x-auto'>
{post.tagItems.map(tag => (
<TagItemMiddle key={tag.name} tag={tag} />
))}
</div>
)}
</div>
<div className='flex flex-wrap gap-3 mt-5 text-sm'>
{post?.type !== 'Page' && (<>
<Link
href={`/archive#${formatDateFmt(post?.publishDate, 'yyyy-MM')}`}
passHref
className="cursor-pointer whitespace-nowrap">
<i className='far fa-calendar-minus fa-fw'/> {locale.COMMON.POST_TIME}: {post?.publishDay}
</Link>
<span className='whitespace-nowrap'>
<i className='far fa-calendar-check fa-fw' />{locale.COMMON.LAST_EDITED_TIME}: {post.lastEditedDay}
</span>
<span className="hidden busuanzi_container_page_pv font-light mr-2">
<i className='mr-1 fas fa-eye' /><span className="busuanzi_value_page_pv" />
</span>
<WordCount />
</>)}
</div>
</section>
<div className='flex flex-wrap gap-3 mt-5 text-sm'>
{post?.type !== 'Page' && (
<>
<Link
href={`/archive#${formatDateFmt(post?.publishDate, 'yyyy-MM')}`}
passHref
className='cursor-pointer whitespace-nowrap'>
<i className='far fa-calendar-minus fa-fw' />{' '}
{locale.COMMON.POST_TIME}: {post?.publishDay}
</Link>
<span className='whitespace-nowrap'>
<i className='far fa-calendar-check fa-fw' />
{locale.COMMON.LAST_EDITED_TIME}: {post.lastEditedDay}
</span>
<span className='hidden busuanzi_container_page_pv font-light mr-2'>
<i className='mr-1 fas fa-eye' />
<span className='busuanzi_value_page_pv' />
</span>
<WordCount wordCount={post.wordCount} readTime={post.readTime} />
</>
)}
</div>
</section>
)
}

View File

@@ -1,68 +0,0 @@
import { useGlobal } from '@/lib/global'
import { useEffect } from 'react'
/**
* 字数统计
* @returns
*/
export default function WordCount() {
const { locale } = useGlobal()
useEffect(() => {
countWords()
})
return <span id='wordCountWrapper' className='flex gap-3 font-light'>
<span className='flex whitespace-nowrap items-center'>
<i className='pl-1 pr-2 fas fa-file-word' />
<span>{locale.COMMON.WORD_COUNT}</span>&nbsp;
<span id='wordCount'>0</span>
</span>
<span className='flex whitespace-nowrap items-center'>
<i className='mr-1 fas fa-clock' />
<span></span>
<span id='readTime'>0</span>&nbsp;{locale.COMMON.MINUTE}
</span>
</span>
}
/**
* 更新字数统计和阅读时间
*/
function countWords() {
const articleText = deleteHtmlTag(document.querySelector('#article-wrapper #notion-article')?.innerHTML)
const wordCount = fnGetCpmisWords(articleText)
// 阅读速度 300-500每分钟
document.getElementById('wordCount').innerHTML = wordCount
document.getElementById('readTime').innerHTML = Math.floor(wordCount / 400) + 1
const wordCountWrapper = document.getElementById('wordCountWrapper')
wordCountWrapper.classList.remove('hidden')
}
// 去除html标签
function deleteHtmlTag(str) {
if (!str) {
return ''
}
str = str.replace(/<[^>]+>|&[^>]+;/g, '').trim()// 去掉所有的html标签和&nbsp;之类的特殊符合
return str
}
// 用word方式计算正文字数
function fnGetCpmisWords(str) {
if (!str) {
return 0
}
let sLen = 0
try {
// eslint-disable-next-line no-irregular-whitespace
str = str.replace(/(\r\n+|\s+| +)/g, '龘')
// eslint-disable-next-line no-control-regex
str = str.replace(/[\x00-\xff]/g, 'm')
str = str.replace(/m+/g, '*')
str = str.replace(/龘+/g, '')
sLen = str.length
} catch (e) {
}
return sLen
}

View File

@@ -14,7 +14,7 @@ import ArticleCopyright from './ArticleCopyright'
import BlogAround from './BlogAround'
import RecommendPosts from './RecommendPosts'
import TagItem from './TagItem'
import WordCount from './WordCount'
import WordCount from '@/components/WordCount'
/**
*
@@ -92,7 +92,7 @@ export default function ArticleDetail(props) {
)}
</div>
<WordCount />
<WordCount wordCount={post.wordCount} readTime={post.readTime} />
</section>
</header>
)}

View File

@@ -1,62 +0,0 @@
import { useGlobal } from '@/lib/global'
import { useEffect } from 'react'
/**
* 字数统计
* @returns
*/
export default function WordCount() {
useEffect(() => {
countWords()
})
const { locale } = useGlobal()
return <div id='wordCountWrapper' className='flex justify-center my-auto font-light'>
<i className='mr-1 fas fa-file-word my-auto' />
<span className='hidden md:block'>{locale.COMMON.WORD_COUNT}</span>
<strong id='wordCount'>0</strong> &nbsp;|&nbsp; <i className='mr-1 fas fa-clock my-auto' />{locale.COMMON.READ_TIME} <span className='hidden md:block'></span> <strong id='readTime'>0</strong> {locale.COMMON.MINUTE}
</div>
}
/**
* 更新字数统计和阅读时间
*/
function countWords() {
const articleText = deleteHtmlTag(document.querySelector('#article-wrapper #notion-article')?.innerHTML)
const wordCount = fnGetCpmisWords(articleText)
// 阅读速度 300-500每分钟
document.getElementById('wordCount').innerHTML = wordCount
document.getElementById('readTime').innerHTML = Math.floor(wordCount / 400) + 1
const wordCountWrapper = document.getElementById('wordCountWrapper')
wordCountWrapper.classList.remove('hidden')
}
// 去除html标签
function deleteHtmlTag(str) {
if (!str) {
return ''
}
str = str.replace(/<[^>]+>|&[^>]+;/g, '').trim()// 去掉所有的html标签和&nbsp;之类的特殊符合
return str
}
// 用word方式计算正文字数
function fnGetCpmisWords(str) {
if (!str) {
return 0
}
let sLen = 0
try {
// eslint-disable-next-line no-irregular-whitespace
str = str.replace(/(\r\n+|\s+| +)/g, '龘')
// eslint-disable-next-line no-control-regex
str = str.replace(/[\x00-\xff]/g, 'm')
str = str.replace(/m+/g, '*')
str = str.replace(/龘+/g, '')
sLen = str.length
} catch (e) {
}
return sLen
}