提交 6c49007c authored 作者: 张伊明's avatar 张伊明

fix 优化原文组件

上级 070b639a
...@@ -11,18 +11,16 @@ ...@@ -11,18 +11,16 @@
<el-switch v-model="isTranslate" /> <el-switch v-model="isTranslate" />
<div class="switch-label">原文显示</div> <div class="switch-label">原文显示</div>
<div class="btn" @click="emits('download')"> <div
<div class="icon icon-gap-4"> v-for="action in headerActions"
<img :src="defaultDownloadIcon" alt="" /> :key="action.key"
class="btn"
@click="action.onClick"
>
<div :class="['icon', action.iconGapClass]">
<img :src="action.icon" alt="" />
</div> </div>
<div class="text">下载</div> <div class="text">{{ action.text }}</div>
</div>
<div class="btn" @click="handleFindWord('open')">
<div class="icon icon-gap-6">
<img :src="defaultSearchIcon" alt="" />
</div>
<div class="text">查找</div>
</div> </div>
<div class="find-word-box" v-if="findWordBox"> <div class="find-word-box" v-if="findWordBox">
...@@ -47,15 +45,16 @@ ...@@ -47,15 +45,16 @@
</div> </div>
<div class="report-main"> <div class="report-main">
<div v-if="!displayReportData.length" class="noContent">{{ "暂无数据" }}</div> <div v-if="!displayReportData.length" class="no-content">暂无数据</div>
<el-scrollbar height="100%" v-else> <el-scrollbar v-else height="100%">
<div <div
v-for="item in displayReportData" v-for="item in displayReportData"
:key="item.num" :key="item.num"
:class="['content-row', { 'high-light': isHighlight }]" class="content-row"
:class="{ 'high-light': isHighlight }"
> >
<div :class="['content-cn', { 'translate-cn': !isTranslate }]" v-html="item.content"></div> <div class="content-cn" :class="{ 'translate-cn': !isTranslate }" v-html="item.content" />
<div class="content-en" v-html="item.contentEn" v-if="isTranslate"></div> <div v-if="isTranslate" class="content-en" v-html="item.contentEn" />
</div> </div>
</el-scrollbar> </el-scrollbar>
</div> </div>
...@@ -70,8 +69,6 @@ import defaultSearchIcon from "./assets/icons/search.png"; ...@@ -70,8 +69,6 @@ import defaultSearchIcon from "./assets/icons/search.png";
import { nextTick, ref, watch } from "vue"; import { nextTick, ref, watch } from "vue";
import { debounce } from "lodash"; import { debounce } from "lodash";
// 该组件为公共展示组件:网络请求/下载等业务由父组件处理;查找、高亮、显示切换等通用交互在组件内部封装。
// 图标资源固定使用组件内置文件,保证组件资源自包含。
const props = defineProps({ const props = defineProps({
reportData: { type: Array, default: () => [] }, reportData: { type: Array, default: () => [] },
}); });
...@@ -88,6 +85,23 @@ const findWordMax = ref(0); ...@@ -88,6 +85,23 @@ const findWordMax = ref(0);
const originReportData = ref([]); const originReportData = ref([]);
const displayReportData = ref([]); const displayReportData = ref([]);
const headerActions = [
{
key: "download",
text: "下载",
icon: defaultDownloadIcon,
iconGapClass: "icon-gap-4",
onClick: () => emits("download"),
},
{
key: "search",
text: "查找",
icon: defaultSearchIcon,
iconGapClass: "icon-gap-6",
onClick: () => handleFindWord("open"),
},
];
function escapeRegExp(text) { function escapeRegExp(text) {
return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
} }
...@@ -137,7 +151,9 @@ const doUpdateWord = () => { ...@@ -137,7 +151,9 @@ const doUpdateWord = () => {
displayReportData.value = originReportData.value.map((item) => { displayReportData.value = originReportData.value.map((item) => {
const cn = applyHighlightToText(item.content, term); const cn = applyHighlightToText(item.content, term);
const en = isTranslate.value ? applyHighlightToText(item.contentEn, term) : { html: item.contentEn, count: 0 }; const en = isTranslate.value
? applyHighlightToText(item.contentEn, term)
: { html: item.contentEn, count: 0 };
findWordMax.value += cn.count + en.count; findWordMax.value += cn.count + en.count;
return { return {
...item, ...item,
...@@ -222,7 +238,6 @@ watch(isTranslate, () => { ...@@ -222,7 +238,6 @@ watch(isTranslate, () => {
width: 1600px; width: 1600px;
background-color: white; background-color: white;
padding: 0 60px; padding: 0 60px;
height: 20px;
flex: auto; flex: auto;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
...@@ -245,7 +260,6 @@ watch(isTranslate, () => { ...@@ -245,7 +260,6 @@ watch(isTranslate, () => {
display: flex; display: flex;
align-items: center; align-items: center;
.find-word-input { .find-word-input {
width: 20px;
flex: auto; flex: auto;
} }
.find-word-limit { .find-word-limit {
...@@ -265,8 +279,7 @@ watch(isTranslate, () => { ...@@ -265,8 +279,7 @@ watch(isTranslate, () => {
font-size: 20px; font-size: 20px;
line-height: 20px; line-height: 20px;
font-weight: 700; font-weight: 700;
width: 20px; flex: 1;
flex: auto;
} }
.btn { .btn {
margin-left: 10px; margin-left: 10px;
...@@ -310,25 +323,11 @@ watch(isTranslate, () => { ...@@ -310,25 +323,11 @@ watch(isTranslate, () => {
} }
.report-main { .report-main {
height: 20px;
flex: auto; flex: auto;
box-sizing: border-box; box-sizing: border-box;
padding-top: 10px; padding-top: 10px;
&::-webkit-scrollbar { .no-content {
display: none;
}
&::-webkit-scrollbar-thumb {
background: #c1c1c1;
border-radius: 4px;
}
&::-webkit-scrollbar-track {
background: #f1f1f1;
}
.noContent {
height: 100%; height: 100%;
display: flex; display: flex;
align-items: center; align-items: center;
...@@ -347,10 +346,6 @@ watch(isTranslate, () => { ...@@ -347,10 +346,6 @@ watch(isTranslate, () => {
min-height: 100px; min-height: 100px;
gap: 80px; gap: 80px;
&:last-child {
border-bottom: none;
}
.content-en, .content-en,
.content-cn { .content-cn {
width: 50%; width: 50%;
......
<template> <template>
<div class="bill-original-text-page"> <div class="bill-original-text-page">
<div class="page-header"> <DecreeOriginal :report-data="reportData" @download="handleDownload" />
<div class="page-title">法案原文</div>
<div class="page-actions">
<div class="action-btn" @click="handleBack">返回</div>
</div>
</div>
<div class="page-content">
<iframe v-if="billFullText" :src="billFullText" width="100%" height="100%" frameborder="0"></iframe>
<div v-else class="empty-state">暂无原文</div>
</div>
</div> </div>
</template> </template>
<script setup> <script setup>
import { onMounted, ref } from "vue"; import { ref } from "vue";
import { useRoute, useRouter } from "vue-router"; import DecreeOriginal from "@/components/base/DecreeOriginal/index.vue";
import { getBillFullText } from "@/api/bill";
const route = useRoute();
const router = useRouter();
const billFullText = ref("");
const getBillFullTextFn = async () => { // 旧“法案原文”功能/按钮全部废弃:页面仅承载通用原文组件,后续接入新接口再赋值。
const res = await getBillFullText({ const reportData = ref([]);
id: route.query.billId
});
if (res.code === 200 && res.data) {
billFullText.value = typeof res.data === "string" ? res.data.trim() : res.data;
}
};
const handleBack = () => { const handleDownload = () => {
router.back(); // 后续接入新接口/下载逻辑
}; };
onMounted(() => {
getBillFullTextFn();
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.bill-original-text-page { .bill-original-text-page {
width: 100%; width: 100%;
box-sizing: border-box; height: 100%;
background: rgba(248, 249, 250, 1);
padding: 0 0 20px;
.page-header {
width: 100%;
height: 64px;
display: flex;
align-items: center;
justify-content: space-between;
.page-title {
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 18px;
font-weight: 700;
}
.page-actions {
display: flex;
justify-content: flex-end;
.action-btn {
cursor: pointer;
height: 32px;
line-height: 32px;
padding: 0 12px;
border-radius: 6px;
border: 1px solid rgba(230, 231, 232, 1);
background: rgba(255, 255, 255, 1);
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
}
}
}
.page-content {
width: 100%;
height: calc(100vh - 320px);
min-height: 600px;
background: #fff;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
overflow: hidden;
iframe {
display: block;
}
.empty-state {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei;
font-size: 14px;
}
}
} }
</style> </style>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论