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

合并分支 'zy-dev' 到 'pre'

从 zy-dev 合并到 pre 查看合并请求 !298
流水线 #306 已通过 于阶段
in 5 分 43 秒
<template>
<div class="layout-container">
<div class="layout-main">
<div class="layout-main-center">
<div class="report-header">
<div class="report-title">政令原文</div>
<el-switch v-model="isHighlight" @change="handleHighlight" />
<div class="switch-label switch-label-left">高亮实体</div>
<el-switch v-model="isTranslate" @change="handleTranslate" />
<div class="switch-label">译文显示</div>
<div class="btn" @click="emits('download')">
<div class="icon icon-gap-4">
<img src="./assets/icons/download.png" alt="" />
</div>
<div class="text">下载</div>
</div>
<div class="btn" @click="handleFindWord('open')">
<div class="icon icon-gap-6">
<img src="./assets/icons/search.png" alt="" />
</div>
<div class="text">查找</div>
</div>
<div class="find-word-box" v-if="findWordBox">
<div class="find-word-input">
<el-input v-model="findWordTxt" placeholder="查找原文内容" @input="handleUpdateWord" />
</div>
<div class="find-word-limit">{{ findWordNum }}/{{ findWordMax }}</div>
<div class="find-word-icon" @click="handleFindWord('last')">
<el-icon><ArrowUp /></el-icon>
</div>
<div class="find-word-icon" @click="handleFindWord('next')">
<el-icon><ArrowDown /></el-icon>
</div>
<div class="find-word-icon" @click="handleFindWord('close')">
<el-icon><Close /></el-icon>
</div>
</div>
</div>
<div :class="['report-main', {'is-highlight': isHighlight}]">
<div v-if="!formatData.length" class="no-content">暂无数据</div>
<el-scrollbar v-else height="100%">
<div v-for="(item, index) in formatData" :key="index" class="content-row">
<div class="content-en" :class="{ 'only-show': !isTranslate }">
<template v-for="(node, num) in item.contentEn" :key="num">
<el-icon v-if="node.icon && isHighlight" color="#508fd4" size="14"><Search /></el-icon>
<span v-else-if="node.point" class="find-light-point"></span>
<span v-else-if="node.fill" :class="node.class" @click="handleHighLight(node)">{{ node.txt }}</span>
<span v-else :class="node.class">{{ node.txt }}</span>
</template>
</div>
<div class="content-ch" v-if="isTranslate">
<template v-for="(node, num) in item.contentCh" :key="num">
<el-icon v-if="node.icon && isHighlight" color="#508fd4" size="14"><Search /></el-icon>
<span v-else-if="node.point" class="find-light-point"></span>
<span v-else-if="node.fill" :class="node.class" @click="handleHighLight(node)">{{ node.txt }}</span>
<span v-else :class="node.class">{{ node.txt }}</span>
</template>
</div>
</div>
</el-scrollbar>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { nextTick, ref } from "vue";
import { debounce } from "lodash";
import { extractTextEntity } from "@/api/intelligent";
const emits = defineEmits(["download"]);
const isHighlight = ref(true); // 是否高亮实体
const isTranslate = ref(true); // 是否显示译文
const handleTranslate = () => {
if (findWordTxt.value?.trim()) handleUpdateWord()
}
const findWordTxt = ref("");
const findWordBox = ref(false);
const findWordNum = ref(0);
const findWordMax = ref(0);
const formatData = ref([])
const handleUpdateWord = debounce(() => {
findWordNum.value = 0;
findWordMax.value = 0;
formatData.value = originData.map(item => {
return {
contentEn: onHighlightedText(item.contentEn, keywordEn),
contentCh: isTranslate.value ? onHighlightedText(item.contentCh, keywordCh) : [],
}
})
if (findWordMax.value) {
findWordNum.value = 1;
nextTick(updateActiveHighlight)
}
}, 300);
function handleFindWord(event) {
switch (event) {
case "open":
findWordBox.value = true;
break;
case "last":
if (findWordMax.value > 1) {
findWordNum.value = findWordNum.value === 1 ? findWordMax.value : findWordNum.value - 1;
updateActiveHighlight();
}
break;
case "next":
if (findWordMax.value > 1) {
findWordNum.value = findWordNum.value === findWordMax.value ? 1 : findWordNum.value + 1;
updateActiveHighlight();
}
break;
case "close":
findWordBox.value = false;
findWordTxt.value = "";
handleUpdateWord();
break;
}
}
const updateActiveHighlight = () => {
if (!findWordNum.value) return
const spans = document.querySelectorAll("span.find-light-point");
spans.forEach((span, index) => {
if (index + 1 === findWordNum.value) span.scrollIntoView({});
});
}
// 政令原文信息
let originData = []
let keywordCh = []
let keywordEn = []
const setOriginalData = (data) => {
originData = []
let num = Math.max(data.content.length, data.contentEn.length)
for (let i = 0; i < num; i++) {
let obj = {
contentCh: data.content[i] || "",
contentEn: data.contentEn[i] || "",
}
originData.push(obj);
}
let allEn = ""
let allCh = ""
formatData.value = originData.map(item => {
allEn += item.contentEn + "。"
allCh += item.contentCh + "。"
return {
contentEn: [{txt: item.contentEn, class: ""}],
contentCh: [{txt: item.contentCh, class: ""}]
}
})
extractTextEntity(allEn || "").then(res => {
if (res?.result?.length) keywordEn = res.result || []
originData.forEach((item, index) => {
formatData.value[index].contentEn = onHighlightedText(item.contentEn, keywordEn);
})
})
extractTextEntity(allCh || "").then(res => {
if (res?.result?.length) keywordCh = res.result || []
if (isTranslate.value) {
originData.forEach((item, index) => {
formatData.value[index].contentCh = onHighlightedText(item.contentCh, keywordCh);
})
}
})
}
defineExpose({ setOriginalData })
// 文本分割
const onHighlightedText = (text, nounList) => {
if (text === "") return []
// 获取区间(合并相邻/重叠),并自动过滤空关键词
const getIntervals = (str, keywords) => {
const intervals = [];
for (const kw of keywords) {
if (!kw) continue; // 跳过空字符串,防止无限循环
let idx = 0;
while ((idx = str.indexOf(kw, idx)) !== -1) {
intervals.push({ start: idx, end: idx + kw.length });
idx += kw.length;
}
}
if (!intervals.length) return [];
intervals.sort((a, b) => a.start - b.start);
const merged = [intervals[0]];
for (let i = 1; i < intervals.length; i++) {
const prev = merged[merged.length - 1];
const curr = intervals[i];
if (curr.start <= prev.end) {
prev.end = Math.max(prev.end, curr.end);
} else {
merged.push(curr);
}
}
return merged;
};
// 处理空搜索文本
let textTrim = findWordTxt.value.trim() || "";
const searchIntervals = textTrim ? getIntervals(text, [textTrim]) : [];
const nounIntervals = getIntervals(text, nounList.map(n => n.text_span));
// 收集分割点
const points = new Set([0, text.length]);
[...searchIntervals, ...nounIntervals].forEach(({ start, end }) => {
points.add(start);
points.add(end);
});
const sortedPoints = Array.from(points).sort((a, b) => a - b);
const list = [];
for (let i = 0; i < sortedPoints.length - 1; i++) {
const start = sortedPoints[i];
const end = sortedPoints[i + 1];
if (start === end) continue;
const fragment = text.slice(start, end);
const findLight = searchIntervals.some(s => start >= s.start && end <= s.end);
const highLight = nounIntervals.some(n => start >= n.start && end <= n.end);
const classes = [];
if (findLight) classes.push("find-light");
if (highLight) classes.push("high-light");
const textItem = { txt: fragment, class: classes.join(" ") };
if (highLight) {
const nounInterval = nounIntervals.find(n => start >= n.start && end <= n.end);
if (nounInterval) {
textItem.fill = text.slice(nounInterval.start, nounInterval.end);
}
}
list.push(textItem);
// 实体区间结束后添加图标
const iconAdded = new Set();
for (const nounInterval of nounIntervals) {
const key = `${nounInterval.start}-${nounInterval.end}`;
if (end === nounInterval.end && !iconAdded.has(key)) {
list.push({ icon: true, class: "" });
iconAdded.add(key);
break;
}
}
// 搜索区间结束后添加锚点
const pointAdded = new Set();
for (const searchInterval of searchIntervals) {
const key = `${searchInterval.start}-${searchInterval.end}`;
if (end === searchInterval.end && !pointAdded.has(key)) {
findWordMax.value++;
list.push({ point: true, class: "" });
pointAdded.add(key);
break;
}
}
}
return list;
};
// 点击高亮实体
import { useGotoSearchResults } from "@/router/modules/comprehensiveSearch";
const gotoSearchResults = useGotoSearchResults();
const handleHighLight = (node) => {
gotoSearchResults(node.fill, '')
}
</script>
<style lang="scss" scoped>
.is-highlight .high-light {
color: var(--color-primary-100);
cursor: pointer;
}
.find-light {
background-color: #ffff00;
}
.layout-container {
width: 100%;
height: 100%;
background-color: #f7f8f9;
.layout-main {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
.layout-main-center {
width: 1600px;
background-color: white;
padding: 0 60px;
flex: auto;
height: 100%;
min-height: 0;
display: flex;
flex-direction: column;
.report-header {
height: 80px;
display: flex;
align-items: center;
border-bottom: solid 1px rgba(234, 236, 238, 1);
margin: 0 20px 10px;
position: relative;
.find-word-box {
position: absolute;
top: -50px;
right: 0px;
width: 430px;
height: 60px;
border: 1px solid rgba(230, 231, 232, 1);
background-color: white;
border-radius: 6px;
display: flex;
align-items: center;
.find-word-input {
flex: auto;
}
.find-word-limit {
border-right: solid 1px rgba(230, 231, 232, 1);
color: #5f656c;
padding-right: 16px;
}
.find-word-icon {
padding: 10px 12px;
margin: 0 2px;
cursor: pointer;
}
}
.report-title {
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 20px;
line-height: 20px;
font-weight: 700;
flex: 1;
}
.btn {
margin-left: 10px;
width: 88px;
height: 32px;
box-sizing: border-box;
border: 1px solid rgba(230, 231, 232, 1);
border-radius: 6px;
background: rgba(255, 255, 255, 1);
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
.text {
height: 24px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-style: Regular;
font-size: 14px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0px;
text-align: left;
}
.icon {
width: 16px;
height: 16px;
font-size: 0px;
img {
width: 100%;
height: 100%;
}
}
.icon-gap-4 {
margin-right: 4px;
}
.icon-gap-6 {
margin-right: 6px;
}
}
}
.report-main {
flex: auto;
height: 20px;
padding: 10px 0;
:deep(.el-scrollbar) {
height: 100%;
}
.no-content {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-style: Regular;
font-size: 20px;
font-weight: 400;
}
.content-row {
display: flex;
width: 100%;
padding: 0 20px;
min-height: 100px;
gap: 80px;
.content-en,
.content-ch {
width: 50%;
flex: auto;
padding-bottom: 40px;
box-sizing: border-box;
font-size: 16px;
line-height: 1.8;
color: #3b414b;
font-family: Microsoft YaHei;
text-align: justify;
white-space: pre-wrap;
}
.only-show {
padding-bottom: 10px;
}
}
}
}
}
}
.switch-label {
margin-left: 6px;
}
.switch-label-left {
margin-right: 10px;
}
:deep(.el-scrollbar__bar.is-vertical) {
right: 0px;
width: 4px;
background: transparent;
border-radius: 2px;
& > div {
background: #c5c7c9;
opacity: 1;
}
& > div:hover {
background: #505357;
}
}
</style>
......@@ -26,7 +26,7 @@
</div>
<div class="layout-main-center">
<BaseDecreeOriginal :report-data="reportData" @download="handleDownload" />
<newOriginal ref="refNewOriginal" @download="handleDownload"></newOriginal>
</div>
</div>
</div>
......@@ -38,7 +38,7 @@ import { useRoute } from "vue-router";
import { ElMessage } from "element-plus";
import { getDecreeSummary } from "@/api/decree/introduction";
import { getDecreeReport } from "@/api/decree/introduction";
import BaseDecreeOriginal from "@/components/base/DecreeOriginal/index.vue";
import newOriginal from "@/components/base/DecreeOriginal/newOriginal.vue";
const route = useRoute();
let pdfUrl = "";
......@@ -98,26 +98,16 @@ const handleGetSummary = async () => {
};
// 获取报告原文 - 修改为获取分段数组
const reportData = ref([]);
const refNewOriginal = ref(null);
const handleGetReport = async () => {
try {
const res = await getDecreeReport({id: route.query.id});
console.log("报告原文", res);
if (res.code === 200 && res.data) {
if (res.code === 200) {
pdfUrl = res.data.pdfUrl;
const originData = [];
let num = Math.max(res.data.content.length, res.data.contentEn.length)
for (let i = 0; i < num; i++) {
let obj = {
content: res.data.content[i] || "",
contentEn: res.data.contentEn[i] || "",
num: i + 1,
}
originData.push(obj);
}
reportData.value = JSON.parse(JSON.stringify(originData));
refNewOriginal.value.setOriginalData({...res.data});
}
} catch (error) { }
} catch (error) {}
};
onMounted(() => {
......
......@@ -16,14 +16,12 @@
<div class="timeline-content-card">
<div class="item-head">
<div :class="`item-tag tag-${item.sortcode}`">{{ item.sortcode }}</div>
<div class="item-name">{{ item.searchname }}</div>
<div class="item-name one-line-ellipsis">{{ item.searchname }}</div>
<div class="item-state">
<span class="dot"></span> {{ item.casestatus }}
</div>
</div>
<div class="card-body">
{{ item.content }}
</div>
<div class="card-body">{{ item.content }}</div>
<div class="card-footer">
<div class="footer-left-tags">
<AreaTag v-for="(name, num) in item.searchArea" :key="num" :tagName="name"></AreaTag>
......@@ -129,7 +127,7 @@ const onNavigateToDetail = item => {
.timeline-content-card {
width: 20px;
flex: auto;
padding: 2px 16px 0;
padding: 4px 16px 0;
margin-bottom: 30px;
&:hover .item-head .item-name {
......
......@@ -32,39 +32,26 @@
<div class="wrapper-main">
<div class="left">
<!-- 科技领域 -->
<div class="left-box">
<div class="left-header">
<div class="icon"></div>
<div class="title">{{ "科技领域" }}</div>
</div>
<div class="left-main">
<el-checkbox-group class="checkbox-group" v-model="checkedAreaList" @change="handleCheckedAreasChange">
<el-checkbox class="filter-checkbox" label="全部领域"> 全部领域 </el-checkbox>
<el-checkbox v-for="area in surveyAreaList" :key="area.id" :label="area.id" class="filter-checkbox">
{{ area.name }}
</el-checkbox>
</el-checkbox-group>
<div class="check-box">
<div class="check-head">
<div class="head-name">{{ "科技领域" }}</div>
</div>
<el-checkbox-group class="check-list" v-model="checkedAreaList" @change="handleCheckedAreasChange">
<el-checkbox class="check-item" v-for="item in surveyAreaList" :key="item.id" :label="item.id">
{{ item.name }}
</el-checkbox>
</el-checkbox-group>
</div>
<!-- 发布时间 -->
<div class="left-box">
<div class="left-header">
<div class="icon"></div>
<div class="title">{{ "发布时间" }}</div>
<div class="check-box">
<div class="check-head">
<div class="head-name">{{ "发布时间" }}</div>
</div>
<div class="left-main">
<el-checkbox-group class="checkbox-group" v-model="checkedSurveyYears" @change="handleCheckedYearsChange">
<el-checkbox class="filter-checkbox" label="全部时间"> 全部时间 </el-checkbox>
<el-checkbox v-for="year in displayedYearList" :key="year.id" :label="year.id" class="filter-checkbox">
<el-checkbox-group class="check-list" v-model="checkedYearList" @change="handleCheckedYearsChange">
<el-checkbox class="check-item" v-for="year in surveyYearList" :key="year.id" :label="year.id">
{{ year.name }}
</el-checkbox>
<div v-if="surveyYearList.length > 6" class="expand-btn" @click="isYearExpanded = !isYearExpanded">
{{ isYearExpanded ? "收起" : "更早" }}
<el-icon>
<ArrowUp v-if="isYearExpanded" />
<ArrowDown v-else />
</el-icon>
</div>
</el-checkbox-group>
</div>
</div>
......@@ -98,8 +85,8 @@
</template>
<script setup>
import { ref, onMounted, watch, computed } from "vue";
import { Search, ArrowDown, ArrowUp } from "@element-plus/icons-vue";
import { ref, onMounted, watch } from "vue";
import { Search } from "@element-plus/icons-vue";
import { getSearchAllArea, getSearchAllYear, getSurveyList } from "@/api/marketAccessRestrictions";
import SurveyHistory from "@/views/marketAccessRestrictions/com/SurveyHistory.vue"
......@@ -116,42 +103,49 @@ const handleSwithSort = () => {
// 科技领域过滤
const surveyAreaList = ref([]);
const checkedAreaList = ref([]);
const checkAllAreas = ref(true);
const isIndeterminateAreas = ref(false);
const handleCheckAllAreasChange = val => {
checkedAreaList.value = val ? surveyAreaList.value.map(a => a.id) : [];
isIndeterminateAreas.value = false;
const checkedAreaList = ref(['']);
const handleGetSearchAllArea = async () => {
try {
const res = await getSearchAllArea({ sortCode: "232" });
if (res.code === 200) {
surveyAreaList.value = res.data.map(item => ({ name: item.AREANAME, id: item.AREACODE }));
}
} catch (error) {}
surveyAreaList.value.unshift({ name: "全部领域", id: "" });
};
const handleCheckedAreasChange = value => {
const checkedCount = value.length;
checkAllAreas.value = checkedCount === surveyAreaList.value.length;
isIndeterminateAreas.value = checkedCount > 0 && checkedCount < surveyAreaList.value.length;
const handleCheckedAreasChange = event => {
if (event.length && event[event.length-1] !== "") {
checkedAreaList.value = event.filter(item => item !== "");
} else {
checkedAreaList.value = [""];
}
currentPage.value = 1;
handleFetchSurveyList();
};
// 发布时间过滤
const surveyYearList = ref([]);
const checkedSurveyYears = ref([]);
const checkAllYears = ref(true);
const isIndeterminateYears = ref(false);
const isYearExpanded = ref(false);
const displayedYearList = computed(() => {
if (isYearExpanded.value) return surveyYearList.value;
return surveyYearList.value.slice(0, 6);
});
const handleCheckAllYearsChange = val => {
checkedSurveyYears.value = val ? surveyYearList.value.map(y => y.id) : [];
isIndeterminateYears.value = false;
const checkedYearList = ref(['']);
const handleGetSearchAllYear = async () => {
try {
const res = await getSearchAllYear({ sortCode: "232" });
if (res.code === 200) {
let allYear = res.data.sort((a, b) => (b-a));
let beforeYear = allYear.slice(6).join(',');
surveyYearList.value = allYear.slice(0, 6).map(item => ({ name: item + "年", id: item }));
if (beforeYear) surveyYearList.value.push({ name: "更早", id: beforeYear });
}
} catch (error) {}
surveyYearList.value.unshift({ name: "全部时间", id: "" });
};
const handleCheckedYearsChange = value => {
const checkedCount = value.length;
checkAllYears.value = checkedCount === surveyYearList.value.length;
isIndeterminateYears.value = checkedCount > 0 && checkedCount < surveyYearList.value.length;
const handleCheckedYearsChange = event => {
if (event.length && event[event.length-1] !== "") {
checkedYearList.value = event.filter(item => item !== "");
} else {
checkedYearList.value = [""];
}
currentPage.value = 1;
handleFetchSurveyList();
};
// 数据列表
......@@ -169,8 +163,8 @@ const handleFetchSurveyList = async () => {
currentPage: currentPage.value - 1,
pageSize: pageSize.value,
sortCode: "232",
publishYear: checkAllYears.value ? "" : checkedSurveyYears.value.toString(),
Area: checkAllAreas.value ? "" : checkedAreaList.value.toString(),
publishYear: checkedYearList.value.join(',') || null,
Area: checkedAreaList.value.join(',') || null,
caseStatus: filterStage.value,
keywords: searchText.value,
sortField: "date",
......@@ -199,39 +193,12 @@ const handleSearch = () => {
};
// 监听过滤条件
watch([checkedSurveyYears, checkedAreaList, isSort, filterStage, filterParty, filterReason], () => {
watch([isSort, filterStage, filterParty, filterReason], () => {
if (isInitializing.value) return;
currentPage.value = 1;
handleFetchSurveyList();
});
const handleGetSearchAllArea = async () => {
try {
const res = await getSearchAllArea({ sortCode: "232" });
if (res.code === 200 && res.data) {
surveyAreaList.value = res.data.map(item => ({
name: item.AREANAME,
id: item.AREACODE
}));
handleCheckAllAreasChange(true);
}
} catch (error) {}
};
const handleGetSearchAllYear = async () => {
try {
const res = await getSearchAllYear({ sortCode: "232" });
if (res.code === 200 && res.data) {
const sortedYears = res.data.sort((a, b) => b - a);
surveyYearList.value = sortedYears.map(item => ({
name: item + "年",
id: item
}));
handleCheckAllYearsChange(true);
}
} catch (error) {}
};
onMounted(async () => {
await Promise.all([handleGetSearchAllArea(), handleGetSearchAllYear()]);
isInitializing.value = false;
......@@ -306,58 +273,50 @@ onMounted(async () => {
.left {
width: 360px;
min-height: 560px;
min-height: 300px;
height: fit-content;
padding-bottom: 20px;
border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(60, 87, 126, 0.2);
background: #fff;
.left-box {
margin-top: 17px;
.left-header {
display: flex;
align-items: center;
.icon {
.check-box {
margin-top: 18px;
.check-head {
position: relative;
margin-bottom: 12px;
&::before {
content: "";
position: absolute;
top: 0px;
left: 0px;
width: 8px;
height: 16px;
background: var(--color-main-active);
height: 100%;
background: var(--color-primary-100);
border-radius: 0 2px 2px 0;
}
.title {
margin-left: 17px;
color: var(--color-main-active);
.head-name {
margin-left: 25px;
color: var(--color-primary-100);
font-size: 16px;
font-weight: 700;
line-height: 16px;
font-family: Source Han Sans CN;
font-weight: bold;
}
}
}
.checkbox-group {
padding: 10px 0 0 25px;
.filter-checkbox {
width: 130px;
margin-bottom: 8px;
height: 32px;
:deep(.el-checkbox__label) {
font-size: 16px;
color: #5f656c;
}
}
.expand-btn {
color: var(--color-main-active);
font-size: 14px;
cursor: pointer;
display: flex;
align-items: center;
margin-top: 4px;
.el-icon {
margin-left: 4px;
.check-list {
padding: 0 10px 0 25px;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-gap: 0 12px;
.check-item {
width: 100%;
height: 32px;
:deep(.el-checkbox__label) {
font-family: Source Han Sans CN;
font-size: 16px;
color: var(--text-primary-65-color);
}
}
}
}
......
......@@ -21,39 +21,26 @@
<div class="wrapper-main">
<div class="left">
<!-- 科技领域 -->
<div class="left-box">
<div class="left-header">
<div class="icon"></div>
<div class="title">{{ "科技领域" }}</div>
</div>
<div class="left-main">
<el-checkbox-group class="checkbox-group" v-model="checkedAreaList" @change="handleCheckedAreasChange">
<el-checkbox class="filter-checkbox" label="全部领域"> 全部领域 </el-checkbox>
<el-checkbox v-for="area in surveyAreaList" :key="area.id" :label="area.id" class="filter-checkbox">
{{ area.name }}
</el-checkbox>
</el-checkbox-group>
<div class="check-box">
<div class="check-head">
<div class="head-name">{{ "科技领域" }}</div>
</div>
<el-checkbox-group class="check-list" v-model="checkedAreaList" @change="handleCheckedAreasChange">
<el-checkbox class="check-item" v-for="item in surveyAreaList" :key="item.id" :label="item.id">
{{ item.name }}
</el-checkbox>
</el-checkbox-group>
</div>
<!-- 发布时间 -->
<div class="left-box">
<div class="left-header">
<div class="icon"></div>
<div class="title">{{ "发布时间" }}</div>
<div class="check-box">
<div class="check-head">
<div class="head-name">{{ "发布时间" }}</div>
</div>
<div class="left-main">
<el-checkbox-group class="checkbox-group" v-model="checkedSurveyYears" @change="handleCheckedYearsChange">
<el-checkbox class="filter-checkbox" label="全部时间"> 全部时间 </el-checkbox>
<el-checkbox v-for="year in displayedYearList" :key="year.id" :label="year.id" class="filter-checkbox">
<el-checkbox-group class="check-list" v-model="checkedYearList" @change="handleCheckedYearsChange">
<el-checkbox class="check-item" v-for="year in surveyYearList" :key="year.id" :label="year.id">
{{ year.name }}
</el-checkbox>
<div v-if="surveyYearList.length > 6" class="expand-btn" @click="isYearExpanded = !isYearExpanded">
{{ isYearExpanded ? "收起" : "更早" }}
<el-icon>
<ArrowUp v-if="isYearExpanded" />
<ArrowDown v-else />
</el-icon>
</div>
</el-checkbox-group>
</div>
</div>
......@@ -78,8 +65,8 @@
</template>
<script setup>
import { ref, onMounted, watch, computed } from "vue";
import { Search, ArrowDown, ArrowUp } from "@element-plus/icons-vue";
import { ref, onMounted, watch } from "vue";
import { Search } from "@element-plus/icons-vue";
import { getSearchAllArea, getSearchAllYear, getSurveyList } from "@/api/marketAccessRestrictions";
import SurveyHistory from "@/views/marketAccessRestrictions/com/SurveyHistory.vue"
......@@ -88,46 +75,51 @@ const handleSwithSort = () => {
isSort.value = !isSort.value;
};
const surveyYearList = ref([]);
const checkedSurveyYears = ref([]);
const isYearExpanded = ref(false);
const displayedYearList = computed(() => {
if (isYearExpanded.value) {
return surveyYearList.value;
}
return surveyYearList.value.slice(0, 6);
});
const checkAllYears = ref(false);
const isIndeterminateYears = ref(false);
const handleCheckAllYearsChange = (val) => {
checkedSurveyYears.value = val ? surveyYearList.value.map(y => y.id) : [];
isIndeterminateYears.value = false;
// 科技领域过滤
const surveyAreaList = ref([]);
const checkedAreaList = ref(['']);
const handleGetSearchAllArea = async () => {
try {
const res = await getSearchAllArea({ sortCode: "301" });
if (res.code === 200) {
surveyAreaList.value = res.data.map(item => ({ name: item.AREANAME, id: item.AREACODE }));
}
} catch (error) {}
surveyAreaList.value.unshift({ name: "全部领域", id: "" });
};
const handleCheckedYearsChange = (value) => {
const checkedCount = value.length;
checkAllYears.value = checkedCount === surveyYearList.value.length;
isIndeterminateYears.value = checkedCount > 0 && checkedCount < surveyYearList.value.length;
const handleCheckedAreasChange = event => {
if (event.length && event[event.length-1] !== "") {
checkedAreaList.value = event.filter(item => item !== "");
} else {
checkedAreaList.value = [""];
}
currentPage.value = 1;
handleFetchSurveyList();
};
const surveyAreaList = ref([]);
const checkedAreaList = ref([]);
const checkAllAreas = ref(false);
const isIndeterminateAreas = ref(false);
const handleCheckAllAreasChange = (val) => {
checkedAreaList.value = val ? surveyAreaList.value.map(a => a.id) : [];
isIndeterminateAreas.value = false;
// 发布时间过滤
const surveyYearList = ref([]);
const checkedYearList = ref(['']);
const handleGetSearchAllYear = async () => {
try {
const res = await getSearchAllYear({ sortCode: "301" });
if (res.code === 200) {
let allYear = res.data.sort((a, b) => (b-a));
let beforeYear = allYear.slice(6).join(',');
surveyYearList.value = allYear.slice(0, 6).map(item => ({ name: item + "年", id: item }));
if (beforeYear) surveyYearList.value.push({ name: "更早", id: beforeYear });
}
} catch (error) {}
surveyYearList.value.unshift({ name: "全部时间", id: "" });
};
const handleCheckedAreasChange = (value) => {
const checkedCount = value.length;
checkAllAreas.value = checkedCount === surveyAreaList.value.length;
isIndeterminateAreas.value = checkedCount > 0 && checkedCount < surveyAreaList.value.length;
const handleCheckedYearsChange = event => {
if (event.length && event[event.length-1] !== "") {
checkedYearList.value = event.filter(item => item !== "");
} else {
checkedYearList.value = [""];
}
currentPage.value = 1;
handleFetchSurveyList();
};
const totalDiscussNum = ref(0);
......@@ -145,8 +137,8 @@ const handleFetchSurveyList = async () => {
currentPage: currentPage.value - 1,
pageSize: pageSize.value,
sortCode: "301",
publishYear: checkAllYears.value ? "" : checkedSurveyYears.value.toString(),
Area: checkAllAreas.value ? "" : checkedAreaList.value.toString(),
publishYear: checkedYearList.value.join(',') || null,
Area: checkedAreaList.value.join(',') || null,
// keywords: searchText.value,
sortField: "date",
sortOrder: isSort.value ? "asc" : "desc"
......@@ -173,60 +165,11 @@ const handleSearch = () => {
handleFetchSurveyList();
};
watch(
[checkedSurveyYears, checkedAreaList, isSort],
() => {
if (isInitializing.value) return;
currentPage.value = 1;
handleFetchSurveyList();
},
{
deep: true
}
);
const handleGetSearchAllArea = async () => {
try {
const res = await getSearchAllArea({
sortCode: '301'
});
if(res.code === 200 && res.data) {
surveyAreaList.value = res.data.map(item => {
return {
name: item.AREANAME,
id: item.AREACODE
};
});
// 默认选中全部
checkAllAreas.value = true;
handleCheckAllAreasChange(true);
}
} catch (error) {
}
}
const handleGetSearchAllYear = async () => {
try {
const res = await getSearchAllYear({
sortCode: '301'
});
if(res.code === 200 && res.data) {
// 排序并格式化
const sortedYears = res.data.sort((a, b) => b - a);
surveyYearList.value = sortedYears.map(item => {
return {
name: item + '年',
id: item
};
});
// 默认选中全部
checkAllYears.value = true;
handleCheckAllYearsChange(true);
}
} catch (error) {
}
}
watch([isSort], () => {
if (isInitializing.value) return;
currentPage.value = 1;
handleFetchSurveyList();
});
onMounted(async () => {
await Promise.all([handleGetSearchAllArea(), handleGetSearchAllYear()]);
......@@ -309,58 +252,50 @@ onMounted(async () => {
.left {
width: 360px;
min-height: 560px;
min-height: 300px;
height: fit-content;
padding-bottom: 20px;
border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(60, 87, 126, 0.2);
background: #fff;
.left-box {
margin-top: 17px;
.left-header {
display: flex;
align-items: center;
.icon {
.check-box {
margin-top: 18px;
.check-head {
position: relative;
margin-bottom: 12px;
&::before {
content: "";
position: absolute;
top: 0px;
left: 0px;
width: 8px;
height: 16px;
background: var(--color-main-active);
height: 100%;
background: var(--color-primary-100);
border-radius: 0 2px 2px 0;
}
.title {
margin-left: 17px;
color: var(--color-main-active);
.head-name {
margin-left: 25px;
color: var(--color-primary-100);
font-size: 16px;
font-weight: 700;
line-height: 16px;
font-family: Source Han Sans CN;
font-weight: bold;
}
}
}
.checkbox-group {
padding: 10px 0 0 25px;
.filter-checkbox {
width: 130px;
margin-bottom: 8px;
height: 32px;
:deep(.el-checkbox__label) {
font-size: 16px;
color: #5f656c;
}
}
.expand-btn {
color: var(--color-main-active);
font-size: 14px;
cursor: pointer;
display: flex;
align-items: center;
margin-top: 4px;
.el-icon {
margin-left: 4px;
.check-list {
padding: 0 10px 0 25px;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-gap: 0 12px;
.check-item {
width: 100%;
height: 32px;
:deep(.el-checkbox__label) {
font-family: Source Han Sans CN;
font-size: 16px;
color: var(--text-primary-65-color);
}
}
}
}
......
......@@ -33,53 +33,37 @@
<div class="wrapper-main">
<div class="left">
<!-- 科技领域 -->
<div class="left-box">
<div class="left-header">
<div class="icon"></div>
<div class="title">{{ "科技领域" }}</div>
</div>
<div class="left-main">
<el-checkbox-group class="checkbox-group" v-model="checkedAreaList" @change="handleCheckedAreasChange">
<el-checkbox class="filter-checkbox" label="全部领域"> 全部领域 </el-checkbox>
<el-checkbox v-for="area in surveyAreaList" :key="area.id" :label="area.id" class="filter-checkbox">
{{ area.name }}
</el-checkbox>
</el-checkbox-group>
<div class="check-box">
<div class="check-head">
<div class="head-name">{{ "科技领域" }}</div>
</div>
<el-checkbox-group class="check-list" v-model="checkedAreaList" @change="handleCheckedAreasChange">
<el-checkbox class="check-item" v-for="item in surveyAreaList" :key="item.id" :label="item.id">
{{ item.name }}
</el-checkbox>
</el-checkbox-group>
</div>
<!-- 发布时间 -->
<div class="left-box">
<div class="left-header">
<div class="icon"></div>
<div class="title">{{ "发布时间" }}</div>
<div class="check-box">
<div class="check-head">
<div class="head-name">{{ "发布时间" }}</div>
</div>
<div class="left-main">
<el-checkbox-group class="checkbox-group" v-model="checkedSurveyYears" @change="handleCheckedYearsChange">
<el-checkbox class="filter-checkbox" label="全部时间"> 全部时间 </el-checkbox>
<el-checkbox v-for="year in displayedYearList" :key="year.id" :label="year.id" class="filter-checkbox">
<el-checkbox-group class="check-list" v-model="checkedYearList" @change="handleCheckedYearsChange">
<el-checkbox class="check-item" v-for="year in surveyYearList" :key="year.id" :label="year.id">
{{ year.name }}
</el-checkbox>
<div v-if="surveyYearList.length > 6" class="expand-btn" @click="isYearExpanded = !isYearExpanded">
{{ isYearExpanded ? "收起" : "更早" }}
<el-icon>
<ArrowUp v-if="isYearExpanded" />
<ArrowDown v-else />
</el-icon>
</div>
</el-checkbox-group>
</div>
</div>
<!-- 受调查国家/地区 -->
<div class="left-box">
<div class="left-header">
<div class="icon"></div>
<div class="title">{{ "受调查国家/地区" }}</div>
<div class="check-box">
<div class="check-head">
<div class="head-name">{{ "受调查国家/地区" }}</div>
</div>
<div class="left-main">
<el-checkbox-group class="checkbox-group" v-model="checkedCountryList"
@change="handleCheckedCountriesChange">
<el-checkbox class="filter-checkbox" label="全部"> 全部 </el-checkbox>
<el-checkbox v-for="area in surveyCountryList" :key="area.id" :label="area.id" class="filter-checkbox">
<el-checkbox-group class="check-list" v-model="checkedCountryList" @change="handleCheckedCountriesChange">
<el-checkbox class="check-item" v-for="area in surveyCountryList" :key="area.id" :label="area.id">
{{ area.name }}
</el-checkbox>
</el-checkbox-group>
......@@ -103,8 +87,8 @@
</template>
<script setup>
import { ref, onMounted, watch, computed } from "vue";
import { Search, ArrowDown, ArrowUp } from "@element-plus/icons-vue";
import { ref, onMounted, watch } from "vue";
import { Search } from "@element-plus/icons-vue";
import { getSearchAllArea, getSearchAllYear, getSurveyList, getSearchAllCountry } from "@/api/marketAccessRestrictions";
import AnalysisBox from "@/components/base/boxBackground/analysisBox.vue"
......@@ -131,61 +115,71 @@ const releaseTimeList = ref([
// 科技领域过滤
const surveyAreaList = ref([]);
const checkedAreaList = ref(['全部领域']);
const handleCheckedAreasChange = val => {
if (val.includes("全部领域") && val.length > 1) {
if (val[val.length - 1] === "全部领域") {
checkedAreaList.value = ["全部领域"];
} else {
checkedAreaList.value = val.filter(item => item !== "全部领域");
const checkedAreaList = ref(['']);
const handleGetSearchAllArea = async () => {
try {
const res = await getSearchAllArea({ sortCode: "337" });
if (res.code === 200) {
surveyAreaList.value = res.data.map(item => ({ name: item.AREANAME, id: item.AREACODE }));
}
} else if (val.length === 0) {
checkedAreaList.value = ["全部领域"];
} catch (error) {}
surveyAreaList.value.unshift({ name: "全部领域", id: "" });
};
const handleCheckedAreasChange = event => {
if (event.length && event[event.length-1] !== "") {
checkedAreaList.value = event.filter(item => item !== "");
} else {
checkedAreaList.value = [""];
}
currentPage.value = 1;
handleFetchSurveyList();
};
// 发布时间过滤
const surveyYearList = ref([]);
const checkedSurveyYears = ref(['全部时间']);
const isYearExpanded = ref(false);
const displayedYearList = computed(() => {
if (isYearExpanded.value) return surveyYearList.value;
return surveyYearList.value.slice(0, 6);
});
const handleCheckedYearsChange = value => {
// const checkedCount = value.length;
// checkAllYears.value = checkedCount === surveyYearList.value.length;
// isIndeterminateYears.value = checkedCount > 0 && checkedCount < surveyYearList.value.length;
if (val.includes("全部时间") && val.length > 1) {
if (val[val.length - 1] === "全部时间") {
checkedSurveyYears.value = ["全部时间"];
} else {
checkedSurveyYears.value = val.filter(item => item !== "全部时间");
const checkedYearList = ref(['']);
const handleGetSearchAllYear = async () => {
try {
const res = await getSearchAllYear({ sortCode: "337" });
if (res.code === 200) {
let allYear = res.data.sort((a, b) => (b-a));
let beforeYear = allYear.slice(6).join(',');
surveyYearList.value = allYear.slice(0, 6).map(item => ({ name: item + "年", id: item }));
if (beforeYear) surveyYearList.value.push({ name: "更早", id: beforeYear });
}
} else if (val.length === 0) {
checkedSurveyYears.value = ["全部时间"];
} catch (error) {}
surveyYearList.value.unshift({ name: "全部时间", id: "" });
};
const handleCheckedYearsChange = event => {
if (event.length && event[event.length-1] !== "") {
checkedYearList.value = event.filter(item => item !== "");
} else {
checkedYearList.value = [""];
}
currentPage.value = 1;
handleFetchSurveyList();
};
// 受调查国家/地区过滤
const surveyCountryList = ref([]);
const checkedCountryList = ref(['全部']);
const handleCheckedCountriesChange = val => {
if (val.includes("全部") && val.length > 1) {
if (val[val.length - 1] === "全部") {
checkedCountryList.value = ["全部"];
} else {
checkedCountryList.value = val.filter(item => item !== "全部");
const checkedCountryList = ref(['']);
const handleGetSearchAllCountry = async () => {
try {
const res = await getSearchAllCountry();
if (res.code === 200) {
surveyCountryList.value = res.data.map(item => ({ name: item.COUNTRYNAME, id: item.COUNTRYID }));
}
} else if (val.length === 0) {
checkedCountryList.value = ["全部"];
} catch (error) {}
surveyCountryList.value.unshift({ name: "全部", id: "" });
};
const handleCheckedCountriesChange = event => {
if (event.length && event[event.length-1] !== "") {
checkedCountryList.value = event.filter(item => item !== "");
} else {
checkedCountryList.value = [""];
}
currentPage.value = 1;
handleFetchSurveyList();
};
// 数据列表
......@@ -203,9 +197,9 @@ const handleFetchSurveyList = async () => {
currentPage: currentPage.value - 1,
pageSize: pageSize.value,
sortCode: "337",
publishYear: checkedSurveyYears.value[0] === '全部时间' ? null : checkedSurveyYears.value.toString(),
Area: checkedAreaList.value[0] === '全部领域' ? null : checkedAreaList.value.toString(),
searchCountry: checkedCountryList.value[0] === '全部' ? null : checkedCountryList.value.toString(),
publishYear: checkedYearList.value.join(',') || null,
Area: checkedAreaList.value.join(',') || null,
searchCountry: checkedCountryList.value.join(',') || null,
caseStatus: filterStage.value ? filterStage.value : null,
keywords: searchText.value ? searchText.value : null,
sortField: "date",
......@@ -234,52 +228,11 @@ const handleSearch = () => {
};
// 监听过滤条件
watch(
[checkedSurveyYears, checkedAreaList, checkedCountryList, isSort, filterStage, filterParty, filterReason],
() => {
if (isInitializing.value) return;
currentPage.value = 1;
handleFetchSurveyList();
}
);
const handleGetSearchAllArea = async () => {
try {
const res = await getSearchAllArea({ sortCode: "337" });
if (res.code === 200 && res.data) {
surveyAreaList.value = res.data.map(item => ({
name: item.AREANAME,
id: item.AREACODE
}));
handleCheckAllAreasChange(true);
}
} catch (error) { }
};
const handleGetSearchAllYear = async () => {
try {
const res = await getSearchAllYear({ sortCode: "337" });
if (res.code === 200 && res.data) {
const sortedYears = res.data.sort((a, b) => b - a);
surveyYearList.value = sortedYears.map(item => ({
name: item + "年",
id: item
}));
}
} catch (error) { }
};
const handleGetSearchAllCountry = async () => {
try {
const res = await getSearchAllCountry();
if (res.code === 200 && res.data) {
surveyCountryList.value = res.data.map(item => ({
name: item.COUNTRYNAME,
id: item.COUNTRYID
}));
}
} catch (error) { }
};
watch([isSort, filterStage, filterParty, filterReason], () => {
if (isInitializing.value) return;
currentPage.value = 1;
handleFetchSurveyList();
});
onMounted(async () => {
await Promise.all([handleGetSearchAllArea(), handleGetSearchAllYear(), handleGetSearchAllCountry()]);
......@@ -360,58 +313,50 @@ onMounted(async () => {
.left {
width: 360px;
min-height: 560px;
min-height: 300px;
height: fit-content;
padding-bottom: 20px;
border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(60, 87, 126, 0.2);
background: #fff;
.left-box {
margin-top: 17px;
.left-header {
display: flex;
align-items: center;
.icon {
.check-box {
margin-top: 18px;
.check-head {
position: relative;
margin-bottom: 12px;
&::before {
content: "";
position: absolute;
top: 0px;
left: 0px;
width: 8px;
height: 16px;
background: var(--color-main-active);
height: 100%;
background: var(--color-primary-100);
border-radius: 0 2px 2px 0;
}
.title {
margin-left: 17px;
color: var(--color-main-active);
font-size: 16px;
font-weight: 700;
}
}
}
.checkbox-group {
padding: 10px 0 0 25px;
.filter-checkbox {
width: 130px;
margin-bottom: 8px;
height: 32px;
:deep(.el-checkbox__label) {
.head-name {
margin-left: 25px;
color: var(--color-primary-100);
font-size: 16px;
color: #5f656c;
line-height: 16px;
font-family: Source Han Sans CN;
font-weight: bold;
}
}
.expand-btn {
color: var(--color-main-active);
font-size: 14px;
cursor: pointer;
display: flex;
align-items: center;
margin-top: 4px;
.el-icon {
margin-left: 4px;
.check-list {
padding: 0 10px 0 25px;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-gap: 0 12px;
.check-item {
width: 100%;
height: 32px;
:deep(.el-checkbox__label) {
font-family: Source Han Sans CN;
font-size: 16px;
color: var(--text-primary-65-color);
}
}
}
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论