fix(richedit): 修复移动端富文本编辑器滚动加载和样式问题

修复无限滚动加载逻辑,确保在接近底部时触发加载
调整容器样式解决滚动条显示问题
优化标签切换时的数据重置逻辑
This commit is contained in:
zzp 2025-10-12 13:15:54 +08:00
parent 5ebff592cf
commit 11144f2fa7
1 changed files with 487 additions and 458 deletions

View File

@ -1,8 +1,14 @@
<template> <template>
<div class="all" ref="mescrollRef" v-infinite-scroll="getDataByScoll" style="overflow-y: auto"> <!-- v-infinite-scroll="getDataByScoll" -->
<div class="all" ref="mescrollRef" style="overflow: auto">
<div style="display: flex; align-items: center"> <div style="display: flex; align-items: center">
<el-input v-model="form.keyword" placeholder="输入关键字进行搜索(以空格隔开)" class="input-with-select" <el-input
@keyup.enter="handleSearch" style="width: 80%"> v-model="form.keyword"
placeholder="输入关键字进行搜索(以空格隔开)"
class="input-with-select"
@keyup.enter="handleSearch"
style="width: 80%"
>
<template #append> <template #append>
<el-button icon="Search" @click="handleSearch" /> <el-button icon="Search" @click="handleSearch" />
</template> </template>
@ -11,17 +17,27 @@
<el-button style="width: 20%" type="text" @click="restData">清空条件</el-button> <el-button style="width: 20%" type="text" @click="restData">清空条件</el-button>
</div> </div>
<el-date-picker style="margin-top: 20px; width: 100%; max-height: 40px" v-model="daterange" type="daterange" <el-date-picker
range-separator="至" value-format="YYYY-MM-DD" start-placeholder="选择报道时间" end-placeholder="选择报道时间" style="margin-top: 20px; width: 100%; max-height: 40px"
@change="handleSearch" /> v-model="daterange"
type="daterange"
range-separator="至"
value-format="YYYY-MM-DD"
start-placeholder="选择报道时间"
end-placeholder="选择报道时间"
@change="handleSearch"
/>
<div class="filter"> <div class="filter">
<div class="r_tabs"> <div class="r_tabs">
<div class="tabItem" v-for="(item, index) in tabsList" :key="index" @click="changeTab(index)"> <div class="tabItem" v-for="(item, index) in tabsList" :key="index" @click="changeTab(index)">
<text :style="{ <text
:style="{
color: tabIndex == index ? '#409eff' : '#333', color: tabIndex == index ? '#409eff' : '#333',
fontWeight: tabIndex == index ? 'bold' : 'normal', fontWeight: tabIndex == index ? 'bold' : 'normal',
}">{{ item.name }}</text> }"
>{{ item.name }}</text
>
<div class="tab_line" v-if="tabIndex == index"></div> <div class="tab_line" v-if="tabIndex == index"></div>
</div> </div>
</div> </div>
@ -35,8 +51,7 @@
<div class="card_header" @click.stop="goDetail(1, item, true)"> <div class="card_header" @click.stop="goDetail(1, item, true)">
<text class="card_title" v-html="item.title"></text> <text class="card_title" v-html="item.title"></text>
<div class="r_point" :style="{ color: '#000' }"> <div class="r_point" :style="{ color: '#000' }">
<div class="point" :style="{ backgroundColor: item.status == 2 ? '#52C41A' : '#D9D9D9' }"> <div class="point" :style="{ backgroundColor: item.status == 2 ? '#52C41A' : '#D9D9D9' }"></div>
</div>
<text v-if="item.status == 0" style="color: rgba(0, 0, 0, 0.65)">草稿</text> <text v-if="item.status == 0" style="color: rgba(0, 0, 0, 0.65)">草稿</text>
<text v-if="item.status == 1" style="color: rgba(0, 0, 0, 0.65)"> <text v-if="item.status == 1" style="color: rgba(0, 0, 0, 0.65)">
{{ item.deleted ? '已删除' : '未发布' }} {{ item.deleted ? '已删除' : '未发布' }}
@ -71,59 +86,54 @@
<div style="display: flex; justify-content: space-between; align-items: center; height: 10px"> <div style="display: flex; justify-content: space-between; align-items: center; height: 10px">
<div></div> <div></div>
<div class="option"> <div class="option">
<el-button v-if="item.deleted" type="text" style="margin-left: -10px" <el-button v-if="item.deleted" type="text" style="margin-left: -10px" @click="doRecoverFn(item)">
@click="doRecoverFn(item)">
<text>恢复</text> <text>恢复</text>
</el-button> </el-button>
<div v-else <div v-else style="display: flex; gap: 3px; align-items: center; flex-wrap: nowrap; white-space: nowrap">
style="display: flex; gap: 3px; align-items: center; flex-wrap: nowrap; white-space: nowrap">
<!-- 新闻状态 0-草稿 | 1-未发布 | 2-已发布 | 3-送审 | 4-已二审 | -1-退改中 --> <!-- 新闻状态 0-草稿 | 1-未发布 | 2-已发布 | 3-送审 | 4-已二审 | -1-退改中 -->
<div v-if="Session.get('userInfoLocal').userType == '00'"> <div v-if="Session.get('userInfoLocal').userType == '00'">
<!-- 普通账号 --> <!-- 普通账号 -->
<el-button v-if="item.status == 0 || item.status == 1 || item.status == -1" <el-button v-if="item.status == 0 || item.status == 1 || item.status == -1" type="text" @click="goDetail(1, item, false)"
type="text" @click="goDetail(1, item, false)">编辑</el-button> >编辑</el-button
>
<el-button v-if="item.status == 0 || item.status == 1 || item.status == -1" <el-button v-if="item.status == 0 || item.status == 1 || item.status == -1" type="text" @click="doApprovalFn(item, item.status)"
type="text" @click="doApprovalFn(item, item.status)">送审</el-button> >送审</el-button
<el-button v-else-if="item.status == 3" type="text" >
@click="doApprovalFn(item, item.status)">撤审</el-button> <el-button v-else-if="item.status == 3" type="text" @click="doApprovalFn(item, item.status)">撤审</el-button>
<el-button v-if="item.status == 0 || item.status == 1 || item.status == -1" <el-button
type="text" style="color: #ff1818" @click="doDeleteNewsFn(item)">删除</el-button> v-if="item.status == 0 || item.status == 1 || item.status == -1"
type="text"
style="color: #ff1818"
@click="doDeleteNewsFn(item)"
>删除</el-button
>
</div> </div>
<div v-if="Session.get('userInfoLocal').userType == '02'"> <div v-if="Session.get('userInfoLocal').userType == '02'">
<el-button v-if="item.status == 4" type="text" <el-button v-if="item.status == 4" type="text" @click="doApprovalFn(item, item.status)">撤审</el-button>
@click="doApprovalFn(item, item.status)">撤审</el-button>
<!-- 二审账号 --> <!-- 二审账号 -->
<el-button v-if="item.status == 3" type="text" style="color: #ff1818" <el-button v-if="item.status == 3" type="text" style="color: #ff1818" @click="doNewReturnFn(item)">退改</el-button>
@click="doNewReturnFn(item)">退改</el-button>
<el-button v-if="item.status == 3" type="text" <el-button v-if="item.status == 3" type="text" @click="goDetail(1, item, false)">编辑</el-button>
@click="goDetail(1, item, false)">编辑</el-button>
<el-button v-if="item.status == 3" type="text" <el-button v-if="item.status == 3" type="text" @click="doNewCheckFn(item)">复审</el-button>
@click="doNewCheckFn(item)">复审</el-button>
<el-button type="text" v-if="item.status == 4" <el-button type="text" v-if="item.status == 4" @click="doNewsPublishFn(item, 2)">发布</el-button>
@click="doNewsPublishFn(item, 2)">发布</el-button>
</div> </div>
<div v-if="Session.get('userInfoLocal').userType == '01'"> <div v-if="Session.get('userInfoLocal').userType == '01'">
<!-- 终审账号 --> <!-- 终审账号 -->
<el-button v-if="item.status == 3 || item.status == 4" type="text" <el-button v-if="item.status == 3 || item.status == 4" type="text" @click="goDetail(1, item, false)">编辑</el-button>
@click="goDetail(1, item, false)">编辑</el-button>
<el-button v-if="item.status == 4" type="text" style="color: #ff1818" <el-button v-if="item.status == 4" type="text" style="color: #ff1818" @click="doNewReturnFn(item)">退改</el-button>
@click="doNewReturnFn(item)">退改</el-button>
<el-button type="text" v-if="item.status == 2" <el-button type="text" v-if="item.status == 2" @click="doNewsPublishFn(item, 1)">撤稿</el-button>
@click="doNewsPublishFn(item, 1)">撤稿</el-button> <el-button type="text" v-else-if="item.status != -1 && item.status == 4" @click="doNewsPublishFn(item, 2)">发布</el-button>
<el-button type="text" v-else-if="item.status != -1 && item.status == 4"
@click="doNewsPublishFn(item, 2)">发布</el-button>
<el-button v-if="item.status == 3" type="text" <el-button v-if="item.status == 3" type="text" style="color: #ff1818; margin-left: 5px" @click="doNewReturnFn(item)"
style="color: #ff1818; margin-left: 5px" >退改</el-button
@click="doNewReturnFn(item)">退改</el-button> >
</div> </div>
<!-- <el-icon size="16" @click="goRecord(scope.row)"> <!-- <el-icon size="16" @click="goRecord(scope.row)">
@ -145,9 +155,16 @@
</el-icon> </el-icon>
</div> </div>
<keep-alive> <keep-alive>
<DetailDrawer v-model="drawer" :data="newsData" :readOnly="readOnly" :type="newstype" <DetailDrawer
@handleEditStatus="handleEditStatus" @doNewsPublishFn="doNewsPublishFn" @doDeleteNewsFn="doDeleteNewsFn" v-model="drawer"
@getData="getData" /> :data="newsData"
:readOnly="readOnly"
:type="newstype"
@handleEditStatus="handleEditStatus"
@doNewsPublishFn="doNewsPublishFn"
@doDeleteNewsFn="doDeleteNewsFn"
@getData="getData"
/>
</keep-alive> </keep-alive>
</div> </div>
</template> </template>
@ -187,6 +204,7 @@ const tabsList = ref([
const tabIndex = ref(0); const tabIndex = ref(0);
function changeTab(index) { function changeTab(index) {
tableData.page = 1;
tabIndex.value = index; tabIndex.value = index;
form.value.status = tabsList.value[index].status; form.value.status = tabsList.value[index].status;
getData(); getData();
@ -215,6 +233,8 @@ const tableData = reactive({
}); });
function getDataByScoll() { function getDataByScoll() {
console.log('🚀 ~ getDataByScoll ~ tableData.data.length :', tableData.data.length);
console.log('🚀 ~ getDataByScoll ~ tableData.total:', tableData.total);
if (tableData.data.length < tableData.total) { if (tableData.data.length < tableData.total) {
tableData.page++; tableData.page++;
getData(); getData();
@ -319,7 +339,7 @@ async function doNewsPublishFn(item, status) {
getData(); getData();
} }
}) })
.catch(() => { }); .catch(() => {});
} }
/** 管理后台需求文件0519V1.1 start */ /** 管理后台需求文件0519V1.1 start */
@ -361,7 +381,7 @@ function restData() {
form.value.mediaId = null; form.value.mediaId = null;
form.value.deleted = null; form.value.deleted = null;
form.value.status = null; // form.value.status = null;
form.value.rating = null; form.value.rating = null;
form.value.orderBy = null; form.value.orderBy = null;
@ -388,12 +408,23 @@ function goTop() {
} }
const isShowBackTop = ref(false); const isShowBackTop = ref(false);
function handleScroll() { function handleScroll(e) {
console.log('🚀 ~ handleScroll ~ e:', e);
if (mescrollRef.value.scrollTop > 300) { if (mescrollRef.value.scrollTop > 300) {
isShowBackTop.value = true; isShowBackTop.value = true;
} else { } else {
isShowBackTop.value = false; isShowBackTop.value = false;
} }
const { scrollTop, clientHeight, scrollHeight } = mescrollRef.value;
// 200px
const isNearBottom = scrollTop + clientHeight >= scrollHeight - 50;
//
if (isNearBottom) {
getDataByScoll();
}
} }
// //
@ -445,11 +476,10 @@ async function doApprovalFn(item, status) {
getData(); getData();
} }
}) })
.catch(() => { }); .catch(() => {});
} }
onMounted(() => { onMounted(() => {
if (Session.get('userInfoLocal').userType == '02') { if (Session.get('userInfoLocal').userType == '02') {
tabsList.value = [ tabsList.value = [
{ {
@ -472,7 +502,7 @@ onMounted(() => {
name: '全部', name: '全部',
status: null, status: null,
}, },
] ];
} else if (Session.get('userInfoLocal').userType == '01') { } else if (Session.get('userInfoLocal').userType == '01') {
tabsList.value = [ tabsList.value = [
{ {
@ -491,14 +521,12 @@ onMounted(() => {
name: '全部', name: '全部',
status: null, status: null,
}, },
] ];
} }
changeTab(0); changeTab(0);
mescrollRef.value.addEventListener('scroll', handleScroll); mescrollRef.value.addEventListener('scroll', handleScroll);
// getData(); // getData();
}); });
onUnmounted(() => { onUnmounted(() => {
@ -510,8 +538,9 @@ onUnmounted(() => {
.all { .all {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
max-width: 100vw; // max-width: 100vw;
height: 100vh; height: 100vh;
overflow-y: auto;
scrollbar-width: none; scrollbar-width: none;
/* Firefox */ /* Firefox */
-ms-overflow-style: none; -ms-overflow-style: none;
@ -620,7 +649,7 @@ onUnmounted(() => {
.bottom_load_text { .bottom_load_text {
font-size: 14px; font-size: 14px;
color: #ccc; color: #ccc;
width: 90vw; // width: 90vw;
height: 30px; height: 30px;
display: flex; display: flex;
text-align: center; text-align: center;