1102 lines
26 KiB
Vue
1102 lines
26 KiB
Vue
<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>
|
||
<cloud-image
|
||
height="64rpx"
|
||
width="64rpx"
|
||
borderRadius="50%"
|
||
:src="data.user_id[0].avatar_file.url"></cloud-image>
|
||
<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>
|
||
|
||
<uni-grid :column="3" :highlight="true" @change="change" :show-border="false">
|
||
<uni-grid-item
|
||
v-for="(item, index) in gridLst"
|
||
:index="index"
|
||
:key="index">
|
||
<view class="grid-item-box" style="background-color: #fff;">
|
||
<uni-icons :type="item.icon" :size="30" :color="item.select_flag?'#e66':'#777'" />
|
||
<text class="text">{{item.value}}</text>
|
||
</view>
|
||
</uni-grid-item>
|
||
</uni-grid>
|
||
|
||
<view class="">
|
||
<text class="date" @click="complaint">投诉</text> | 阅读 {{ data.view_count }}
|
||
|
||
</view>
|
||
<view class="example-body" style="justify-content:center" v-for="(item, index) in cmsArticleLogList" :key="index">
|
||
<cloud-image
|
||
v-if="item1.user_id[0].avatar_file.url"
|
||
height="64rpx"
|
||
width="64rpx"
|
||
borderRadius="50%"
|
||
v-for="(item1, index1) in item"
|
||
:key="index1"
|
||
:src="item1.user_id[0].avatar_file.url"></cloud-image>
|
||
<image
|
||
v-else
|
||
src="https://env-00jxt5y29hrd.normal.cloudstatic.cn/static/static/center/avatar.png?expire_at=1741142218&er_sign=2f723854c2a07dcb5571d2ede5458f7f"
|
||
style="width: 64rpx;height: 64rpx;border-radius: 50%;"></image>
|
||
|
||
</view>
|
||
|
||
<uni-drawer ref="showLeft" mode="left" :width="320" @change="change($event,'showLeft')">
|
||
<view class="close">
|
||
<button @click="closeDrawer('showLeft')"><text class="word-btn-white">关闭Drawer</text></button>
|
||
</view>
|
||
</uni-drawer>
|
||
|
||
<!-- 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 '@/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 {
|
||
gridLst:[
|
||
{
|
||
text: "点赞",
|
||
icon: "heart",
|
||
value: 0,
|
||
select_flag: false
|
||
},
|
||
{
|
||
text: "收藏",
|
||
icon: "folder-add",
|
||
value: 0,
|
||
select_flag: false
|
||
},
|
||
{
|
||
text: "打赏",
|
||
icon: "gift",
|
||
value: 0,
|
||
select_flag: false
|
||
}
|
||
],
|
||
cmsArticleLogList:[],
|
||
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() {
|
||
let uid = this.userInfo._id;
|
||
console.log(uid);
|
||
if (this.id) {
|
||
this.detailLog(this.id, uid);
|
||
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,gift_count,collect_count'
|
||
).getTemp(),
|
||
db.collection(userDBName).field('_id, nickname,avatar_file').getTemp()
|
||
]
|
||
}
|
||
},
|
||
onReady() {
|
||
// 开始加载数据,修改 where 条件后才开始去加载 clinetDB 的数据 ,需要等组件渲染完毕后才开始执行 loadData,所以不能再 onLoad 中执行
|
||
if (this.id) { // ID 不为空,则发起查询
|
||
this.$refs.detail.loadData()
|
||
} else {
|
||
uni.showToast({
|
||
icon: 'none',
|
||
title: 'id 不能为空'
|
||
})
|
||
}
|
||
},
|
||
async onLoad(event) {
|
||
//获取文章id,通常 id 来自上一个页面
|
||
if (event.id) {
|
||
this.id = event.id
|
||
}
|
||
|
||
await this.getArticleInfo();
|
||
await this.getCmsArticleLog(this.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: ''
|
||
})
|
||
}
|
||
},
|
||
async created() {
|
||
|
||
},
|
||
methods: {
|
||
chunkDataIntoGroups(originalArray) {
|
||
|
||
const MAX_PER_GROUP = 7;
|
||
const MAX_TOTAL = 21;
|
||
const result = [];
|
||
|
||
const workingArray = originalArray.slice(0, MAX_TOTAL);
|
||
|
||
for (let i = 0; i < workingArray.length; i += MAX_PER_GROUP) {
|
||
const group = workingArray.slice(i, i + MAX_PER_GROUP);
|
||
result.push(group);
|
||
}
|
||
|
||
return result;
|
||
},
|
||
async getCmsArticleLog(id) {
|
||
try {
|
||
let res = await uniCloud.importObject("article_info").getCmsArticleLog({
|
||
article_id: id
|
||
});
|
||
console.log(res);
|
||
|
||
if (res.code === 200 ) {
|
||
if (res.cmsArticleLog.length > 0 ) {
|
||
this.cmsArticleLogList = this.chunkDataIntoGroups(res.cmsArticleLog);
|
||
}
|
||
console.log(this.cmsArticleLogList);
|
||
|
||
}
|
||
console.log(this.cmsArticleLogList);
|
||
} catch(e) {
|
||
console.log(e.message);
|
||
}
|
||
},
|
||
async getArticleInfo() {
|
||
try {
|
||
let res = await uniCloud.importObject("article_info").getInfo({
|
||
user_id: this.userInfo._id,
|
||
article_id: this.id
|
||
});
|
||
|
||
console.log(res);
|
||
|
||
if (res.code === 200 ) {
|
||
this.gridLst[0].select_flag = res.isLike;
|
||
this.gridLst[1].select_flag = res.isCollect;
|
||
}
|
||
|
||
} catch(e) {
|
||
console.log(e.message);
|
||
}
|
||
},
|
||
async change(e) {
|
||
let index = e.detail.index;
|
||
if (this.gridLst[index].text === "点赞") {
|
||
if (!this.gridLst[index].select_flag) {
|
||
let res = await uniCloud.importObject("cms-articles-like").likeArticle({
|
||
user_id: this.userInfo._id,
|
||
article_id: this.id
|
||
});
|
||
console.log(res);
|
||
this.gridLst[index].value++;
|
||
} else {
|
||
let res = await uniCloud.importObject("cms-articles-like").relikeArticle({
|
||
user_id: this.userInfo._id,
|
||
article_id: this.id
|
||
});
|
||
console.log(res);
|
||
this.gridLst[index].value--;
|
||
}
|
||
|
||
} else if(this.gridLst[index].text === "收藏") {
|
||
if (!this.gridLst[index].select_flag) {
|
||
let res = await uniCloud.importObject("cms-articles-collect").collectArticle({
|
||
user_id: this.userInfo._id,
|
||
article_id: this.id
|
||
});
|
||
console.log(res);
|
||
this.gridLst[index].value++;
|
||
} else {
|
||
let res = await uniCloud.importObject("cms-articles-collect").recollectArticle({
|
||
user_id: this.userInfo._id,
|
||
article_id: this.id
|
||
});
|
||
console.log(res);
|
||
this.gridLst[index].value--;
|
||
}
|
||
} else if (this.gridLst[index].text === "送礼") {
|
||
console.log("点击了送礼");
|
||
}
|
||
|
||
this.gridLst[index].select_flag = !this.gridLst[index].select_flag;
|
||
|
||
|
||
},
|
||
async detailLog(id, uid) {
|
||
console.log(uid);
|
||
let res = await uniCloud.importObject("uni-cms-articles").detailLog({
|
||
articleId: id,
|
||
userId: uid,
|
||
});
|
||
},
|
||
|
||
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) {
|
||
console.log(data);
|
||
this.gridLst[0].value = data.like_count;
|
||
this.gridLst[1].value = data.collect_count
|
||
this.gridLst[2].value = data.gift_count
|
||
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
|
||
);
|
||
console.log(this.commentData);
|
||
console.log(index);
|
||
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(item) {
|
||
try {
|
||
// 1. 操作防抖与权限预校验
|
||
if (this.reqFlag) {
|
||
uni.showToast({
|
||
title: '操作受限',
|
||
icon: 'none'
|
||
});
|
||
return;
|
||
}
|
||
console.log(item);
|
||
|
||
this.reqFlag = true;
|
||
|
||
uni.hideToast();
|
||
|
||
// 2. 双重加载态管理
|
||
uni.showLoading({
|
||
title: '安全检查中...',
|
||
mask: true
|
||
});
|
||
|
||
// 3. 带权限校验的二次确认
|
||
const {
|
||
confirm
|
||
} = await uni.showModal({
|
||
title: '删除确认',
|
||
content: '确定删除这条评论?删除后不可恢复',
|
||
confirmText: '确认删除',
|
||
confirmColor: '#dd514d'
|
||
});
|
||
|
||
if (!confirm) {
|
||
this._resetOperationState();
|
||
return;
|
||
}
|
||
|
||
|
||
let commentId = item.id;
|
||
|
||
// // 4. 更新加载状态(网页1)
|
||
uni.showLoading({
|
||
title: '数据删除中...',
|
||
mask: true
|
||
});
|
||
|
||
// // 5. 带重试机制的请求(网页4扩展)
|
||
// 调用云对象方法
|
||
const commentObj = uniCloud.importObject("comments");
|
||
const res = await commentObj.deleteComment(commentId, item.root_id);
|
||
|
||
|
||
console.log(res);
|
||
|
||
console.log(this.commentData.comment);
|
||
|
||
if (item.root_id === 0) {
|
||
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
|
||
});
|
||
} else {
|
||
const index = this.commentData.comment.findIndex(
|
||
i => i._id === item.root_id
|
||
);
|
||
if (index !== -1) {
|
||
let comment = this.commentData.comment[index].children;
|
||
const index2 = comment.findIndex(
|
||
i => i._id === item.root_id
|
||
);
|
||
this.commentData.comment[index].children.splice(index2, 1);
|
||
uni.showLoading({
|
||
title: '删除成功',
|
||
mask: true
|
||
});
|
||
}
|
||
}
|
||
|
||
|
||
|
||
} catch (error) {
|
||
this._handleDeleteError(error);
|
||
|
||
this.$refs.commentList?.refresh();
|
||
|
||
} finally {
|
||
this._resetOperationState();
|
||
}
|
||
},
|
||
_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();
|
||
}
|
||
|
||
.image {
|
||
width: 25px;
|
||
height: 25px;
|
||
}
|
||
|
||
.text {
|
||
font-size: 14px;
|
||
margin-top: 5px;
|
||
}
|
||
|
||
.example-body {
|
||
/* #ifndef APP-NVUE */
|
||
// display: block;
|
||
/* #endif */
|
||
}
|
||
|
||
.grid-dynamic-box {
|
||
margin-bottom: 15px;
|
||
}
|
||
|
||
.grid-item-box {
|
||
flex: 1;
|
||
// position: relative;
|
||
/* #ifndef APP-NVUE */
|
||
display: flex;
|
||
/* #endif */
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 15px 0;
|
||
}
|
||
|
||
.grid-item-box-row {
|
||
flex: 1;
|
||
// position: relative;
|
||
/* #ifndef APP-NVUE */
|
||
display: flex;
|
||
/* #endif */
|
||
flex-direction: row;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 15px 0;
|
||
}
|
||
|
||
.grid-dot {
|
||
position: absolute;
|
||
top: 5px;
|
||
right: 15px;
|
||
}
|
||
|
||
.swiper {
|
||
height: 420px;
|
||
}
|
||
|
||
</style> |