869 lines
26 KiB
Plaintext
869 lines
26 KiB
Plaintext
<template>
|
||
<view class="">
|
||
<unicloud-db v-slot:default="{data, loading, error, options}" :collection="collection" :options="formData"
|
||
:getone="true" :where="where" :manual="true" ref="detail" foreignKey="uni-cms-articles.user_id"
|
||
@load="loadData"
|
||
class="article">
|
||
<template v-if="!loading && data">
|
||
<view class="meta">
|
||
<view class="title">
|
||
<text class="text">{{ data.title }}</text>
|
||
</view>
|
||
<view class="excerpt">
|
||
<text class="text">{{ data.excerpt }}</text>
|
||
</view>
|
||
<view class="author">
|
||
<template v-if="data.user_id[0]">
|
||
<text class="at">{{ data.user_id[0].nickname || '' }}</text>
|
||
<text class="split">·</text>
|
||
</template>
|
||
<text class="date">{{ publishTime( data.publish_date) }}</text>
|
||
</view>
|
||
</view>
|
||
<render-article-detail
|
||
:content="data.content"
|
||
:content-images="data.content_images"
|
||
:ad-config="{ adpId, watchAdUniqueType }"
|
||
></render-article-detail>
|
||
|
||
<!-- <view class="" style="font-size: 20rpx;color: #999;margin-left: 50rpx;margin-top: 20rpx;">
|
||
更新于 2024-12-26 {{ publishTime(data.last_modify_date) }}
|
||
</view> -->
|
||
|
||
</template>
|
||
<view class="detail-loading" v-else>
|
||
<uni-icons type="spinner-cycle" size="35px"/>
|
||
</view>
|
||
|
||
|
||
|
||
<view class="example-body">
|
||
<button>
|
||
<svg t="1739442625419" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1476" width="16" height="16"><path d="M109.226667 798.72c-20.48 0-35.84 17.066667-35.84 37.546667 0 20.48 17.066667 35.84 37.546666 35.84 3.413333 0 157.013333 1.706667 252.586667 107.52 6.826667 8.533333 17.066667 11.946667 27.306667 11.946666 8.533333 0 17.066667-3.413333 23.893333-10.24 15.36-13.653333 17.066667-35.84 3.413333-51.2-119.466667-131.413333-302.08-131.413333-308.906666-131.413333zM914.773333 798.72c-6.826667 0-186.026667 0-307.2 131.413333-13.653333 15.36-13.653333 37.546667 1.706667 51.2 6.826667 6.826667 15.36 10.24 25.6 10.24s20.48-3.413333 27.306667-11.946666c98.986667-107.52 250.88-107.52 252.586666-107.52 20.48 0 35.84-15.36 37.546667-35.84 0-20.48-17.066667-37.546667-37.546667-37.546667z" fill="#d81e06" p-id="1477"></path><path d="M877.226667 600.746667c78.506667-133.12 97.28-307.2 44.373333-431.786667-5.12-13.653333-18.773333-22.186667-32.426667-22.186667h-11.946666c-71.68 0-138.24 13.653333-197.973334 40.96-42.666667-80.213333-90.453333-138.24-145.066666-177.493333-1.706667-1.706667-3.413333-3.413333-5.12-3.413333-10.24-6.826667-23.893333-6.826667-34.133334-3.413334-3.413333 1.706667-6.826667 3.413333-10.24 6.826667-54.613333 39.253333-102.4 98.986667-145.066666 177.493333-59.733333-25.6-124.586667-39.253333-194.56-39.253333h-10.24c-15.36-1.706667-27.306667 8.533333-34.133334 20.48-51.2 124.586667-34.133333 296.96 44.373334 431.786667 68.266667 116.053333 172.373333 187.733333 296.96 203.093333 3.413333 1.706667 6.826667 1.706667 10.24 1.706667h20.48v180.906666c0 20.48 17.066667 37.546667 37.546666 37.546667 20.48 0 37.546667-17.066667 37.546667-37.546667V805.546667h22.186667c3.413333 0 6.826667 0 10.24-1.706667 124.586667-15.36 228.693333-87.04 296.96-203.093333z" fill="#d81e06" p-id="1478"></path></svg>
|
||
送花
|
||
</button>
|
||
<button>
|
||
<uni-icons
|
||
type="gift"
|
||
size="16">
|
||
|
||
</uni-icons>
|
||
打赏
|
||
</button>
|
||
|
||
</view>
|
||
<view class=""
|
||
style="text-align: center;
|
||
color:3ee;
|
||
margin-top: 20rpx;
|
||
padding-bottom: 50rpx;
|
||
color: #555;
|
||
">
|
||
———<text style="color: #3ee;">{{ " " }}4 朵花{{ " " }}</text>———
|
||
</view>
|
||
<view class="">
|
||
<text class="date" @click="complaint">投诉</text> | 阅读 {{ data.view_count }}
|
||
|
||
</view>
|
||
<view class="example-body" style="justify-content:center">
|
||
<image src="https://qnycdn.mymoyu.top/static/avatar.jpg" style="width: 64rpx;height: 64rpx;border-radius: 50%;"></image>
|
||
<image src="https://qnycdn.mymoyu.top/static/avatar.jpg" style="width: 64rpx;height: 64rpx;border-radius: 50%;"></image>
|
||
<image src="https://qnycdn.mymoyu.top/static/avatar.jpg" style="width: 64rpx;height: 64rpx;border-radius: 50%;"></image>
|
||
<image src="https://qnycdn.mymoyu.top/static/avatar.jpg" style="width: 64rpx;height: 64rpx;border-radius: 50%;"></image>
|
||
<image src="https://qnycdn.mymoyu.top/static/avatar.jpg" style="width: 64rpx;height: 64rpx;border-radius: 50%;"></image>
|
||
<image src="https://qnycdn.mymoyu.top/static/avatar.jpg" style="width: 64rpx;height: 64rpx;border-radius: 50%;"></image>
|
||
<image src="https://qnycdn.mymoyu.top/static/avatar.jpg" style="width: 64rpx;height: 64rpx;border-radius: 50%;"></image>
|
||
</view>
|
||
<view class="example-body" style="justify-content:center">
|
||
<image src="https://qnycdn.mymoyu.top/static/avatar.jpg" style="width: 64rpx;height: 64rpx;border-radius: 50%;"></image>
|
||
<image src="https://qnycdn.mymoyu.top/static/avatar.jpg" style="width: 64rpx;height: 64rpx;border-radius: 50%;"></image>
|
||
<image src="https://qnycdn.mymoyu.top/static/avatar.jpg" style="width: 64rpx;height: 64rpx;border-radius: 50%;"></image>
|
||
<image src="https://qnycdn.mymoyu.top/static/avatar.jpg" style="width: 64rpx;height: 64rpx;border-radius: 50%;"></image>
|
||
<image src="https://qnycdn.mymoyu.top/static/avatar.jpg" style="width: 64rpx;height: 64rpx;border-radius: 50%;"></image>
|
||
<image src="https://qnycdn.mymoyu.top/static/avatar.jpg" style="width: 64rpx;height: 64rpx;border-radius: 50%;"></image>
|
||
<image src="https://qnycdn.mymoyu.top/static/avatar.jpg" style="width: 64rpx;height: 64rpx;border-radius: 50%;"></image>
|
||
</view>
|
||
<view class="example-body" style="justify-content:center">
|
||
<image src="https://qnycdn.mymoyu.top/static/avatar.jpg" style="width: 64rpx;height: 64rpx;border-radius: 50%;"></image>
|
||
<image src="https://qnycdn.mymoyu.top/static/avatar.jpg" style="width: 64rpx;height: 64rpx;border-radius: 50%;"></image>
|
||
<image src="https://qnycdn.mymoyu.top/static/avatar.jpg" style="width: 64rpx;height: 64rpx;border-radius: 50%;"></image>
|
||
<image src="https://qnycdn.mymoyu.top/static/avatar.jpg" style="width: 64rpx;height: 64rpx;border-radius: 50%;"></image>
|
||
<image src="https://qnycdn.mymoyu.top/static/avatar.jpg" style="width: 64rpx;height: 64rpx;border-radius: 50%;"></image>
|
||
<image src="https://qnycdn.mymoyu.top/static/avatar.jpg" style="width: 64rpx;height: 64rpx;border-radius: 50%;"></image>
|
||
<image src="https://qnycdn.mymoyu.top/static/avatar.jpg" style="width: 64rpx;height: 64rpx;border-radius: 50%;"></image>
|
||
</view>
|
||
<!-- comment_count -->
|
||
<view class="comment-eg">
|
||
<hb-comment
|
||
ref="hbComment"
|
||
@add="add"
|
||
@del="del"
|
||
@like="like"
|
||
@relike="relike"
|
||
@focusOn="focusOn"
|
||
@replyAdd = "replyAdd"
|
||
@getTreeComment="getTreeComment"
|
||
:deleteTip="'确认删除?'"
|
||
:cmData="commentData"
|
||
:articlesData="data"
|
||
v-if="commentData">
|
||
</hb-comment>
|
||
</view>
|
||
</unicloud-db>
|
||
|
||
|
||
|
||
</view>
|
||
|
||
</template>
|
||
|
||
<script>
|
||
import uniNavBar from '@/uni_modules/uni-nav-bar/components/uni-nav-bar/uni-nav-bar.vue';
|
||
import renderArticleDetail from "@/uni_modules/uni-cms-article/components/render-article-detail/index.vue";
|
||
import translatePublishTime from "@/uni_modules/uni-cms-article/common/publish-time";
|
||
|
||
const uniIdCo = uniCloud.importObject("uni-id-co")
|
||
import {
|
||
store,
|
||
mutations
|
||
} from '@/pages3/uni_modules/uni-id-pages/common/store.js'
|
||
|
||
|
||
const db = uniCloud.database()
|
||
const articleDBName = 'uni-cms-articles'
|
||
const userDBName = 'uni-id-users'
|
||
|
||
export default {
|
||
components: {
|
||
uniNavBar,
|
||
renderArticleDetail
|
||
},
|
||
data() {
|
||
return {
|
||
templateSrc:"https://env-00jxt5y29hrd.normal.cloudstatic.cn/static/bg.jpg?expire_at=1741101988&er_sign=c9732cddaaead925cf110d9a11751231",
|
||
"commentData": null,
|
||
"reqFlag": false,
|
||
id: "", // 文章ID
|
||
title: "", // 文章标题
|
||
formData: {}, // 表单数据
|
||
|
||
// 广告相关配置
|
||
adpId: "", // TODO: 请填写广告位ID
|
||
watchAdUniqueType: "device" // TODO: 观看广告的唯一标识类型,可选值为 user 或者 device,user 表示用户唯一,device 表示设备唯一
|
||
}
|
||
},
|
||
onShow() {
|
||
|
||
this.getComment();
|
||
},
|
||
computed: {
|
||
userInfo() {
|
||
return store.userInfo
|
||
},
|
||
realNameStatus () {
|
||
if (!this.userInfo.realNameAuth) {
|
||
return 0
|
||
}
|
||
|
||
return this.userInfo.realNameAuth.authStatus
|
||
},
|
||
where() {
|
||
//拼接where条件 查询条件 ,更多详见 :https://uniapp.dcloud.net.cn/uniCloud/unicloud-db?id=jsquery
|
||
return `_id =="${this.id}"`
|
||
},
|
||
collection() {
|
||
return [
|
||
db.collection(articleDBName).where(this.where).field('user_id,thumbnail,excerpt,publish_date,title,content,last_modify_date,view_count,_id,comment_count,like_count,last_modify_ip,_id').getTemp(),
|
||
db.collection(userDBName).field('_id, nickname').getTemp()
|
||
]
|
||
}
|
||
},
|
||
onReady() {
|
||
// 开始加载数据,修改 where 条件后才开始去加载 clinetDB 的数据 ,需要等组件渲染完毕后才开始执行 loadData,所以不能再 onLoad 中执行
|
||
if (this.id) {
|
||
this.$refs.detail.loadData()
|
||
} else {
|
||
uni.showToast({
|
||
icon: 'none',
|
||
title: 'id 不能为空'
|
||
})
|
||
}
|
||
},
|
||
onLoad(event) {
|
||
//获取文章id,通常 id 来自上一个页面
|
||
if (event.id) {
|
||
this.id = event.id
|
||
}
|
||
|
||
// 监听解锁内容事件
|
||
uni.$on('onUnlockContent', this.onUnlockContent)
|
||
},
|
||
onUnload() {
|
||
// 页面卸载时,移除监听事件
|
||
uni.$off('onUnlockContent', this.onUnlockContent)
|
||
},
|
||
onPageScroll(e) {
|
||
// 根据滚动位置判断是否显示导航栏
|
||
if (e.scrollTop > 100) {
|
||
uni.setNavigationBarTitle({
|
||
title: this.title
|
||
})
|
||
} else {
|
||
uni.setNavigationBarTitle({
|
||
title: ''
|
||
})
|
||
}
|
||
},
|
||
methods: {
|
||
// 将时间戳转换为可读的时间格式
|
||
publishTime(timestamp) {
|
||
return translatePublishTime(timestamp)
|
||
},
|
||
// 将文章加入阅读历史
|
||
setReadHistory() {
|
||
// 获取阅读历史缓存,如果不存在则为空数组
|
||
const historyCache = uni.getStorageSync('readHistory') || []
|
||
// 过滤掉当前文章的阅读历史
|
||
const readHistory = historyCache.filter(item => item.article_id !== this.id)
|
||
// 将当前文章的阅读历史添加到数组最前面
|
||
readHistory.unshift({
|
||
article_id: this.id,
|
||
last_time: Date.now()
|
||
})
|
||
// 将更新后的阅读历史缓存到本地
|
||
uni.setStorageSync('readHistory', readHistory)
|
||
|
||
},
|
||
// 加载数据
|
||
loadData(data) {
|
||
// 设置文章标题
|
||
this.title = data.title
|
||
|
||
// 将文章添加进阅读历史
|
||
this.setReadHistory()
|
||
},
|
||
// 监听解锁内容事件,解锁内容后重新加载数据
|
||
async onUnlockContent() {
|
||
this.$refs.detail.loadData()
|
||
},
|
||
// 登录校验
|
||
|
||
check() {
|
||
const token = uni.getStorageSync('uni_id_token');
|
||
const tokenExpired = uni.getStorageSync('uni_id_token_expired');
|
||
const now = Date.now();
|
||
|
||
// 检查 Token 存在性 + 有效期
|
||
if (token && now < tokenExpired) {
|
||
return true;
|
||
} else if (token && now >= tokenExpired) {
|
||
uni.showToast({ title: '登录已过期', icon: 'none' });
|
||
this.clearLoginState(); // 清理过期凭证
|
||
return false;
|
||
}
|
||
},
|
||
checkLogin() {
|
||
// 防抖处理(防止连续触发)
|
||
if (this._lastCheckTime && Date.now() - this._lastCheckTime < 1500) return false;
|
||
this._lastCheckTime = Date.now();
|
||
|
||
try {
|
||
// 增强校验逻辑(结合本地存储和服务端验证)
|
||
const token = uni.getStorageSync('uni_id_token');
|
||
const isLogin = !!token && this.verifyTokenExpiration(token);
|
||
|
||
if (isLogin) return true;
|
||
|
||
// 优化提示交互(带图标和动画)
|
||
uni.showModal({
|
||
title: '?? 登录提示',
|
||
content: '体验完整功能需要先登录哦~',
|
||
confirmText: '立即登录',
|
||
cancelText: '稍后再说',
|
||
confirmColor: '#007AFF',
|
||
animationType: 'slide-in-bottom',
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
uni.navigateTo({
|
||
url: "/pages/login/login"
|
||
})
|
||
}
|
||
}
|
||
});
|
||
return false;
|
||
} catch (error) {
|
||
uni.showToast({
|
||
title: '登录状态异常,请重新登录',
|
||
icon: 'error'
|
||
});
|
||
this.clearInvalidSession();
|
||
return false;
|
||
}
|
||
},
|
||
|
||
// 新增 Token 校验方法
|
||
verifyTokenExpiration(token) {
|
||
return true;
|
||
},
|
||
|
||
// 新增会话清理
|
||
clearInvalidSession() {
|
||
uni.removeStorageSync('uni_id_token');
|
||
},
|
||
// 输入框聚焦
|
||
focusOn() {
|
||
this.checkLogin();
|
||
},
|
||
async getTreeComment(root_id) {
|
||
try{
|
||
let query = { root_id: root_id };
|
||
const res = await uniCloud.importObject("comments").getReplyComment(query);
|
||
console.log(res.data.commentList)
|
||
const index = this.commentData.comment.findIndex(
|
||
item => item._id === root_id
|
||
)
|
||
console.log(1, this.commentData, index)
|
||
if (index !== -1) {
|
||
console.log(this.commentData.comment);
|
||
this.commentData.comment[index].children= [...this.commentData.comment[index].children, ...res.data.commentList];
|
||
this.commentData.comment[index].replyCount -= res.data.commentList.length;
|
||
}
|
||
|
||
} catch (error) {
|
||
console.error('获取评论失败:', error);
|
||
// 设置默认值或提示用户
|
||
this.commentData = {
|
||
readNumer: 0,
|
||
commentSize: 0,
|
||
comment: []
|
||
};
|
||
uni.showToast({
|
||
title: '评论加载失败,请重试',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
|
||
},
|
||
async getComment() {
|
||
try {
|
||
console.log(this.id);
|
||
console.log('开始获取评论');
|
||
let query = { article_id: this.id };
|
||
const res = await uniCloud.importObject("comments").getComments(query);
|
||
|
||
const readNumer_res = await uniCloud.importObject("comments").getReadCount(query);
|
||
|
||
// 处理正常响应
|
||
this.commentData = {
|
||
readNumer: readNumer_res.data.view_count,
|
||
commentSize: res.data.commentList.length,
|
||
comment: res.data.commentList
|
||
};
|
||
} catch (error) {
|
||
console.error('获取评论失败:', error);
|
||
// 设置默认值或提示用户
|
||
this.commentData = {
|
||
readNumer: 0,
|
||
commentSize: 0,
|
||
comment: []
|
||
};
|
||
uni.showToast({
|
||
title: '评论加载失败,请重试',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
},
|
||
// 新增评论
|
||
async add(content) {
|
||
try {
|
||
// 获取当前用户信息(需确保已登录)
|
||
const uniIdToken = uni.getStorageSync('uni_id_token');
|
||
if (!uniIdToken) {
|
||
uni.showToast({ title: '请先登录', icon: 'none' });
|
||
return;
|
||
}
|
||
console.log(this.id);
|
||
// 构建符合后端接口规范的评论对象
|
||
const comment = {
|
||
article_id: this.id,
|
||
content: content,
|
||
parent_id: 0,
|
||
};
|
||
|
||
// 调用云对象方法
|
||
const commentObj = uniCloud.importObject("comments");
|
||
const res = await commentObj.addComment(comment);
|
||
|
||
// 处理响应结果
|
||
if (res.code === 200) {
|
||
uni.showToast({ title: '评论成功' });
|
||
this.commentData.comment.splice(0, 0, res.data);
|
||
this.commentData.commentSize++;
|
||
// 更新前端显示(示例)
|
||
// this.$refs.commentList.unshift({
|
||
// _id: res.data.comment_id,
|
||
// content: comment.content,
|
||
// create_time: new Date().toISOString(),
|
||
// depth: res.data.depth,
|
||
// reply_count: 0
|
||
// });
|
||
}
|
||
} catch (e) {
|
||
console.error('评论失败:', e);
|
||
|
||
// 错误分类处理(根据后端错误码映射)
|
||
const errorHandler = {
|
||
'PERMISSION_DENIED': '登录状态失效,请重新登录',
|
||
'INVALID_PARAMS': '评论内容不能为空',
|
||
'CONTENT_BLOCKED': '包含违禁词汇: ' + e.message.split(':')[1],
|
||
'PARENT_COMMENT_NOT_FOUND': '回复的评论不存在'
|
||
};
|
||
|
||
uni.showToast({
|
||
title: errorHandler[e.errorType] || '评论失败,请稍后重试',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
},
|
||
|
||
// 点赞评论
|
||
// 修改后的点赞方法(带防抖和状态反馈)
|
||
async like(comment) {
|
||
if (!this.checkLogin()) {
|
||
return;
|
||
}
|
||
|
||
// 防抖处理(500ms间隔)
|
||
if (this._lastClickTime && Date.now() - this._lastClickTime < 500) {
|
||
uni.vibrateShort(); // 触觉反馈[2](@ref)
|
||
return;
|
||
}
|
||
this._lastClickTime = Date.now();
|
||
|
||
try {
|
||
// 显示加载状态
|
||
let commentId = comment._id;
|
||
let userInfo = uniCloud.getCurrentUserInfo();
|
||
console.log(userInfo);
|
||
let uid = userInfo.uid;
|
||
|
||
const commentObj = uniCloud.importObject("comments");
|
||
const res = await commentObj.likeComment(uid, commentId);
|
||
|
||
// 更新UI状态(带动画效果)
|
||
this.$refs.hbComment.likeComplete(comment);
|
||
|
||
// 视觉反馈
|
||
} catch (error) {
|
||
console.error(error);
|
||
// 错误处理
|
||
uni.showToast({
|
||
title: error.message || '操作失败',
|
||
icon: 'error'
|
||
});
|
||
} finally {
|
||
this.reqFlag = false;
|
||
}
|
||
},
|
||
async relike(comment) {
|
||
if (!this.checkLogin()) {
|
||
return;
|
||
}
|
||
|
||
// 防抖处理(500ms间隔)
|
||
if (this._lastClickTime && Date.now() - this._lastClickTime < 500) {
|
||
uni.vibrateShort(); // 触觉反馈[2](@ref)
|
||
return;
|
||
}
|
||
this._lastClickTime = Date.now();
|
||
|
||
try {
|
||
// 显示加载状态
|
||
let commentId = comment._id;
|
||
let userInfo = uniCloud.getCurrentUserInfo();
|
||
console.log(userInfo);
|
||
let uid = userInfo.uid;
|
||
|
||
const commentObj = uniCloud.importObject("comments");
|
||
const res = await commentObj.relikeComment(uid, commentId);
|
||
|
||
// 更新UI状态(带动画效果)
|
||
this.$refs.hbComment.likeComplete(comment);
|
||
|
||
// 视觉反馈
|
||
|
||
|
||
} catch (error) {
|
||
console.error(error);
|
||
// 错误处理
|
||
uni.showToast({
|
||
title: error.message || '操作失败',
|
||
icon: 'error'
|
||
});
|
||
|
||
} finally {
|
||
this.reqFlag = false;
|
||
}
|
||
},
|
||
async replyAdd(commentReq) {
|
||
try{
|
||
let content = commentReq.content;
|
||
|
||
// 获取当前用户信息(需确保已登录)
|
||
const uniIdToken = uni.getStorageSync('uni_id_token');
|
||
if (!uniIdToken) {
|
||
uni.showToast({ title: '请先登录', icon: 'none' });
|
||
return;
|
||
}
|
||
// return;
|
||
// 构建符合后端接口规范的评论对象
|
||
|
||
const comment = {
|
||
article_id: this.id,
|
||
root_id: commentReq.root_id,
|
||
content: commentReq.content,
|
||
parent_id: commentReq.pId
|
||
};
|
||
console.log(comment)
|
||
// 调用云对象方法
|
||
const commentObj = uniCloud.importObject("comments");
|
||
const res = await commentObj.replyComment(comment);
|
||
|
||
// 处理响应结果
|
||
if (res.code === 200) {
|
||
uni.showToast({ title: '评论成功' });
|
||
// this.commentData.comment.splice(0, 0, res.data);
|
||
const index = this.commentData.comment.findIndex(
|
||
item => item._id === commentReq.root_id
|
||
);
|
||
if (index !== -1) {
|
||
this.commentData.comment[index].children.splice(0,0, res.data)
|
||
this.commentData.commentSize++;
|
||
}
|
||
console.log(this.commentData.comment);
|
||
// 更新前端显示(示例)
|
||
// this.$refs.commentList.unshift({
|
||
// _id: res.data.comment_id,
|
||
// content: comment.content,
|
||
// create_time: new Date().toISOString(),
|
||
// depth: res.data.depth,
|
||
// reply_count: 0
|
||
// });
|
||
}
|
||
} catch (e) {
|
||
console.error('评论失败:', e);
|
||
|
||
// 错误分类处理(根据后端错误码映射)
|
||
const errorHandler = {
|
||
'PERMISSION_DENIED': '登录状态失效,请重新登录',
|
||
'INVALID_PARAMS': '评论内容不能为空',
|
||
'CONTENT_BLOCKED': '包含违禁词汇: ' + e.message.split(':')[1],
|
||
'PARENT_COMMENT_NOT_FOUND': '回复的评论不存在'
|
||
};
|
||
|
||
uni.showToast({
|
||
title: errorHandler[e.errorType] || '评论失败,请稍后重试',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
},
|
||
// 删除评论
|
||
async del(commentId) {
|
||
try {
|
||
// 1. 操作防抖与权限预校验(网页4/6)
|
||
if (this.reqFlag ) {
|
||
uni.showToast({ title: '操作受限', icon: 'none' });
|
||
return;
|
||
}
|
||
this.reqFlag = true;
|
||
|
||
uni.hideToast();
|
||
|
||
// 2. 双重加载态管理(网页1/4)
|
||
uni.showLoading({ title: '安全检查中...', mask: true });
|
||
|
||
// 3. 带权限校验的二次确认(网页6)
|
||
const { confirm } = await uni.showModal({
|
||
title: '删除确认',
|
||
content: '确定删除这条评论?删除后不可恢复',
|
||
confirmText: '确认删除',
|
||
confirmColor: '#dd514d'
|
||
});
|
||
|
||
if (!confirm) {
|
||
this._resetOperationState();
|
||
return;
|
||
}
|
||
|
||
// // 4. 更新加载状态(网页1)
|
||
uni.showLoading({ title: '数据删除中...', mask: true });
|
||
|
||
// // 5. 带重试机制的请求(网页4扩展)
|
||
// 调用云对象方法
|
||
const commentObj = uniCloud.importObject("comments");
|
||
const res = await commentObj.deleteComment(commentId);
|
||
|
||
|
||
console.log(res);
|
||
|
||
// // 6. 数据更新与事件通知(网页1/5)
|
||
// this._updateLocalData(commentId, res.data);
|
||
// uni.$emit('comment-state-changed', {
|
||
// type: 'delete',
|
||
// commentId,
|
||
// articleId: res.data?.article_id
|
||
// });
|
||
|
||
// // 7. 操作反馈(网页5)
|
||
console.log(this.commentData.comment);
|
||
const index = this.commentData.comment.findIndex(
|
||
item => item._id === commentId
|
||
);
|
||
if (index !== -1) {
|
||
this.commentData.comment.splice(index, 1);
|
||
}
|
||
this.commentData.commentSize --;
|
||
uni.showLoading({ title: '发布成功', mask: true });
|
||
|
||
} catch (error) {
|
||
// 8. 错误分级处理(网页4/6)
|
||
this._handleDeleteError(error);
|
||
|
||
// 9. 失败时数据回滚
|
||
this.$refs.commentList?.refresh();
|
||
|
||
} finally {
|
||
// 10. 安全状态重置(网页4)
|
||
this._resetOperationState();
|
||
}
|
||
},
|
||
// 权限校验(网页6)
|
||
|
||
// 本地数据更新(网页1)
|
||
_updateLocalData(commentId, serverData) {
|
||
this.$store.commit('comments/REMOVE', commentId);
|
||
this.$store.commit('articles/UPDATE_STATS', {
|
||
id: serverData.article_id,
|
||
type: 'comment',
|
||
value: -1
|
||
});
|
||
},
|
||
|
||
// 错误处理(网页4/6)
|
||
_handleDeleteError(error) {
|
||
const errorConfig = {
|
||
'PERMISSION_DENIED': { title: '操作权限不足', icon: 'none' },
|
||
'COMMENT_NOT_FOUND': { title: '内容已删除', icon: 'none' },
|
||
'NETWORK_ERROR': { title: '网络不稳定', icon: 'none' },
|
||
'default': { title: error.errMsg || '操作失败', icon: 'none' }
|
||
};
|
||
console.log(error);
|
||
uni.showToast(errorConfig[error.code] || errorConfig.default);
|
||
},
|
||
|
||
// 状态重置(网页4)
|
||
_resetOperationState() {
|
||
try { uni.hideLoading(); } catch(e) {}
|
||
this.reqFlag = false;
|
||
},
|
||
// 列表按照父子转换成树
|
||
getTree(data) {
|
||
let result = [];
|
||
let map = {};
|
||
data.forEach(item => {
|
||
map[item.id] = item;
|
||
});
|
||
data.forEach(item => {
|
||
let parent = map[item.parentId];
|
||
if (parent) {
|
||
(parent.children || (parent.children = [])).push(item);
|
||
} else {
|
||
result.push(item);
|
||
}
|
||
});
|
||
return result;
|
||
},
|
||
complaint() {
|
||
|
||
}
|
||
}
|
||
|
||
}
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
/* #ifdef APP-NVUE */
|
||
.article {
|
||
background-color: #fff;
|
||
}
|
||
|
||
/* #endif */
|
||
|
||
@mixin cp {
|
||
padding: 0 30rpx;
|
||
}
|
||
|
||
.detail-loading {
|
||
margin: 100rpx auto 0;
|
||
width: 35px;
|
||
height: 35px;
|
||
animation: rotate360 2s linear infinite;
|
||
}
|
||
|
||
@keyframes rotate360 {
|
||
0% {
|
||
transform: rotate(0deg);
|
||
transform-origin: center center;
|
||
}
|
||
|
||
100% {
|
||
transform: rotate(360deg);
|
||
transform-origin: center center;
|
||
}
|
||
}
|
||
|
||
.meta {
|
||
@include cp;
|
||
position: relative;
|
||
z-index: 1;
|
||
padding-top: 20rpx;
|
||
.title {
|
||
.text {
|
||
font-size: 40rpx;
|
||
line-height: 66rpx;
|
||
font-weight: bold;
|
||
color: #333;
|
||
}
|
||
}
|
||
|
||
.excerpt {
|
||
margin-top: 10rpx;
|
||
.text {
|
||
font-size: 26rpx;
|
||
line-height: 40rpx;
|
||
color: #999;
|
||
}
|
||
}
|
||
|
||
.author {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: flex-start;
|
||
flex-direction: row;
|
||
margin-top: 20rpx;
|
||
|
||
.at,
|
||
.split,
|
||
.date {
|
||
font-size: 26rpx;
|
||
color: #ccc;
|
||
}
|
||
|
||
.split {
|
||
margin: 0 10rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
.example-body {
|
||
/* #ifndef APP-PLUS-NVUE */
|
||
display: flex;
|
||
/* #endif */
|
||
flex-direction: row;
|
||
justify-content: flex-start;
|
||
/* align-items: flex-end; */
|
||
/* flex-wrap: wrap; */
|
||
padding: 10rpx;
|
||
}
|
||
.btn {
|
||
text-align: center;
|
||
color: #fff;
|
||
padding: 20rpx;
|
||
margin: 20rpx;
|
||
border-radius: 20rpx;
|
||
background-color: #2979ff;
|
||
}
|
||
.tab {
|
||
text-indent: 2rem;
|
||
}
|
||
.v-preview {
|
||
.img {
|
||
width: 100%;
|
||
}
|
||
.btn-area {
|
||
position: relative;
|
||
top: -50rpx;
|
||
}
|
||
.red-btn-area {
|
||
display: flex;
|
||
justify-content: center;
|
||
padding: 10rpx 0;
|
||
margin: 0 40rpx 20rpx 40rpx;
|
||
font-size: 20rpx;
|
||
.red-btn {
|
||
position: relative;
|
||
color: #fff;
|
||
font-weight: 700;
|
||
font-size: 24rpx;
|
||
height: 40rpx;
|
||
line-height: 40rpx;
|
||
margin: 0;
|
||
background-image: linear-gradient(to bottom, #c11c1f, #5c0201);
|
||
+ .red-btn {
|
||
margin-left: 20rpx;
|
||
}
|
||
}
|
||
}
|
||
.red-btn-plain-area {
|
||
display: flex;
|
||
justify-content: center;
|
||
padding: 10rpx 0;
|
||
margin: 0 40rpx;
|
||
font-size: 21rpx;
|
||
border-top: 2px solid;
|
||
border-bottom: 2px solid;
|
||
border-image: linear-gradient(
|
||
to right,
|
||
#fff,
|
||
#f44336bf,
|
||
#b13636,
|
||
#f44336bf,
|
||
#fff
|
||
)
|
||
1;
|
||
.red-btn-plain {
|
||
position: relative;
|
||
color: #b13636;
|
||
font-weight: 700;
|
||
padding-left: 15rpx;
|
||
+ .red-btn-plain {
|
||
margin-left: 10rpx;
|
||
&::before {
|
||
// border-left: 2px solid #f44336;
|
||
content: "";
|
||
position: absolute;
|
||
left: 0;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
width: 2px;
|
||
height: 20rpx;
|
||
background-color: #b13636;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.game_content .person_info:nth-child(1) .person_detail .user_avatar_box .rank_box{
|
||
background-image: url();
|
||
}
|
||
|
||
.game_content .person_info:nth-child(2) .person_detail .user_avatar_box .rank_box{
|
||
background-image: url();
|
||
}
|
||
|
||
.game_content .person_info:nth-child(3) .person_detail .user_avatar_box .rank_box{
|
||
background-image: url();
|
||
}
|
||
</style>
|