提交 e8ae5570 authored 作者: 朱政's avatar 朱政

Merge branch 'pre' into zz-dev

流水线 #410 已通过 于阶段
in 1 分 44 秒
<template>
<div class="summary-cards-panel" :style="{ width: panelWidth }" v-loading="loading">
<div class="date-box">
<div class="date-icon" v-if="tipIcon">
<img :src="tipIcon" alt="" />
</div>
<div class="date-text">{{ descriptionText }}</div>
<TimeTabPane @time-click="onTimeClick" :activeTime="activeTime" />
</div>
<div class="cards-box" v-if="cards.length">
<div class="summary-item" v-for="item in cards" :key="item.id || item.name">
<div class="item-left">
<img :src="item.avatar || defaultAvatar" alt="" />
</div>
<div class="item-center" @click="emit('name-click', item)">
<div class="item-name one-line-ellipsis">{{ item.name }}</div>
<div v-if="item.subText" class="item-sub-text one-line-ellipsis">{{ item.subText }}</div>
</div>
<el-popover content="跳转至数据资源库" placement="top">
<template #reference>
<div class="item-total" @click="emit('count-click', item)">{{ item.count }}{{ countSuffix }}</div>
</template>
</el-popover>
<el-icon color="var(--color-primary-100)">
<ArrowRightBold />
</el-icon>
<div class="item-dot" v-if="item.delta">+{{ item.delta }}</div>
</div>
<div v-if="shouldShowMoreCard" class="summary-item" @click="emit('more-click')">
<div class="item-more">{{ moreText }} ({{ totalCount }}家)</div>
<el-icon color="var(--color-primary-100)">
<ArrowRightBold />
</el-icon>
</div>
</div>
<div v-else class="cards-empty">
<el-empty :description="emptyText" :image-size="80" />
</div>
</div>
</template>
<script setup>
import TimeTabPane from "@/components/base/TimeTabPane/index.vue";
import { ArrowRightBold } from "@element-plus/icons-vue";
import { computed } from "vue";
const props = defineProps({
descriptionText: {
type: String,
default: ""
},
cards: {
type: Array,
default: () => []
},
totalCount: {
type: Number,
default: 0
},
showMoreCard: {
type: Boolean,
default: true
},
moreCardMinCount: {
type: Number,
default: 8
},
emptyText: {
type: String,
default: "暂无数据"
},
activeTime: {
type: String,
default: "近一年"
},
tipIcon: {
type: String,
default: ""
},
defaultAvatar: {
type: String,
default: ""
},
countSuffix: {
type: String,
default: "项"
},
moreText: {
type: String,
default: "查看全部机构"
},
panelWidth: {
type: String,
default: "1600px"
},
loading: {
type: Boolean,
default: false
}
});
const emit = defineEmits(["time-click", "name-click", "count-click", "more-click"]);
const shouldShowMoreCard = computed(() => {
if (!props.showMoreCard) return false;
if (props.moreCardMinCount <= 0) return true;
return (props.cards?.length || 0) >= props.moreCardMinCount;
});
const onTimeClick = event => {
emit("time-click", event);
};
</script>
<style scoped lang="scss">
.summary-cards-panel {
margin: 48px auto 0;
.date-box {
display: flex;
align-items: center;
.date-icon {
width: 16px;
height: 16px;
font-size: 0;
margin-right: 6px;
img {
width: 100%;
height: 100%;
}
}
.date-text {
width: 20px;
flex: auto;
font-size: 18px;
line-height: 18px;
font-family: Source Han Sans CN;
color: var(--text-primary-80-color);
}
}
.cards-box {
margin: 20px 0 64px;
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 80px;
gap: 16px;
font-family: Microsoft YaHei;
.summary-item {
padding: 0 16px;
display: flex;
box-sizing: border-box;
background: rgba(255, 255, 255, 0.65);
border: 1px solid rgba(255, 255, 255, 1);
border-radius: 10px;
box-shadow: 0 0 20px 0 rgba(25, 69, 130, 0.1);
align-items: center;
justify-content: center;
cursor: pointer;
transition: transform 0.3s ease, box-shadow 0.3s ease;
position: relative;
&:hover {
transform: translateY(-3px);
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
}
.item-left {
width: 48px;
height: 48px;
font-size: 0;
img {
width: 100%;
height: 100%;
}
}
.item-center {
width: 20px;
flex: auto;
margin: 0 16px;
cursor: pointer;
}
.item-name {
color: rgba(59, 65, 75, 1);
font-size: 20px;
font-weight: 700;
line-height: 20px;
&:hover {
color: var(--color-primary-100);
text-decoration: underline;
}
}
.item-sub-text {
margin-top: 6px;
color: var(--text-primary-50-color);
font-size: 14px;
line-height: 18px;
}
.item-total {
font-size: 20px;
margin-right: 2px;
white-space: nowrap;
font-weight: 700;
line-height: 20px;
color: var(--color-primary-100);
&:hover {
text-decoration: underline;
}
}
.item-more {
font-size: 16px;
margin-right: 12px;
white-space: nowrap;
font-weight: 700;
line-height: 16px;
color: var(--color-primary-100);
}
.item-dot {
position: absolute;
right: -13px;
top: -10px;
padding: 0 8px;
height: 26px;
background-color: #ff4d4f;
color: white;
font-size: 16px;
line-height: 26px;
font-family: Source Han Sans CN;
border-radius: 14px;
letter-spacing: 1px;
}
}
}
.cards-empty {
margin: 20px 0 64px;
height: 120px;
display: flex;
align-items: center;
justify-content: center;
background: rgba(255, 255, 255, 0.65);
border: 1px solid rgba(255, 255, 255, 1);
border-radius: 10px;
box-shadow: 0 0 20px 0 rgba(25, 69, 130, 0.1);
}
}
</style>
...@@ -15,6 +15,7 @@ const BillProgressForecast = () => import('@/views/bill/influence/ProgressForeca ...@@ -15,6 +15,7 @@ const BillProgressForecast = () => import('@/views/bill/influence/ProgressForeca
const BillInfluenceScientificResearch = () => import('@/views/bill/influence/scientificResearch/index.vue') const BillInfluenceScientificResearch = () => import('@/views/bill/influence/scientificResearch/index.vue')
const BillRelevantCircumstance = () => import('@/views/bill/relevantCircumstance/index.vue') const BillRelevantCircumstance = () => import('@/views/bill/relevantCircumstance/index.vue')
const BillVersionCompare = () => import('@/views/bill/versionCompare/index.vue') const BillVersionCompare = () => import('@/views/bill/versionCompare/index.vue')
const BillAllCommittee = () => import('@/views/bill/allCommittee/index.vue')
const billRoutes = [ const billRoutes = [
...@@ -28,6 +29,19 @@ const billRoutes = [ ...@@ -28,6 +29,19 @@ const billRoutes = [
isShowHeader: true isShowHeader: true
} }
}, },
{
path: "/bill/allCommittee",
name: "BillAllCommittee",
component: BillAllCommittee,
meta: {
title: "法案委员会列表",
isShowHeader: true
}
},
{
path: "/billAllCommittee",
redirect: "/bill/allCommittee"
},
{ {
path: "/billLayout", path: "/billLayout",
name: "BillLayoutContainer", name: "BillLayoutContainer",
......
<template>
<div class="view-box">
<div class="container-box">
<div class="hard-box">
<div class="hard-name text-title-0-show">美国国会委员会</div>
<div class="hard-num text-title-2-show">{{ committeeInfo.total }}</div>
<div style="width: 0; flex: auto"></div>
<div class="hard-input">
<el-input
v-model="committeeInfo.keyWord"
@keyup.enter="onAllCommittee()"
style="width: 100%; height: 100%"
:suffix-icon="Search"
placeholder="搜索委员会"
/>
</div>
</div>
<div class="date-box">
<div class="date-text">近期美国国会各委员会涉华提案数量汇总</div>
<TimeTabPane @time-click="handleDateChange" activeTime="近一年" />
</div>
<div class="committee-list" ref="refCommittee" v-loading="committeeInfo.loading">
<div class="committee-item" v-for="item in committeeInfo.list" :key="item.id" @click="handleToDataLibrary(item)">
<div class="item-left">
<img :src="iconCommit" alt="" />
</div>
<div class="item-right">
<div class="item-name one-line-ellipsis">{{ item.name }}</div>
<div class="item-chamber one-line-ellipsis">{{ item.chamber }}</div>
</div>
<div class="item-total">{{ item.count }}</div>
<el-icon color="var(--color-primary-100)">
<ArrowRightBold />
</el-icon>
</div>
</div>
<div class="pagination-box">
<el-pagination
@current-change="onAllCommittee"
:pageSize="committeeInfo.pageSize"
:current-page="committeeInfo.pageNum"
background
layout="prev, pager, next"
:total="committeeInfo.total"
/>
</div>
</div>
</div>
</template>
<script setup name="BillAllCommittee">
import { onMounted, reactive, ref } from "vue";
import { Search } from "@element-plus/icons-vue";
import { ArrowRightBold } from "@element-plus/icons-vue";
import router from "@/router";
import TimeTabPane from "@/components/base/TimeTabPane/index.vue";
import { getStatisticsBillCountByCommittee } from "@/api/bill/billHome";
import iconCommit from "../billHome/assets/icons/icon-commit.png";
const committeeInfo = reactive({
loading: false,
pageNum: 1,
pageSize: 8,
total: 0,
keyWord: "",
dateDesc: "近一年",
list: []
});
const getChamberLabel = orgType => {
if (orgType === "Senate") return "参议院";
if (orgType === "House") return "众议院";
return orgType || "";
};
const onAllCommittee = async num => {
committeeInfo.pageNum = num || 1;
committeeInfo.loading = true;
try {
const res = await getStatisticsBillCountByCommittee({
dateDesc: committeeInfo.dateDesc
});
if (res.code === 200 && Array.isArray(res.data)) {
const source = res.data
.map(item => ({
id: `${item.orgType || ""}-${item.orgName || ""}`,
name: item.orgName,
chamber: getChamberLabel(item.orgType),
count: Number(item.count || 0)
}))
.filter(item => !committeeInfo.keyWord || item.name?.includes(committeeInfo.keyWord))
.sort((a, b) => (b.count || 0) - (a.count || 0));
committeeInfo.total = source.length;
const start = (committeeInfo.pageNum - 1) * committeeInfo.pageSize;
committeeInfo.list = source.slice(start, start + committeeInfo.pageSize);
} else {
committeeInfo.total = 0;
committeeInfo.list = [];
}
} catch (error) {
committeeInfo.total = 0;
committeeInfo.list = [];
}
committeeInfo.loading = false;
};
const handleDateChange = event => {
committeeInfo.dateDesc = event?.time || "近一年";
onAllCommittee();
};
const handleToDataLibrary = item => {
const route = router.resolve({
path: "/dataLibrary/countryBill",
query: {
selectedOrg: item.name,
selectedCongress: item.chamber
}
});
window.open(route.href, "_blank");
};
const refCommittee = ref();
onMounted(() => {
let height = 2;
if (refCommittee.value) {
height = Math.floor(refCommittee.value?.clientHeight / 120);
}
committeeInfo.pageSize = height * 4;
onAllCommittee();
});
</script>
<style scoped lang="scss">
.view-box {
width: 100%;
height: 100%;
background: url("../billHome/assets/images/background.png"), linear-gradient(180deg, rgba(229, 241, 254, 1) 0%, rgba(246, 251, 255, 0) 30%);
background-size: 100% 100%;
display: flex;
justify-content: center;
.container-box {
width: 1600px;
padding: 50px 0 20px;
display: flex;
flex-direction: column;
.hard-box {
display: flex;
align-items: center;
width: 100%;
.hard-name {
color: var(--text-primary-90-color);
height: 62px;
line-height: 62px !important;
}
.hard-num {
height: 36px;
background-color: var(--color-primary-100);
color: var(--bg-white-100);
border-radius: 18px;
line-height: 36px !important;
padding: 0 16px;
margin-left: 16px;
}
.hard-input {
background-color: var(--el-fill-color-blank);
border-radius: var(--el-border-radius-base);
box-shadow: 0 0 0 1px var(--el-border-color) inset;
box-sizing: border-box;
margin-left: 20px;
width: 180px;
height: 32px;
}
}
.date-box {
margin-top: 6px;
display: flex;
align-items: center;
width: 100%;
.date-text {
width: 20px;
flex: auto;
font-size: 18px;
line-height: 18px;
font-family: Source Han Sans CN;
color: var(--text-primary-80-color);
}
}
.committee-list {
width: 100%;
height: 20px;
padding: 16px 0;
margin-top: 10px;
flex: auto;
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 104px;
gap: 16px;
.committee-item {
padding: 0 16px;
display: flex;
background: rgba(255, 255, 255, 0.65);
border: 1px solid rgba(255, 255, 255, 1);
border-radius: 10px;
box-shadow: 0 0 20px 0 rgba(25, 69, 130, 0.1);
align-items: center;
cursor: pointer;
transition: transform 0.3s ease, box-shadow 0.3s ease;
&:hover {
transform: translateY(-3px);
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
}
.item-left {
width: 48px;
height: 48px;
margin-right: 12px;
img {
width: 100%;
height: 100%;
}
}
.item-right {
flex: auto;
min-width: 0;
.item-name {
font-size: 20px;
font-weight: 700;
line-height: 22px;
color: var(--text-primary-80-color);
}
.item-chamber {
margin-top: 6px;
font-size: 14px;
color: var(--text-primary-50-color);
}
}
.item-total {
font-size: 20px;
font-weight: 700;
line-height: 20px;
color: var(--color-primary-100);
margin-right: 6px;
}
}
}
.pagination-box {
display: flex;
justify-content: center;
}
}
}
</style>
...@@ -9,34 +9,22 @@ ...@@ -9,34 +9,22 @@
:containerRef="containerRef" areaName="法案" :enableBillTypeSwitch="true" defaultBillSearchType="federal" /> :containerRef="containerRef" areaName="法案" :enableBillTypeSwitch="true" defaultBillSearchType="federal" />
</div> </div>
<div class="committee-cards-section"> <SummaryCardsPanel
<div class="committee-cards-filter"> descriptionText="近期美国国会各委员会涉华提案数量汇总"
<span class="committee-cards-desc">近期美国国会各委员会涉华提案数量汇总</span> :cards="committeeCards"
<el-radio-group v-model="committeeTimeRange" class="committee-time-switch" size="default"> :totalCount="committeeTotalCount"
<el-radio-button v-for="item in committeeTimeOptions" :key="item.value" :value="item.value"> :tipIcon="box7HeaderIcon"
<span class="committee-time-switch-inner"> :defaultAvatar="iconCommit"
<el-icon v-if="committeeTimeRange === item.value" class="committee-time-switch-icon"> :loading="committeeLoading"
<Calendar /> activeTime="近一年"
</el-icon> emptyText="暂无数据"
{{ item.label }} moreText="查看全部委员会"
</span> :moreCardMinCount="7"
</el-radio-button> @time-click="handleCommitteeTimeClick"
</el-radio-group> @name-click="handleToDataLibrary"
</div> @count-click="handleToDataLibrary"
<div class="committee-cards-row"> @more-click="handleToCommitteeMore"
<div v-for="item in committeeCardList" :key="item.id" class="committee-card" />
@click="handleToDataLibrary(item)">
<div class="committee-card-icon">
<img :src="iconCommit" alt="委员会头像" />
</div>
<div class="committee-card-content">
<div class="committee-card-name">{{ item.name }}</div>
<div class="committee-card-chamber">{{ item.chamber }}</div>
</div>
<div class="committee-card-count">{{ item.count }}&gt;</div>
</div>
</div>
</div>
<DivideHeader id="position1" class="divide1" :titleText="'最新动态'"></DivideHeader> <DivideHeader id="position1" class="divide1" :titleText="'最新动态'"></DivideHeader>
<div class="home-content-center"> <div class="home-content-center">
...@@ -256,6 +244,7 @@ ...@@ -256,6 +244,7 @@
<script setup> <script setup>
import RiskSignal from "@/components/base/riskSignal/index.vue"; import RiskSignal from "@/components/base/riskSignal/index.vue";
import SummaryCardsPanel from "@/components/base/SummaryCardsPanel/index.vue";
import { onMounted, ref, onUnmounted, nextTick, watch, computed } from "vue"; import { onMounted, ref, onUnmounted, nextTick, watch, computed } from "vue";
import router from "@/router/index"; import router from "@/router/index";
import { navigateToViewRiskSignal, navigateToViewRiskSignalOpenFirstDetail } from "@/utils/riskSignalOverviewNavigate"; import { navigateToViewRiskSignal, navigateToViewRiskSignalOpenFirstDetail } from "@/utils/riskSignalOverviewNavigate";
...@@ -276,7 +265,7 @@ import { ...@@ -276,7 +265,7 @@ import {
import { getPersonSummaryInfo } from "@/api/common/index"; import { getPersonSummaryInfo } from "@/api/common/index";
import { getChartAnalysis } from "@/api/aiAnalysis/index"; import { getChartAnalysis } from "@/api/aiAnalysis/index";
import DivideHeader from "@/components/DivideHeader.vue"; import DivideHeader from "@/components/DivideHeader.vue";
import overviewMainBox from "@/components/base/boxBackground/overviewMainBox.vue"; import OverviewMainBox from "@/components/base/boxBackground/overviewMainBox.vue";
import OverviewCard from "./OverviewCard.vue"; import OverviewCard from "./OverviewCard.vue";
import ResourceLibrarySection from "./ResourceLibrarySection.vue"; import ResourceLibrarySection from "./ResourceLibrarySection.vue";
import { useContainerScroll } from "@/hooks/useScrollShow"; import { useContainerScroll } from "@/hooks/useScrollShow";
...@@ -295,7 +284,6 @@ import box7HeaderIcon from "./assets/images/box7-header-icon.png"; ...@@ -295,7 +284,6 @@ import box7HeaderIcon from "./assets/images/box7-header-icon.png";
import iconCommit from "./assets/icons/icon-commit.png"; import iconCommit from "./assets/icons/icon-commit.png";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import { Calendar } from "@element-plus/icons-vue";
import { useGotoNewsDetail } from "@/router/modules/news"; import { useGotoNewsDetail } from "@/router/modules/news";
// 跳转人物主页(MessageBubble 的 person-click 传入整条列表项,需取 personId) // 跳转人物主页(MessageBubble 的 person-click 传入整条列表项,需取 personId)
...@@ -369,15 +357,11 @@ const handleClickToCharacter = async item => { ...@@ -369,15 +357,11 @@ const handleClickToCharacter = async item => {
const containerRef = ref(null); const containerRef = ref(null);
const { isShow } = useContainerScroll(containerRef); const { isShow } = useContainerScroll(containerRef);
// 委员会卡片占位数据 // 委员会卡片数据
const committeeTimeRange = ref("近一月"); const committeeTimeRange = ref("近一年");
const committeeTimeOptions = [
{ label: "近一周", value: "近一周" },
{ label: "近一月", value: "近一月" },
{ label: "近一年", value: "近一年" },
{label:"全部时间", value: "全部时间"}
];
const committeeCardList = ref([]); const committeeCardList = ref([]);
const committeeTotalCount = ref(0);
const committeeLoading = ref(false);
const getChamberLabel = orgType => { const getChamberLabel = orgType => {
if (orgType === "Senate") return "参议院"; if (orgType === "Senate") return "参议院";
...@@ -385,27 +369,51 @@ const getChamberLabel = orgType => { ...@@ -385,27 +369,51 @@ const getChamberLabel = orgType => {
return orgType || ""; return orgType || "";
}; };
const committeeCards = computed(() => {
return committeeCardList.value.map(item => ({
id: item.id,
name: item.name,
subText: item.chamber,
count: item.count
}));
});
const handleGetCommitteeBillCount = async () => { const handleGetCommitteeBillCount = async () => {
committeeLoading.value = true;
try { try {
const res = await getStatisticsBillCountByCommittee({ const res = await getStatisticsBillCountByCommittee({
dateDesc: committeeTimeRange.value dateDesc: committeeTimeRange.value
}); });
if (res.code === 200 && Array.isArray(res.data)) { if (res.code === 200 && Array.isArray(res.data)) {
committeeCardList.value = res.data const mappedList = res.data
.map(item => ({ .map(item => ({
id: `${item.orgType || ""}-${item.orgName || ""}`, id: `${item.orgType || ""}-${item.orgName || ""}`,
name: item.orgName, name: item.orgName,
chamber: getChamberLabel(item.orgType), chamber: getChamberLabel(item.orgType),
count: Number(item.count || 0) count: Number(item.count || 0)
})) }))
.sort((a, b) => (b.count || 0) - (a.count || 0)) .sort((a, b) => (b.count || 0) - (a.count || 0));
.slice(0, 3); committeeTotalCount.value = mappedList.length;
committeeCardList.value = mappedList.slice(0, 3);
} else { } else {
committeeTotalCount.value = 0;
committeeCardList.value = []; committeeCardList.value = [];
} }
} catch (error) { } catch (error) {
committeeTotalCount.value = 0;
committeeCardList.value = []; committeeCardList.value = [];
} }
committeeLoading.value = false;
};
const handleCommitteeTimeClick = event => {
committeeTimeRange.value = event?.time || "近一年";
handleGetCommitteeBillCount();
};
const handleToCommitteeMore = () => {
const route = router.resolve({ path: "/bill/allCommittee" });
window.open(route.href, "_blank");
}; };
const hotBillList = ref([]); // 热门法案列表 const hotBillList = ref([]); // 热门法案列表
...@@ -1367,13 +1375,9 @@ watch(box8selectetedTime, () => { ...@@ -1367,13 +1375,9 @@ watch(box8selectetedTime, () => {
handleBox8Data(); handleBox8Data();
}); });
watch( onMounted(() => {
committeeTimeRange, handleGetCommitteeBillCount();
() => { });
handleGetCommitteeBillCount();
},
{ immediate: true }
);
const handleToPosi = id => { const handleToPosi = id => {
const element = document.getElementById(id); const element = document.getElementById(id);
...@@ -1409,16 +1413,25 @@ const handleResize = () => { ...@@ -1409,16 +1413,25 @@ const handleResize = () => {
// 下钻至资源库 // 下钻至资源库
const handleToDataLibrary = (item) => { const handleToDataLibrary = (item) => {
// console.log('item', item); window.sessionStorage.setItem("curTabName", item.id);
const selectParam = { const curRoute = router.resolve({
selectedOrg: item.name, path: "/institution",
selectedCongress: item.chamber query: {
} id: item.id
const route = router.resolve({ }
path: "/dataLibrary/countryBill",
query: selectParam
}); });
window.open(route.href, "_blank"); window.open(curRoute.href, "_blank");
// console.log('item', item);
// const selectParam = {
// selectedOrg: item.name,
// selectedCongress: item.chamber
// }
// const route = router.resolve({
// path: "/dataLibrary/countryBill",
// query: selectParam
// });
// window.open(route.href, "_blank");
} }
......
...@@ -134,9 +134,10 @@ const handleAnalysisClick = analysisType => { ...@@ -134,9 +134,10 @@ const handleAnalysisClick = analysisType => {
// 进展预测 -> 法案简介页(法案进展) // 进展预测 -> 法案简介页(法案进展)
if (analysisType === "forsee") { if (analysisType === "forsee") {
router.push({ const target = router.resolve({
path: `/billLayout/ProgressForecast/${billId}`, path: `/billLayout/ProgressForecast/${billId}`,
}); });
window.open(target.href, "_blank");
return; return;
} }
......
<template> <template>
<div class="industry-wrap"> <BillPageShell>
<div class="left"> <div class="wrap">
<AnalysisBox title="涉及行业" :showAllBtn="false" width="100%" height="100%"> <div class="left">
<div class="left-main"> <AnalysisBox title="涉及行业" :showAllBtn="false" width="100%" height="100%">
<div class="left-center"> <div class="left-main">
<el-select v-model="curHylyId" placeholder="请选择领域" class="left-center-select" <div class="left-center">
@change="handleIndustryChange"> <el-select
<el-option v-for="item in industryList" :key="item.id" :label="item.name || item.hylymc" v-model="curHylyId"
:value="item.id" /> placeholder="请选择领域"
</el-select> class="left-center-select"
<el-input v-model="companySearchKeyword" placeholder="搜索实体" class="left-center-search" @change="handleIndustryChange"
:suffix-icon="Search" clearable /> >
</div> <el-option
<div class="left-list"> v-for="item in industryList"
<div class="left-list-title">实体名称</div> :key="item.id"
<div class="left-list-content"> :label="item.name || item.hylymc"
<el-empty v-if="!curCompanyList?.length" style="padding: 60px 0;" description="暂无数据" :value="item.id"
:image-size="100" /> />
<el-scrollbar v-else height="100%" always> </el-select>
<div class="item-box"> <el-input
<div class="item" v-model="companySearchKeyword"
:class="{ itemActive: companyActiveIndex === ((currentPage - 1) * pageSize + idx) }" placeholder="搜索实体"
@click="handleClickCompany(val, idx)" v-for="(val, idx) in curCompanyList" class="left-center-search"
:key="val.id"> :suffix-icon="Search"
<div class="item-icon"> clearable
<img :src="defaultIcon2" alt="" class="item-img" /> />
</div> </div>
<div class="title" <div class="left-list">
:class="{ titleActive: companyActiveIndex === ((currentPage - 1) * pageSize + idx) }"> <div class="left-list-title">实体名称</div>
{{ val.name }} <div class="left-list-content">
</div> <el-empty
<div class="icon"> v-if="!curCompanyList?.length"
<img v-if="val.status === 'up'" :src="upIcon" alt="" /> style="padding: 60px 0;"
<img v-if="val.status === 'down'" :src="downIcon" alt="" /> description="暂无数据"
:image-size="100"
/>
<el-scrollbar v-else height="100%" always>
<div class="item-box">
<div
v-for="(val, idx) in curCompanyList"
:key="val.id"
class="item"
:class="{ itemActive: companyActiveIndex === ((currentPage - 1) * pageSize + idx) }"
@click="handleClickCompany(val, idx)"
>
<div class="item-icon">
<img :src="defaultIcon2" alt="" class="item-img" />
</div>
<div
class="title"
:class="{ titleActive: companyActiveIndex === ((currentPage - 1) * pageSize + idx) }"
>
{{ val.name }}
</div>
<div class="icon">
<img v-if="val.status === 'up'" :src="upIcon" alt="" />
<img v-if="val.status === 'down'" :src="downIcon" alt="" />
</div>
</div> </div>
</div> </div>
</div> </el-scrollbar>
</el-scrollbar> </div>
</div> </div>
</div> <div class="left-pagination">
<div class="left-pagination"> <div class="left-pagination-left">{{ `共 ${filteredCompanyList.length} 项` }}</div>
<div class="left-pagination-left">{{ `共 ${filteredCompanyList.length} 项` }}</div> <div class="left-pagination-right">
<div class="left-pagination-right"> <el-pagination
<el-pagination @current-change="handleCurrentChange" :pageSize="pageSize" @current-change="handleCurrentChange"
:current-page="currentPage" size="small" background layout="prev, pager, next" :pageSize="pageSize"
:total="filteredCompanyList.length" /> :current-page="currentPage"
size="small"
background
layout="prev, pager, next"
:total="filteredCompanyList.length"
/>
</div>
</div> </div>
</div> </div>
</div> </AnalysisBox>
</AnalysisBox> </div>
</div> <div class="right">
<div class="box2"> <AnalysisBox :showAllBtn="false">
<AnalysisBox :showAllBtn="false"> <template #custom-title>
<template #custom-title> <div class="custom-title">
<div class="custom-title"> <div class="title-left">
<div class="title-left"> <div :class="['title-item', { 'title-active': contentType==1 }]" @click="headerContentType(1)">
<div :class="['title-item', {'title-active': contentType==1}]" @click="headerContentType(1)"> <div class="title-icon">
<div class="title-icon"> <img :src="contentType==1 ? icon1620 : icon1621" alt="" />
<img :src="contentType==1 ? icon1620 : icon1621" alt=""> </div>
<div>产业链</div>
</div> </div>
<div>产业链</div> <div :class="['title-item', { 'title-active': contentType==2 }]" @click="headerContentType(2)">
</div> <div class="title-icon">
<div :class="['title-item', {'title-active': contentType==2}]" @click="headerContentType(2)"> <img :src="contentType==2 ? icon422 : icon423" alt="" />
<div class="title-icon"> </div>
<img :src="contentType==2 ? icon422 : icon423" alt=""> <div>实体关系</div>
</div> </div>
<div>实体关系</div> </div>
<div class="title-right" v-if="contentType==1">
<el-select v-model="industryChain.id" style="width: 100%" @change="onDecreeChainNodes">
<el-option v-for="item in industryChain.list" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</div> </div>
</div> </div>
<div class="title-right" v-if="contentType==1"> </template>
<el-select v-model="industryChain.id" style="width: 100%" @change="onDecreeChainNodes"> <div class="box2-main">
<el-option v-for="item in industryChain.list" :key="item.id" :label="item.name" :value="item.id" /> <AiTips :tips="tips" />
</el-select> <div class="graph-box" v-if="contentType==1">
<ChartChain :listData="fishbone.list" :baseData="fishbone.base" />
</div>
<div class="graph-box" v-if="contentType==2 && graphInfo.nodes.length">
<GraphChart :nodes="graphInfo.nodes" :links="graphInfo.links" layoutType="force" />
</div> </div>
</div> </div>
</template> </AnalysisBox>
<div class="box2-main"> </div>
<AiTips :tips="tips" />
<div class="graph-box" v-if="contentType==1">
<ChartChain :listData="fishbone.list" :baseData="fishbone.base" />
</div>
<div class="graph-box" v-if="contentType==2 && graphInfo.nodes.length">
<GraphChart :nodes="graphInfo.nodes" :links="graphInfo.links" layoutType="force" />
</div>
</div>
</AnalysisBox>
</div> </div>
</div> </BillPageShell>
</template> </template>
<script setup> <script setup>
...@@ -94,6 +124,8 @@ import { ref, onMounted, onBeforeUnmount, nextTick, computed, watch, reactive } ...@@ -94,6 +124,8 @@ import { ref, onMounted, onBeforeUnmount, nextTick, computed, watch, reactive }
import { useRoute } from "vue-router"; import { useRoute } from "vue-router";
import * as echarts from "echarts"; import * as echarts from "echarts";
import BillPageShell from "@/views/bill/components/layout/BillPageShell.vue";
const route = useRoute(); const route = useRoute();
import { getCompanyList, getHylyList, getCompanyDetail } from "@/api/influence"; import { getCompanyList, getHylyList, getCompanyDetail } from "@/api/influence";
import getLineChart from "./utils/lineChart"; import getLineChart from "./utils/lineChart";
...@@ -809,7 +841,7 @@ onMounted(async () => { ...@@ -809,7 +841,7 @@ onMounted(async () => {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.industry-wrap { .wrap {
width: 100%; width: 100%;
height: 100%; height: 100%;
display: flex; display: flex;
...@@ -1012,7 +1044,7 @@ onMounted(async () => { ...@@ -1012,7 +1044,7 @@ onMounted(async () => {
.right { .right {
margin-top: 16px; margin-top: 16px;
margin-left: 16px; margin-left: 16px;
width: 1247px; width: 1104px;
height: 847px; height: 847px;
position: relative; position: relative;
...@@ -1487,7 +1519,7 @@ onMounted(async () => { ...@@ -1487,7 +1519,7 @@ onMounted(async () => {
} }
.box-footer { .box-footer {
width: 1218px; width: 100%;
height: 40px; height: 40px;
display: flex; display: flex;
box-sizing: border-box; box-sizing: border-box;
...@@ -1510,13 +1542,17 @@ onMounted(async () => { ...@@ -1510,13 +1542,17 @@ onMounted(async () => {
.box-footer-center { .box-footer-center {
margin-left: 13px; margin-left: 13px;
margin-top: 8px; margin-top: 8px;
width: 1119px; flex: 1;
min-width: 0;
height: 24px; height: 24px;
color: var(--color-main-active); color: var(--color-main-active);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
font-size: 14px; font-size: 14px;
font-weight: 400; font-weight: 400;
line-height: 24px; line-height: 24px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
} }
.box-footer-right { .box-footer-right {
...@@ -1539,10 +1575,10 @@ onMounted(async () => { ...@@ -1539,10 +1575,10 @@ onMounted(async () => {
} }
} }
.box2 { .right {
margin-top: 16px; margin-top: 16px;
margin-left: 16px; margin-left: 16px;
width: 1247px; width: 1104px;
height: 847px; height: 847px;
position: relative; position: relative;
......
...@@ -29,36 +29,22 @@ ...@@ -29,36 +29,22 @@
<div class="item-footer">分析报告</div> <div class="item-footer">分析报告</div>
</div> </div>
</div> --> </div> -->
<div class="date-box" v-if="keyOrganizationList.length"> <SummaryCardsPanel
<div class="date-icon"> descriptionText="近期美国各联邦政府机构发布涉华政令数量汇总"
<img :src="tipsTcon" alt=""> :cards="keyOrganizationCards"
</div> :totalCount="govInsList.length"
<div class="date-text">近期美国各联邦政府机构发布涉华政令数量汇总</div> :tipIcon="tipsTcon"
<TimeTabPane @time-click="onKeyOrganization" activeTime="近一年" /> :defaultAvatar="DefaultIcon2"
</div> :loading="keyOrganizationLoading"
<div class="home-main-header-item-box" v-if="keyOrganizationList.length"> activeTime="近一年"
<div class="organization-item" v-for="(item, index) in keyOrganizationList" :key="index"> emptyText="暂无数据"
<div class="item-left"> :moreCardMinCount="7"
<img :src="item.imgUrl || DefaultIcon2" alt="" /> moreText="查看全部机构"
</div> @time-click="onKeyOrganization"
<div class="item-right one-line-ellipsis" @click="handleToInstitution(item)">{{ item.orgName }}</div> @name-click="handleToInstitution"
<el-popover content="跳转至数据资源库" placement="top"> @count-click="handleToDataLibrary"
<template #reference> @more-click="onNavigateTo"
<div class="item-total" @click="handleToDataLibrary(item)">{{ item.totalOrderNum }}</div> />
</template>
</el-popover>
<el-icon color="var(--color-primary-100)">
<ArrowRightBold />
</el-icon>
<div class="item-dot" v-if="item.recentOrderNum">+{{ item.recentOrderNum }}</div>
</div>
<div class="organization-item" @click="onNavigateTo()">
<div class="item-more">查看全部机构 ({{ govInsList.length }}家)</div>
<el-icon color="var(--color-primary-100)">
<ArrowRightBold />
</el-icon>
</div>
</div>
</div> </div>
<DivideHeader id="position1" class="divide" :titleText="'最新动态'"></DivideHeader> <DivideHeader id="position1" class="divide" :titleText="'最新动态'"></DivideHeader>
<div class="home-main-center"> <div class="home-main-center">
...@@ -421,12 +407,12 @@ ...@@ -421,12 +407,12 @@
</template> </template>
<script setup> <script setup>
import { onMounted, ref, watch, nextTick, reactive } from "vue"; import { onMounted, ref, watch, nextTick, reactive, computed } from "vue";
import router from "@/router"; import router from "@/router";
import { navigateToViewRiskSignal, navigateToViewRiskSignalOpenFirstDetail } from "@/utils/riskSignalOverviewNavigate"; import { navigateToViewRiskSignal, navigateToViewRiskSignalOpenFirstDetail } from "@/utils/riskSignalOverviewNavigate";
import WordCloudChart from "@/components/base/WordCloundChart/index.vue" import WordCloudChart from "@/components/base/WordCloundChart/index.vue"
import SimplePagination from "@/components/SimplePagination.vue"; import SimplePagination from "@/components/SimplePagination.vue";
import TimeTabPane from '@/components/base/TimeTabPane/index.vue'; import SummaryCardsPanel from "@/components/base/SummaryCardsPanel/index.vue";
import AiButton from '@/components/base/Ai/AiButton/index.vue'; import AiButton from '@/components/base/Ai/AiButton/index.vue';
import AiPane from '@/components/base/Ai/AiPane/index.vue'; import AiPane from '@/components/base/Ai/AiPane/index.vue';
import { import {
...@@ -1158,11 +1144,13 @@ const handleSwithCurDecree = name => { ...@@ -1158,11 +1144,13 @@ const handleSwithCurDecree = name => {
// 关键机构 // 关键机构
const keyOrganizationList = ref([]); const keyOrganizationList = ref([]);
const keyOrganizationLoading = ref(false);
const onKeyOrganization = async (event) => { const onKeyOrganization = async (event) => {
let day = 365 let day = 365
if (event?.time === '近一周') day = 7 if (event?.time === '近一周') day = 7
if (event?.time === '近一月') day = 30 if (event?.time === '近一月') day = 30
if (event?.time === '近一年') day = 365 if (event?.time === '近一年') day = 365
keyOrganizationLoading.value = true;
try { try {
const res = await getKeyOrganization({ day }); const res = await getKeyOrganization({ day });
console.log("关键机构", res); console.log("关键机构", res);
...@@ -1170,8 +1158,20 @@ const onKeyOrganization = async (event) => { ...@@ -1170,8 +1158,20 @@ const onKeyOrganization = async (event) => {
keyOrganizationList.value = res.data; keyOrganizationList.value = res.data;
} }
} catch (error) { } } catch (error) { }
keyOrganizationLoading.value = false;
} }
const keyOrganizationCards = computed(() => {
return keyOrganizationList.value.map(item => ({
...item,
id: item.orgId,
name: item.orgName,
avatar: item.imgUrl,
count: item.totalOrderNum,
delta: item.recentOrderNum
}));
});
// 下钻至数据资源库 // 下钻至数据资源库
const handleToDataLibrary = (item) => { const handleToDataLibrary = (item) => {
const selectParam = { const selectParam = {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论