增加文章点赞和分享功能

This commit is contained in:
李志强 2025-05-20 11:28:29 +08:00
parent 16d2fe4520
commit 40caef19dd
5 changed files with 391 additions and 209 deletions

View File

@ -142,6 +142,16 @@ class ArticlesController extends BaseController
$id = Request::param('id/d', 0); $id = Request::param('id/d', 0);
// 检查文章是否存在
$article = Articles::where('id', $id)
->where('delete_time', null)
->where('status', 2)
->find();
if (!$article) {
return json(['code' => 0, 'msg' => '文章不存在或已被删除']);
}
// 更新点赞数 // 更新点赞数
$result = Articles::where('id', $id) $result = Articles::where('id', $id)
->where('delete_time', null) ->where('delete_time', null)
@ -149,7 +159,15 @@ class ArticlesController extends BaseController
->update(); ->update();
if ($result) { if ($result) {
return json(['code' => 1, 'msg' => '点赞成功']); // 返回更新后的点赞数
$newLikes = $article['likes'] + 1;
return json([
'code' => 1,
'msg' => '点赞成功',
'data' => [
'likes' => $newLikes
]
]);
} else { } else {
return json(['code' => 0, 'msg' => '点赞失败']); return json(['code' => 0, 'msg' => '点赞失败']);
} }

View File

@ -30,12 +30,12 @@
</div> </div>
<div class="article-actions"> <div class="article-actions">
<div class="action-item like-btn"> <div class="action-item like-btn" id="likeBtn">
<i class="fa fa-thumbs-up"></i> <i class="fa fa-thumbs-up"></i>
<span class="action-text">点赞</span> <span class="action-text">点赞</span>
<span class="action-count" id="articleLikes">0</span> <span class="action-count" id="articleLikes">0</span>
</div> </div>
<div class="action-item share-btn"> <div class="action-item share-btn" id="shareBtn">
<i class="fa fa-share-alt"></i> <i class="fa fa-share-alt"></i>
<span class="action-text">分享</span> <span class="action-text">分享</span>
</div> </div>
@ -518,12 +518,12 @@
} }
}) })
.then(response => { .then(response => {
console.log('Response status:', response.status); // console.log('Response status:', response.status);
console.log('Response headers:', response.headers); // console.log('Response headers:', response.headers);
return response.json(); return response.json();
}) })
.then(result => { .then(result => {
console.log('API response:', result); // console.log('API response:', result);
if (result.code === 1) { if (result.code === 1) {
renderArticleDetail(result.data); renderArticleDetail(result.data);
// 更新访问次数 // 更新访问次数
@ -543,26 +543,51 @@
}); });
// 点赞功能 // 点赞功能
const likeBtn = document.querySelector('.like-btn'); const likeBtn = document.getElementById('likeBtn');
if (likeBtn) { if (likeBtn) {
// 检查是否已经点赞
if (likeBtn.classList.contains('liked')) {
likeBtn.style.pointerEvents = 'none'; // 禁用点击
likeBtn.style.cursor = 'default'; // 改变鼠标样式
return;
}
likeBtn.addEventListener('click', function () { likeBtn.addEventListener('click', function () {
// 立即禁用按钮,防止重复点击
likeBtn.style.pointerEvents = 'none';
likeBtn.style.cursor = 'default';
fetch('/index/articles/like?id=' + articleId, { fetch('/index/articles/like?id=' + articleId, {
method: 'POST' method: 'POST',
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
}) })
.then(response => response.json()) .then(response => response.json())
.then(data => { .then(data => {
if (data.code === 1) { if (data.code === 1) {
const countElement = this.querySelector('.action-count'); const countElement = document.getElementById('articlesLikes');
let count = parseInt(countElement.textContent); if (countElement) {
let count = parseInt(countElement.textContent) || 0;
countElement.textContent = count + 1; countElement.textContent = count + 1;
this.classList.add('liked'); }
this.style.color = '#f57005'; // 添加点赞状态
likeBtn.classList.add('liked');
likeBtn.querySelector('i').style.color = '#f57005';
layer.msg('点赞成功', {icon: 1});
} else { } else {
alert('点赞失败:' + data.msg); // 如果请求失败,恢复按钮状态
likeBtn.style.pointerEvents = 'auto';
likeBtn.style.cursor = 'pointer';
layer.msg('点赞失败:' + data.msg, {icon: 2});
} }
}) })
.catch(error => { .catch(error => {
// 如果请求失败,恢复按钮状态
likeBtn.style.pointerEvents = 'auto';
likeBtn.style.cursor = 'pointer';
console.error('点赞请求失败:', error); console.error('点赞请求失败:', error);
layer.msg('点赞失败,请稍后重试', {icon: 2});
}); });
}); });
} }
@ -613,5 +638,29 @@
console.error('更新访问次数失败:', error); console.error('更新访问次数失败:', error);
}); });
} }
// 分享功能
const shareBtn = document.getElementById('shareBtn');
if (shareBtn) {
shareBtn.addEventListener('click', function () {
// 获取当前页面URL
const currentUrl = window.location.href;
// 创建临时输入框
const tempInput = document.createElement('input');
tempInput.value = currentUrl;
document.body.appendChild(tempInput);
// 选择并复制文本
tempInput.select();
document.execCommand('copy');
// 移除临时输入框
document.body.removeChild(tempInput);
// 提示用户复制成功
alert('链接已复制到剪贴板');
});
}
</script> </script>
{include file="component/foot" /} {include file="component/foot" /}

View File

@ -18,7 +18,8 @@
<span class="program-author"><i class="fa fa-user"></i> <span id="programAuthor"></span></span> <span class="program-author"><i class="fa fa-user"></i> <span id="programAuthor"></span></span>
<span class="program-date"><i class="fa fa-calendar"></i> <span id="programDate"></span></span> <span class="program-date"><i class="fa fa-calendar"></i> <span id="programDate"></span></span>
<span class="program-views"><i class="fa-solid fa-eye"></i> <span id="programViews"></span> 浏览</span> <span class="program-views"><i class="fa-solid fa-eye"></i> <span id="programViews"></span> 浏览</span>
<span class="program-downloads"><i class="fa-solid fa-download"></i> <span id="programDownloads"></span> 下载</span> <span class="program-downloads"><i class="fa-solid fa-download"></i> <span id="programDownloads"></span>
下载</span>
</div> </div>
</div> </div>
@ -44,12 +45,16 @@
</div> </div>
</div> </div>
<div class="program-content">
</div>
<div class="program-actions"> <div class="program-actions">
<div class="action-item download-btn" id="downloadBtn"> <div class="action-item download-btn" id="downloadBtn">
<i class="fa fa-download"></i> <i class="fa fa-download"></i>
<span class="action-text">立即下载</span> <span class="action-text">立即下载</span>
</div> </div>
<div class="action-item share-btn"> <div class="action-item share-btn" id="shareBtn">
<i class="fa fa-share-alt"></i> <i class="fa fa-share-alt"></i>
<span class="action-text">分享</span> <span class="action-text">分享</span>
</div> </div>
@ -448,6 +453,8 @@
renderProgramDetail(result.data); renderProgramDetail(result.data);
// 更新访问次数 // 更新访问次数
updateProgramViews(programId); updateProgramViews(programId);
// 初始化分享功能
initShareFunction();
} else { } else {
alert(result.msg || '获取程序详情失败'); alert(result.msg || '获取程序详情失败');
} }
@ -530,5 +537,31 @@
console.error('更新访问次数失败:', error); console.error('更新访问次数失败:', error);
}); });
} }
// 初始化分享功能
function initShareFunction() {
const shareBtn = document.getElementById('shareBtn');
if (shareBtn) {
shareBtn.addEventListener('click', function () {
// 获取当前页面URL
const currentUrl = window.location.href;
// 创建临时输入框
const tempInput = document.createElement('input');
tempInput.value = currentUrl;
document.body.appendChild(tempInput);
// 选择并复制文本
tempInput.select();
document.execCommand('copy');
// 移除临时输入框
document.body.removeChild(tempInput);
// 提示用户复制成功
layer.msg('链接已复制到剪贴板');
});
}
}
</script> </script>
{include file="component/foot" /} {include file="component/foot" /}

View File

@ -1,4 +1,4 @@
<?php /*a:5:{s:63:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\articles\detail.php";i:1747646466;s:62:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\head.php";i:1747617129;s:71:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\header-simple.php";i:1747445574;s:64:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\footer.php";i:1747617266;s:62:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\foot.php";i:1747616844;}*/ ?> <?php /*a:5:{s:63:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\articles\detail.php";i:1747711602;s:62:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\head.php";i:1747617129;s:71:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\header-simple.php";i:1747705841;s:64:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\footer.php";i:1747617266;s:62:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\foot.php";i:1747616844;}*/ ?>
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
@ -48,7 +48,7 @@
<div class="main-menu"> <div class="main-menu">
<div class="container"> <div class="container">
<div class="main-menu__logo"> <div class="main-menu__logo">
<a href="index.html"><img src="/static/images/logo.png" width="186" alt="Logo"></a> <a href="index.html"><img src="/static/images/logo1.png" width="186" alt="Logo"></a>
</div> </div>
<div class="main-menu__nav"> <div class="main-menu__nav">
<ul class="main-menu__list"> <ul class="main-menu__list">
@ -90,7 +90,7 @@
<div class="sticky-nav" style="display: none;"> <div class="sticky-nav" style="display: none;">
<div class="container"> <div class="container">
<div class="sticky-nav__logo"> <div class="sticky-nav__logo">
<a href="index.html"><img src="/static/images/logo.png" width="150" alt="Logo"></a> <a href="index.html"><img src="/static/images/logo1.png" width="150" alt="Logo"></a>
</div> </div>
<div class="sticky-nav__menu"> <div class="sticky-nav__menu">
<ul> <ul>
@ -475,12 +475,12 @@
</div> </div>
<div class="article-actions"> <div class="article-actions">
<div class="action-item like-btn"> <div class="action-item like-btn" id="likeBtn">
<i class="fa fa-thumbs-up"></i> <i class="fa fa-thumbs-up"></i>
<span class="action-text">点赞</span> <span class="action-text">点赞</span>
<span class="action-count" id="articleLikes">0</span> <span class="action-count" id="articleLikes">0</span>
</div> </div>
<div class="action-item share-btn"> <div class="action-item share-btn" id="shareBtn">
<i class="fa fa-share-alt"></i> <i class="fa fa-share-alt"></i>
<span class="action-text">分享</span> <span class="action-text">分享</span>
</div> </div>
@ -1018,12 +1018,12 @@
} }
}) })
.then(response => { .then(response => {
console.log('Response status:', response.status); // console.log('Response status:', response.status);
console.log('Response headers:', response.headers); // console.log('Response headers:', response.headers);
return response.json(); return response.json();
}) })
.then(result => { .then(result => {
console.log('API response:', result); // console.log('API response:', result);
if (result.code === 1) { if (result.code === 1) {
renderArticleDetail(result.data); renderArticleDetail(result.data);
// 更新访问次数 // 更新访问次数
@ -1043,26 +1043,51 @@
}); });
// 点赞功能 // 点赞功能
const likeBtn = document.querySelector('.like-btn'); const likeBtn = document.getElementById('likeBtn');
if (likeBtn) { if (likeBtn) {
// 检查是否已经点赞
if (likeBtn.classList.contains('liked')) {
likeBtn.style.pointerEvents = 'none'; // 禁用点击
likeBtn.style.cursor = 'default'; // 改变鼠标样式
return;
}
likeBtn.addEventListener('click', function () { likeBtn.addEventListener('click', function () {
// 立即禁用按钮,防止重复点击
likeBtn.style.pointerEvents = 'none';
likeBtn.style.cursor = 'default';
fetch('/index/articles/like?id=' + articleId, { fetch('/index/articles/like?id=' + articleId, {
method: 'POST' method: 'POST',
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
}) })
.then(response => response.json()) .then(response => response.json())
.then(data => { .then(data => {
if (data.code === 1) { if (data.code === 1) {
const countElement = this.querySelector('.action-count'); const countElement = document.getElementById('articlesLikes');
let count = parseInt(countElement.textContent); if (countElement) {
let count = parseInt(countElement.textContent) || 0;
countElement.textContent = count + 1; countElement.textContent = count + 1;
this.classList.add('liked'); }
this.style.color = '#f57005'; // 添加点赞状态
likeBtn.classList.add('liked');
likeBtn.querySelector('i').style.color = '#f57005';
layer.msg('点赞成功', {icon: 1});
} else { } else {
alert('点赞失败:' + data.msg); // 如果请求失败,恢复按钮状态
likeBtn.style.pointerEvents = 'auto';
likeBtn.style.cursor = 'pointer';
layer.msg('点赞失败:' + data.msg, {icon: 2});
} }
}) })
.catch(error => { .catch(error => {
// 如果请求失败,恢复按钮状态
likeBtn.style.pointerEvents = 'auto';
likeBtn.style.cursor = 'pointer';
console.error('点赞请求失败:', error); console.error('点赞请求失败:', error);
layer.msg('点赞失败,请稍后重试', {icon: 2});
}); });
}); });
} }
@ -1113,6 +1138,30 @@
console.error('更新访问次数失败:', error); console.error('更新访问次数失败:', error);
}); });
} }
// 分享功能
const shareBtn = document.getElementById('shareBtn');
if (shareBtn) {
shareBtn.addEventListener('click', function () {
// 获取当前页面URL
const currentUrl = window.location.href;
// 创建临时输入框
const tempInput = document.createElement('input');
tempInput.value = currentUrl;
document.body.appendChild(tempInput);
// 选择并复制文本
tempInput.select();
document.execCommand('copy');
// 移除临时输入框
document.body.removeChild(tempInput);
// 提示用户复制成功
alert('链接已复制到剪贴板');
});
}
</script> </script>
</body> </body>

View File

@ -1,4 +1,4 @@
<?php /*a:5:{s:62:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\program\detail.php";i:1747706200;s:62:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\head.php";i:1747617129;s:71:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\header-simple.php";i:1747705841;s:64:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\footer.php";i:1747617266;s:62:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\foot.php";i:1747616844;}*/ ?> <?php /*a:5:{s:62:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\program\detail.php";i:1747709473;s:62:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\head.php";i:1747617129;s:71:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\header-simple.php";i:1747705841;s:64:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\footer.php";i:1747617266;s:62:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\foot.php";i:1747616844;}*/ ?>
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
@ -463,7 +463,8 @@
<span class="program-author"><i class="fa fa-user"></i> <span id="programAuthor"></span></span> <span class="program-author"><i class="fa fa-user"></i> <span id="programAuthor"></span></span>
<span class="program-date"><i class="fa fa-calendar"></i> <span id="programDate"></span></span> <span class="program-date"><i class="fa fa-calendar"></i> <span id="programDate"></span></span>
<span class="program-views"><i class="fa-solid fa-eye"></i> <span id="programViews"></span> 浏览</span> <span class="program-views"><i class="fa-solid fa-eye"></i> <span id="programViews"></span> 浏览</span>
<span class="program-downloads"><i class="fa-solid fa-download"></i> <span id="programDownloads"></span> 下载</span> <span class="program-downloads"><i class="fa-solid fa-download"></i> <span id="programDownloads"></span>
下载</span>
</div> </div>
</div> </div>
@ -489,12 +490,16 @@
</div> </div>
</div> </div>
<div class="program-content">
</div>
<div class="program-actions"> <div class="program-actions">
<div class="action-item download-btn" id="downloadBtn"> <div class="action-item download-btn" id="downloadBtn">
<i class="fa fa-download"></i> <i class="fa fa-download"></i>
<span class="action-text">立即下载</span> <span class="action-text">立即下载</span>
</div> </div>
<div class="action-item share-btn"> <div class="action-item share-btn" id="shareBtn">
<i class="fa fa-share-alt"></i> <i class="fa fa-share-alt"></i>
<span class="action-text">分享</span> <span class="action-text">分享</span>
</div> </div>
@ -948,6 +953,8 @@
renderProgramDetail(result.data); renderProgramDetail(result.data);
// 更新访问次数 // 更新访问次数
updateProgramViews(programId); updateProgramViews(programId);
// 初始化分享功能
initShareFunction();
} else { } else {
alert(result.msg || '获取程序详情失败'); alert(result.msg || '获取程序详情失败');
} }
@ -1030,6 +1037,32 @@
console.error('更新访问次数失败:', error); console.error('更新访问次数失败:', error);
}); });
} }
// 初始化分享功能
function initShareFunction() {
const shareBtn = document.getElementById('shareBtn');
if (shareBtn) {
shareBtn.addEventListener('click', function () {
// 获取当前页面URL
const currentUrl = window.location.href;
// 创建临时输入框
const tempInput = document.createElement('input');
tempInput.value = currentUrl;
document.body.appendChild(tempInput);
// 选择并复制文本
tempInput.select();
document.execCommand('copy');
// 移除临时输入框
document.body.removeChild(tempInput);
// 提示用户复制成功
layer.msg('链接已复制到剪贴板');
});
}
}
</script> </script>
</body> </body>