case-data/pages/detail/detail.vue
zoujiandong db955ff4f3 6.9
2025-06-09 08:38:59 +08:00

1519 lines
39 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<z-paging
ref="paging"
inside-more
loading-more-no-more-text="咱也是有底线的"
:auto-show-back-to-top="false"
v-model="dataList"
@query="queryList"
>
<template #top>
<backNav :navName="'肝胆相照临床病例库'"></backNav>
<view class="box">
<view class="title" v-if="type == 'video'">{{ info.video_title }}</view>
<view class="title" v-else>{{ info.article_title }}</view>
<view class="content">
<view class="info" v-for="item in info.author">
<up--image
:src="headImg"
mode="widthFix"
class="headImg"
width="46rpx"
height="46rpx"
radius="50%"
></up--image>
<view class="name"
>{{ item.doctor_name }} · {{ item.hospital_name }}</view
>
</view>
<view class="deal">
<view class="left">
<view class="eyebox">
<up-icon name="eye" color="#6B7280" size="28rpx"></up-icon>
<view class="num">{{ info.read_num }}</view>
</view>
<view class="collect">
<up-icon
:name="info.is_collect ? 'heart-fill' : 'heart'"
:color="info.is_collect ? 'red' : '#6B7280'"
size="28rpx"
></up-icon>
<view class="num">{{ info.collect_num }}</view>
</view>
</view>
<view class="time">
<up-icon name="clock" color="#6B7280" size="28rpx"></up-icon>
<view class="num">{{formatDay(info.updated_at)}}</view>
</view>
</view>
</view>
<view class="bar"></view>
<view class="detail">
<!-- <view class="votebox">
<view class="name">在线投票</view>
<view class="title">肝胆相照临床病例库肝胆相照临床病例库肝胆</view>
<view class="options">
<view class="option">
<view class="row">
<view class="left">治疗有效性</view>
<view class="num">0%</view>
</view>
<view class="line">
<view class="inner" style="width: 10%"></view>
</view>
</view>
</view>
</view> -->
</view>
<canvas
v-if="showCanvas"
type="2d"
id="watermarkCanvas"
style="width: 200px; height: 200px; position: fixed; top: -9999px"
/>
</view>
</template>
<template #bottom>
<view class="bottom">
<view class="iptbox">
<up--image
:src="chatImg"
mode="widthFix"
width="46rpx"
radius="50%"
></up--image>
<up-input
@focus="open"
type="text"
placeholderClass="placeholderClass"
placeholder="对病例发表您的看法"
class="ipt"
/>
</view>
<view class="right">
<up--image
@click="toggleCollect"
:src="info.is_collect ? collectonImg : collectImg"
mode="widthFix"
width="38rpx"
></up--image>
<view class="imgboxshang">
<up--image
:src="shangImg"
mode="widthFix"
width="169rpx"
height="77rpx"
></up--image>
</view>
</view>
</view>
</template>
<view class="desc">
<view class="videobox" v-if="type == 'video'">
<polyv-player
id="{{'playerContext'+info.video_no}}"
playerId="{{'playerId'+info.video_no}}"
vid="{{info.video_no }}"
height="500rpx"
autoplay="{{false}}"
>
</polyv-player>
</view>
<view class="videobox" v-else>
<view class="content" v-html="info.article_content"></view>
</view>
<view class="bar"></view>
<view class="comnum">
<view class="imgcon">
<up--image
:src="commentImg"
mode="widthFix"
width="50rpx"
></up--image>
</view>
<view class="num">全部评论{{total}}</view>
</view>
<view class="commentcon">
<view
class="item"
v-for="(item, index) in dataList"
:key="item.comment_id"
>
<up--image
:src="headImg"
class="headImg"
width="86rpx"
height="86rpx"
radius="50%"
></up--image>
<view class="info">
<view class="user">
<view class="name">{{ item.user_name }}</view>
<view class="dot" @click="alertDeal(item.comment_id,item.comment_id,item.is_author,item.user_name,item.is_top,2)">...</view>
</view>
<view class="question">{{ item.content }}</view>
<view class="commentImg">
<up-image src="https://cdn.uviewui.com/uview/album/1.jpg" radius="16rpx" width="150rpx" height="150rpx"></up-image>
</view>
<view class="date">{{ formatDate(item.created_at) }}</view>
<view
class="commentcon"
v-if="item.sub_comment && item.sub_comment.length > 0"
>
<view
class="item"
v-for="(cell, index) in item.sub_comment.slice(0,3)"
:key="cell.comment_id"
style="padding-left: 0"
>
<up--image
:src="headImg"
class="headImg"
width="86rpx"
height="86rpx"
radius="50%"
></up--image>
<view class="info">
<view class="user">
<view class="name">{{ cell.user_name }}</view>
<view class="dot" @click="alertDeal(cell.comment_id,cell.root_id,cell.is_author,cell.user_name,cell.is_top,3)">...</view>
</view>
<view class="question" v-html="formatHtml(cell.content )"></view>
<view class="commentImg">
<up-image src="https://cdn.uviewui.com/uview/album/1.jpg" radius="16rpx" width="150rpx" height="150rpx"></up-image>
</view>
<view class="date">{{ formatDate(cell.created_at) }}</view>
</view>
</view>
</view>
<view class="expand" @click="openMorePop(item,item.sub_comment,index)" v-if="item.sub_comment.length > 3"
>展开更多回复</view
>
</view>
</view>
</view>
</view>
</z-paging>
<!-- 评论框 -->
<up-popup
:zIndex="99"
:overlayStyle="{ zIndex:98 }"
:closeOnClickOverlay="false"
:show="showCommentDialog"
:round="10"
closeable
mode="bottom"
@close="close"
@open="open"
>
<view class="poptitle"></view>
<view class="wraper">
<up--textarea
height="200"
v-model="content"
:placeholder="placeholder"
></up--textarea>
</view>
<view class="imgbox">
<view class="imgunit">
<up--image
:src="shangImg"
radius="6"
width="150rpx"
height="150rpx"
@click="previewImg"
></up--image>
<view class="close">
<up-icon name="close-circle" color="#666" size="16"></up-icon>
</view>
</view>
</view>
<view class="sendbox">
<view class="left"
><up--image
:src="uploadImg"
mode="widthFix"
width="40rpx"
height="77rpx"
@click="chooseImg"
></up--image
></view>
<view class="btn" @click="sendComment">发送</view>
</view>
</up-popup>
<!-- 底部操作 -->
<up-popup
:zIndex="60"
:overlayStyle="{ zIndex:59 }"
:closeOnClickOverlay="false"
:show="showDeal"
:round="10"
mode="bottom"
@close="closeDeal"
@open="openDeal"
>
<view class="dealbox">
<view class="dealcell" @click="toggleTop" v-if="level==2">{{is_top?'取消置顶':'置顶'}}</view>
<view class="dealcell" @click="openCommentDialog">回复</view>
<view class="dealcell" v-if="is_author" @click="delComment">删除</view>
<view class="bar"></view>
<view class="dealcell" @click="closeDealPop">取消</view>
</view>
</up-popup>
<!-- 展开更多回复 -->
<up-popup
:zIndex="10"
:overlayStyle="{ zIndex: 9 }"
:closeOnClickOverlay="false"
:show="showMore"
:round="10"
mode="bottom"
@close="closeMore"
@open="openMore"
>
<view class="commentPop">
<view class="title">
回复
<view class="close" @click="closeMore">
<up-icon name="close" color="#666" size="20"></up-icon>
</view>
</view>
<view class="commentScroll">
<view class="unit commentcon">
<view class="item">
<up--image
:src="headImg"
class="headImg"
width="86rpx"
height="86rpx"
radius="50%"
></up--image>
<view class="info">
<view class="user">
<view class="name">{{ mainCommentObj.user_name }}</view>
<view class="dot" @click="alertDeal(mainCommentObj.comment_id,mainCommentObj.comment_id,mainCommentObj.is_author,mainCommentObj.user_name,mainCommentObj.is_top,2)">...</view>
</view>
<view class="question" >{{ mainCommentObj.content}}</view>
<view class="commentImg">
<up-image src="https://cdn.uviewui.com/uview/album/1.jpg" radius="16rpx" width="150rpx" height="150rpx"></up-image>
</view>
<view class="date">{{formatDate(mainCommentObj.created_at) }}</view>
</view>
</view>
</view>
<view class="commentcon">
<view
class="item"
v-for="(cell, index) in childList"
:key="cell.comment_id">
<up--image
:src="headImg"
class="headImg"
width="86rpx"
height="86rpx"
radius="50%"
></up--image>
<view class="info">
<view class="user">
<view class="name">{{ cell.user_name }}</view>
<view class="dot" @click="alertDeal(cell.comment_id,cell.root_id,cell.is_author,cell.user_name,cell.is_top,3)">...</view>
</view>
<view class="question" v-html="formatHtml(cell.content)"></view>
<view class="date">{{ formatDate(cell.created_at) }}</view>
</view>
</view>
</view>
</view>
<view class="bottom" @click="showReplyPop">
<up-input
readonly
:placeholder="'@'+mainCommentObj.user_name+''"
border="surround"
v-model="value"
></up-input>
</view>
</view>
</up-popup>
<!-- 打赏 -->
<up-overlay :show="showGive" mask-click-able>
<view class="zanboxpop">
<view class="zanwraper">
<view class="title">打赏</view>
<view class="count">
积分余额
<text class="num">100</text>积分
<text class="earn">去赚积分</text>
</view>
<view class="countbox">
<view class="minus">-</view>
<up-input
placeholder="请输入内容"
border="surround"
v-model="value"
></up-input>
<view class="add">+</view>
</view>
<view class="btnbox">
<view class="cancle" @click="showGive=false">取消</view>
<view class="ok" @click="confirmGive">确定</view>
</view>
</view>
</view>
</up-overlay>
<up-overlay :show="showModal" mask-click-able>
<view class="zanboxpop">
<view class="zanwraper">
<view class="title">提示</view>
<view class="content">
是否删除该评论
</view>
<view class="btnbox">
<view class="cancle" @click="showModal=false">取消</view>
<view class="ok" @click="confirmDel">确定</view>
</view>
</view>
</view>
</up-overlay>
</template>
<script setup>
import {reactive, ref } from "vue";
import headImg from "@/static/headImg.png";
import collectonImg from "@/static/collectOn.png";
import collectImg from "@/static/collect.png";
import shangImg from "@/static/shang.png";
import chatImg from "@/static/chat.png";
import uploadImg from "@/static/uploadImg.png";
import backNav from "@/components/backNav/backNav.vue";
import commentImg from "@/static/comment_icon.png";
import list from "@/uni_modules/z-paging/components/z-paging/z-paging";
import api from "@/api/api";
import { onLoad } from "@dcloudio/uni-app";
import dayjs from "dayjs";
const paging = ref(null);
const dataList = ref([]);
const total = ref(0);
const showCanvas = ref(false);
const showCommentDialog = ref(false);
const canvasWidth = ref(0);
const canvasHeight = ref(0);
const showModal = ref(false);
const content = ref("");
const type = ref("");
const info = reactive({});
const showDeal = ref(false);
const showMore = ref(false);
const showGive = ref(false);
const id = ref("");
const parent_id = ref(null);
const root_id = ref(null);
const is_author = ref(false);
const reply_name=ref('');
const level=ref(1);
const placeholder=ref("请输入评论内容");
const mainCommentObj=reactive({});
const childList=ref([]);
const clickIndex=ref(0);
const is_top=ref(false);
const confirmGive = () => {
showGive.value = false;
};
const formatDay=(date)=>{
return dayjs(date).format('YYYY-MM-DD')
}
const formatDate = (date) => {
return dayjs(date).format("YYYY-MM-DD HH:mm");
};
const openMorePop=(obj,list,index)=>{
showMore.value=true;
childList.value=list;
Object.assign(mainCommentObj,obj);
clickIndex.value=index;
}
const getArticleDetail = (id) => {
api.getArticleDetail(id).then((res) => {
let result = res.data.data;
Object.assign(info, result);
});
};
const getVideoDetail = (id) => {
api.getVideoDetail(id).then((res) => {
let result = res.data.data;
Object.assign(info, result);
});
};
onLoad((options) => {
id.value = options.id;
type.value = options.type;
if (type.value == "article") {
getArticleDetail(options.id);
} else {
getVideoDetail(options.id);
}
});
const clearComment=()=>{
parent_id.value=null;
content.value="";
root_id.value=null;
is_author.value=false;
reply_name.value="";
level.value=1;
}
const closeDealPop=()=>{
showDeal.value=false;
clearComment();
}
const showReplyPop=()=>{
parent_id.value=mainCommentObj.comment_id;
root_id.value=mainCommentObj.comment_id;
is_author.value=mainCommentObj.is_author==1?true:false;
reply_name.value=mainCommentObj.user_name;
level.value=2;
if(level.value==2 || level.value==3){
placeholder.value="回复"+reply_name.value+"";
}
showCommentDialog.value=true;
};
const alertDeal=(parentId,rootId,isAuthor,name,top,commentLevel)=>{
parent_id.value=parentId;
root_id.value=rootId;
is_author.value=isAuthor==1?true:false;
reply_name.value=name;
level.value=commentLevel;
is_top.value=top==1?true:false;
if(level.value==2 || level.value==3){
placeholder.value="回复"+name+"";
}
showDeal.value=true;
};
const openCommentDialog = () => {
showCommentDialog.value = true;
showDeal.value = false;
};
const queryList = (pageNo, pageSize) => {
const params = {
page: pageNo,
page_size: pageSize,
};
type.value == "article" ? getArticleComment(params) : getVideoComment(params);
};
const getArticleComment = (params) => {
const form = {
article_id: id.value,
is_have_sub_comment: 1,
};
api
.getArticleComment({
...form,
...params,
})
.then((res) => {
paging.value.complete(res.data.data.data);
total.value= res.data.data.total;
setTimeout(()=>{
if(showMore.value){
openMorePop(mainCommentObj,(dataList.value[clickIndex.value]).sub_comment,clickIndex.value)
}
},1500)
})
.catch((res) => {
paging.value.complete(false);
});
};
const getVideoComment = (params) => {
api
.getVideoComment({
...params,
})
.then((res) => {
paging.value.complete(res.data.data.data);
total.value= res.data.data.total;
setTimeout(()=>{
if(showMore.value){
openMorePop(mainCommentObj,(dataList.value[clickIndex.value]).sub_comment,clickIndex.value)
}
},1500)
})
.catch((res) => {
paging.value.complete(false);
});
};
const open = () => {
showCommentDialog.value = true;
console.log("open");
};
const close = () => {
showCommentDialog.value = false;
console.log("close");
};
const openDeal = () => {
showDeal.value = true;
console.log("open");
};
const closeDeal = () => {
showDeal.value = false;
};
const openMore = () => {
showMore.value = true;
console.log("open");
};
const closeMore = () => {
showMore.value = false;
};
const previewImg = () => {
uni.previewImage({
current: "https://example.com/image1.jpg",
urls: ["https://example.com/image1.jpg", "https://example.com/image2.jpg"],
});
};
const fillTextToImgWx = (base64) => {
let maskText = "@zjd嗯嗯嗯嗯嗯嗯3评论暂时真实的334";
return new Promise((resolve, reject) => {
wx.createSelectorQuery()
.select("#watermarkCanvas")
.fields({
node: true,
size: true,
})
.exec((res) => {
const canvas = res[0].node;
const ctx = canvas.getContext("2d");
let textMetrics = ctx.measureText(maskText);
console.log(textMetrics);
//水印文字宽度
let {
width: textWidth,
actualBoundingBoxAscent,
actualBoundingBoxDescent,
} = textMetrics;
//水印文字高度
let textHeight = actualBoundingBoxAscent
? actualBoundingBoxAscent + actualBoundingBoxDescent
: textMetrics.fontBoundingBoxAscent +
textMetrics.fontBoundingBoxDescent;
let imgHeight, imgWidth;
let font = ""; //fontsize"px Arial";
let fontColor = "#fff";
let strokeWidth = 3;
uni.getImageInfo({
src: base64,
success: (imageRes) => {
// 设置canvas宽高
let scale =
(imageRes.width / 800) * 30 > 12
? (imageRes.width / 800) * 30
: 12;
font = scale + "px Arial";
console.log(imageRes);
canvas.width = imageRes.width;
canvas.height = imageRes.height;
imgHeight = imageRes.height;
imgWidth = imageRes.width;
// 创建目标图片对象
const image = canvas.createImage();
image.src = "";
image.src = base64;
image.onload = () => {
// 清除画布
//ctx.clearRect(0, 0, canvas.width, canvas.height);
// 将图片绘制到canvas上
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
let posXmargin = 10; //this.data.posXmargin // 自定义离左/右边的距离
let posYmargin = 10; // this.data.posYmargin // 自定义离上/下边的距离
let randomNumber = 3; //Math.floor(Math.random() * (3 + 1));
console.log("randomNumber:" + randomNumber);
switch (randomNumber) {
case 0: //左上角
let lt_x = posXmargin;
let lt_y = posYmargin + textHeight;
ctx.font = font;
ctx.fillStyle = fontColor;
ctx.storkStyle = "black";
ctx.strokeWidth = strokeWidth;
ctx.fillStyle = "#fff";
ctx.fillText(maskText, lt_x, lt_y);
//ctx.restore()
//ctx.save()
break;
case 1: //左下角
let lb_x = posXmargin;
let lb_y = imgHeight - posYmargin;
ctx.font = font;
ctx.fillStyle = fontColor;
ctx.strokeStyle = "black";
ctx.strokeWidth = strokeWidth;
ctx.fillStyle = "#fff";
ctx.fillText(maskText, lb_x, lb_y);
//ctx.restore()
//ctx.save()
break;
case 2: //右上角
let rt_x =
imgWidth - textWidth * 2.9 - posXmargin <= 0
? 10
: imgWidth - textWidth * 2.9 - posXmargin;
let rt_y = posYmargin + textHeight * 2;
ctx.font = font;
ctx.fillStyle = fontColor;
ctx.strokeStyle = "black";
ctx.strokeWidth = strokeWidth;
ctx.fillStyle = "#fff";
ctx.fillText(maskText, rt_x, rt_y);
ctx.restore();
ctx.save();
break;
case 3: //右下角
let rb_x =
imgWidth - textWidth * 2.9 - posXmargin <= 0
? 10
: imgWidth - textWidth * 2.9 - posXmargin;
let rb_y = imgHeight - posYmargin;
ctx.font = font;
ctx.fillStyle = fontColor;
ctx.strokeStyle = "black";
ctx.strokeWidth = strokeWidth;
ctx.fillStyle = "#fff";
ctx.fillText(maskText, rb_x, rb_y);
//ctx.restore()
//ctx.save()
break;
}
//ctx.restore()
// 将canvas转为图片
//setTimeout(() => {
wx.canvasToTempFilePath({
canvas: canvas,
success: function (res) {
// 输出生成的带水印的图片临时路径
resolve(res.tempFilePath);
wx.previewImage({ urls: [res.tempFilePath] });
showCanvas.value = false;
},
fail: function (res) {
// reject(res)
console.error(res);
},
});
//})
};
},
});
});
});
};
const fillTextToImg = (base64) => {
const img = new Image();
img.src = base64;
img.setAttribute("crossOrigin", "Anonymous");
return new Promise((resolve, reject) => {
img.onload = () => {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
canvas.width = img.width;
canvas.height = img.height;
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
const remFontSize = 30; //canvas.width / 35;
ctx.font = remFontSize + "px '微软雅黑'";
ctx.textAlign = "right";
ctx.strokeStyle = "#000";
ctx.fillStyle = "#fff";
const uploadTime = new Date();
const name = "@zjd";
const spaceH = remFontSize * 0.1;
let randomNumber = Math.floor(Math.random() * (3 + 1));
let position = [
{
top: remFontSize,
left: name.length * 30 || 30,
},
{
top: remFontSize,
left: canvas.width - remFontSize * 0.1 - spaceH,
},
{
top: canvas.height - remFontSize * 0.5 - spaceH,
left: name.length * 30 || 30,
},
{
top: canvas.height - remFontSize * 0.5 - spaceH,
left: canvas.width - remFontSize * 0.1 - spaceH,
},
];
ctx.strokeText(
name,
position[randomNumber].left,
position[randomNumber].top
);
ctx.fillText(
name,
position[randomNumber].left,
position[randomNumber].top
);
resolve(canvas.toDataURL("image/jpeg"));
};
});
};
const base64ToFile = (base64Data, filename) => {
var arr = base64Data.split(",");
var type = arr[0].match(/:(.*?);/)[1];
var fileExt = type.split("/")[1];
var bstr = atob(arr[1]);
var n = bstr.length;
var u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, {
type: type,
});
};
const generateUUID = () => {
let d = new Date().getTime();
if (
typeof performance !== "undefined" &&
typeof performance.now === "function"
) {
d += performance.now(); // 使用性能测量 APIperformance.now())获取更高精度的时间戳
}
const uuid = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(
/[xy]/g,
function (c) {
const r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c == "x" ? r : (r & 0x3) | 0x8).toString(16);
}
);
return uuid;
};
const readImages = async (localIds) => {
console.log(localIds);
let promiseFun = [];
for (var i = 0; i < localIds.length; i++) {
//let localData = await doreadImage(localIds[i]);
let img = null;
/* #ifdef H5 */
let imgBase64 = await getImageBase64(localIds[i]);
img = await fillTextToImg(imgBase64);
console.log(img);
uni.previewImage({ urls: [img] });
/* #endif */
/* #ifdef MP-WEIXIN */
let imgpromise = await fillTextToImgWx(localIds[i]);
console.log(22222);
//console.log(imgBase64);
/* #endif */
//let imgFile = base64ToFile(img, new Date().getTime() + ".jpg");
// console.log(imgFile)
//promiseFun.push(uploadImg(imgFile));
}
Promise.all(promiseFun).then((res) => {
uni.showToast({
duration: 1000,
message: "上传成功",
});
});
};
// 图片转64代
const getImageBase64 = (url) => {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.responseType = "blob";
xhr.onload = function () {
if (this.status == 200) {
const fileReader = new FileReader();
fileReader.onloadend = function () {
resolve(fileReader.result); // Base64编码的字符串
};
fileReader.readAsDataURL(xhr.response); // 将blob转换为base64
} else {
reject("Could not fetch the file.");
}
};
xhr.onerror = function () {
reject("XHR error");
};
xhr.send();
});
};
const chooseImg = () => {
showCanvas.value = true;
uni.chooseImage({
count: 1, //默认9
sizeType: ["original", "compressed"], //可以指定是原图还是压缩图,默认二者都有
sourceType: ["album", "camera "], //从相册选择
success: function (res) {
console.log(333);
readImages(res.tempFilePaths);
},
});
};
const collectArticle = (id) => {
api.collectArticle(id).then((res) => {
uni.showToast({
icon: "none",
title: "收藏成功",
});
getArticleDetail(id);
});
};
const cancelCollectArticle = (id) => {
api.cancelCollectArticle(id).then((res) => {
uni.showToast({
icon: "none",
title: "已取消收藏",
});
getArticleDetail(id);
});
};
const collectVideo = (id) => {
api.collectVideo(id).then((res) => {
uni.showToast({
icon: "none",
title: "收藏成功",
});
getVideoDetail(id);
});
};
const cancelCollectVideo = (id) => {
api.cancelCollectVideo(id).then((res) => {
uni.showToast({
icon: "none",
title: "已取消收藏",
});
getVideoDetail(id);
});
};
const toggleCollect = () => {
if (type.value == "video") {
info.is_collect ? cancelCollectVideo(id.value) : collectVideo(id.value);
} else {
info.is_collect ? cancelCollectArticle(id.value) : collectArticle(id.value);
}
};
const addArticleComment = (id, data) => {
api.addArticleComment(id, data).then((res) => {
uni.showToast({
icon: "none",
title: "评论成功",
});
clearComment();
showCommentDialog.value = false;
paging.value.refresh();
});
};
const addVideoComment = (id, data) => {
api.addVideoContent(id, data).then((res) => {
uni.showToast({
icon: "none",
title: "评论成功",
});
clearComment()
showCommentDialog.value = false;
paging.value.refresh();
});
};
const delArticleComment = (id) => {
api.delArticleComment(id).then((res) => {
uni.showToast({
icon: "none",
title: "删除成功",
});
paging.value.refresh();
});
};
const delVideoComment = (id) => {
api.delVideoComment(id).then((res) => {
uni.showToast({
icon: "none",
title: "删除成功",
});
paging.value.refresh();
});
};
const topArticleComment = (id) => {
api.topArticleComment(id).then((res) => {
uni.showToast({
icon: "none",
title: "置顶成功",
});
});
showDeal.value = false;
paging.value.refresh();
};
const topVideoComment = (id) => {
api.topVideoComment(id).then((res) => {
uni.showToast({
icon: "none",
title: "置顶成功",
});
});
showDeal.value = false;
paging.value.refresh();
};
const cancelTopArticleComment = (id) => {
api.cancelTopArticleComment(id).then((res) => {
uni.showToast({
icon: "none",
title: "取消置顶成功",
});
});
showDeal.value = false;
paging.value.refresh();
};
const cancelTopVideoComment = (id) => {
api.cancelTopArticleComment(id).then((res) => {
uni.showToast({
icon: "none",
title: "取消置顶成功",
});
});
showDeal.value = false;
paging.value.refresh();
};
const delComment=()=>{
showModal.value=true;
showDeal.value=false;
}
const confirmDel=()=>{
if(type.value=='article'){
delArticleComment(parent_id.value)
}else{
delVideoComment(parent_id.value)
}
showModal.value=false;
}
const toggleTop=()=>{
if(type.value=='article'){
is_top.value?cancelTopArticleComment(parent_id.value):topArticleComment(parent_id.value)
}else{
is_top.value?cancelTopVideoComment(parent_id.value):topVideoComment(parent_id.value)
}
}
const sendComment=()=>{
if(!content.value) {
uni.showToast({
icon: "none",
title: "请输入评论内容",
});
return false;
}
const postData={
content:level.value==3?'回复'+reply_name.value+''+content.value:content.value
}
if(parent_id.value !==null){
postData.parent_id=parent_id.value;
}
if(root_id.value!==null){
postData.root_id=root_id.value;
}
if(type.value=='article'){
addArticleComment(id.value,postData)
}else{
addVideoComment(id.value,postData)
}
}
const formatHtml=(val)=>{
if(/^回复.+/.test(val)){
return val.replace(/[^回复]([^]+)/,`<font style="color:#3CC7C0">$&</font>`)
};
return val
}
</script>
<style lang='scss' scoped>
.zanboxpop {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
.zanwraper {
width: 630rpx;
margin: 0 auto;
padding-bottom: 50rpx;
background: #f5f6f9;
border-radius: 16rpx;
.title {
margin-top: 48rpx;
text-align: center;
font-weight: 500;
font-size: 36rpx;
color: rgba(0, 0, 0, 0.85);
}
.content{
padding:30rpx 0 ;
background: #f5f6f9;
text-align: center;
}
.count {
margin-top: 24rpx;
display: flex;
align-items: center;
text-align: center;
justify-content: center;
font-weight: 400;
font-size: 28rpx;
color: rgba(0, 0, 0, 0.65);
.num {
color: #ff0000;
font-size: 32rpx;
}
.earn {
font-size: 32rpx;
color: #3cc7c0;
}
}
.countbox {
display: flex;
width: 100%;
margin: 30rpx 0px 40rpx;
padding: 0 40rpx;
justify-content: center;
box-sizing: border-box;
.minus {
flex-shrink: 0;
margin-left: 10rp;
width: 90rpx;
height: 90rpx;
font-size: 60rpx;
color: #333;
display: flex;
justify-content: center;
align-items: center;
background: #ffffff;
border-radius: 12rpx;
border: 2rpx solid #e9e9e9;
}
.add {
flex-shrink: 0;
width: 90rpx;
margin-left: 10rpx;
height: 90rpx;
font-size: 60rpx;
color: #333;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
background: #3cc7c0;
border-radius: 12rpx;
border: 2rpx solid #3cc7c0;
}
:deep(.u-input__content__field-wrapper__field) {
height: 60rpx;
font-size: 34rpx!important;
text-align: center!important;
}
:deep(.u-input) {
background: #f2f2f2;
width: 200rpx!important;
flex:none;
}
:deep(.u-input--radius) {
border-radius: 24rrpx;
}
}
.btnbox {
margin: 0px 40rpx 0px;
display: flex;
justify-content: space-between;
.cancle {
color: rgba(0, 0, 0, 0.3);
width: 256rpx;
height: 88rpx;
background: #f5f6f9;
border-radius: 25px;
border: 2rpx solid rgba(0, 0, 0, 0.15);
font-weight: 500;
font-size: 32rpx;
color: rgba(0, 0, 0, 0.85);
display: flex;
justify-content: center;
align-items: center;
}
.ok{
color:#fff;
width: 256rpx;
height: 88rpx;
background: #3cc7c0;
border-radius: 25px;
border: 2rpx solid #3cc7c0;
font-weight: 500;
font-size: 32rpx;
display: flex;
justify-content: center;
align-items: center;
}
}
}
}
.commentPop {
height: calc(100vh - 400rpx);
display: flex;
flex-direction: column;
.commentScroll {
flex: 1;
overflow-y: scroll;
margin-bottom: 96rpx;
}
.bottom {
border-top: 2rpx solid #efefef;
height: 96rpx;
display: flex;
align-items: center;
justify-content: center;
background: #fff;
:deep(.u-input__content__field-wrapper__field) {
height: 50rpx;
}
:deep(.u-input) {
background: #f2f2f2;
}
:deep(.u-input--radius) {
border-radius: 40rpx;
}
}
.title {
height: 100rpx;
line-height: 100rpx;
text-align: center;
position: relative;
border-bottom: 2rpx solid #e7e7e7;
.close {
position: absolute;
right: 20rpx;
top: 30rpx;
}
}
.unit {
.item {
margin-top: 12rpx;
border-bottom: 2rpx solid rgb(231, 231, 231);
}
}
}
.dealbox {
.dealcell {
display: flex;
align-items: center;
justify-content: center;
height: 112rpx;
font-size: 32rpx;
color: rgba(0, 0, 0, 0.9);
border-bottom: 2rpx solid #efefef;
}
}
.expand {
display: flex;
font-size: 32rpx;
padding: 12rpx 0;
color: #3cc7c0;
}
.commentcon {
.item {
display: flex;
padding: 30rpx 35rpx 16rpx;
.info {
margin-left: 24rpx;
flex: 1;
.user {
display: flex;
align-items: center;
justify-content: space-between;
.name {
font-size: 34rpx;
}
.dot {
font-size: 32rpx;
}
}
.question {
margin-top: 15rpx;
font-size: 30rpx;
margin-bottom: 0px;
line-height: 54rpx;
color: #333;
white-space: pre-wrap;
word-wrap: break-word;
word-break: break-all;
}
.commentImg{
margin-top: 16rpx;
}
.date {
font-size: 30rpx;
color: #666666;
line-height: 34px;
}
}
}
}
.comnum {
padding: 0 30rpx;
background: #fff;
display: flex;
height: 100rpx;
align-items: center;
border-bottom: 1px solid #e7e7e7;
.imgcon {
margin-top: 10rpx;
}
:deep(.u-image) {
background: none !important;
}
.num {
margin-left: 10rpx;
font-size: 32rpx;
}
}
.content {
padding: 30rpx;
background-color: #fff;
}
.votebox {
padding: 30rpx;
background: #fff;
.name {
font-size: 36rpx;
color: #000000;
line-height: 46rpx;
}
.title {
margin-top: 24rpx;
font-size: 30rpx;
color: #333333;
line-height: 46rpx;
}
.option {
margin-top: 26rpx;
.row {
font-size: 27rpx;
color: #4b5563;
display: flex;
align-items: center;
justify-content: space-between;
}
.line {
width: 100%;
height: 15rpx;
background: #f3f4f6;
border-radius: 19rpx;
overflow: hidden;
.inner {
height: 15rpx;
background: #3cc7c0;
border-radius: 19rpx;
}
}
}
}
.imgboxshang {
display: flex;
align-items: center;
}
.imgbox {
margin: 0 30rpx 30rpx;
.imgunit {
width: 150rpx;
height: 150rpx;
position: relative;
.close {
position: absolute;
top: 0rpx;
right: 0;
}
}
}
.poptitle {
height: 88rpx;
border-bottom: 1rpx solid #e7e7e7;
}
.sendbox {
display: flex;
justify-content: space-between;
margin: 0 30rpx 30rpx;
.btn {
width: 120rpx;
height: 58rpx;
display: flex;
align-items: center;
justify-content: center;
background: #3cc7c0;
font-weight: 400;
font-size: 30rpx;
color: #fff;
border-radius: 12rpx;
}
}
.wraper {
margin: 0rpx 12rpx;
}
.desc {
padding-bottom: 80rpx;
}
.bottom {
position: fixed;
display: flex;
width: 100%;
box-sizing: border-box;
padding: 40rpx 30rpx;
align-items: center;
border-top: 2rpx solid #f9fafb;
background: #fff;
bottom: 0;
:deep(.u-image) {
background: none !important;
}
:deep(.placeholderClass) {
font-size: 30rpx;
color: #4b5563;
}
.right {
margin-left: 20rpx;
display: flex;
align-items: center;
background: #fff;
.imgbox {
margin-left: 20rpx;
}
}
.iptbox {
flex: 1;
padding-left: 30rpx;
background: #f3f4f6;
border-radius: 38px;
height: 77rpx;
display: flex;
align-items: center;
.ipt {
margin-left: 15rpx;
}
}
}
.bar {
width: 100%;
background: #f9fafb;
height: 20rpx;
}
.box {
background: #fff;
/* height: calc(100vh - 220rpx);
overflow-y: scroll;
-webkit-overflow-scrolling: touch; */
.title {
position: relative;
z-index: 1;
padding: 35rpx 30rpx 0;
background: #fff;
margin-top: -40rpx;
font-weight: 400;
font-size: 38rpx;
color: #111827;
line-height: 54rpx;
}
.info {
display: flex;
align-items: center;
margin-top: 20rpx;
padding: 0 30rpx;
font-size: 28rpx;
color: #4b5563;
line-height: 38rpx;
:deep(.u-image) {
margin-top: 10rpx;
}
.name {
margin-left: 15rpx;
}
}
}
.deal {
margin-top: 12rpx;
padding: 0 30rpx 20rpx;
display: flex;
color: #6b7280;
font-size: 24rpx;
justify-content: space-between;
.left {
display: flex;
align-items: center;
}
.collect {
display: flex;
align-items: center;
}
.eyebox {
width: 160rpx;
display: flex;
align-items: center;
}
.time {
display: flex;
align-items: center;
}
.num {
margin-left: 8rpx;
}
}
</style>