提交 95f8d886 authored 作者: coderBryanFu's avatar coderBryanFu

fix:概览页打压遏制时间线模块修改

......@@ -20,7 +20,7 @@ export function getBillInfo(params) {
export function getBillPerson(params) {
return request({
method: 'GET',
url: `/bill/billInfoBean/person/${params.billId}`,
url: `/api/billInfoBean/person/${params.billId}`,
params,
})
}
......
......@@ -111,7 +111,7 @@ export function getBillPostOrg(params) {
export function getBillProcess(params) {
return request({
method: 'GET',
url: `/bill/BillOverview/billsProcess/${params.year}`,
url: `/api/BillOverview/billsProcess/${params.year}`,
})
}
......@@ -119,7 +119,7 @@ export function getBillProcess(params) {
export function getBills(params, signal) {
return request({
method: 'GET',
url: `/bill/BillOverview/bills`,
url: `/api/BillOverview/bills`,
params,
signal
})
......@@ -129,7 +129,7 @@ export function getBills(params, signal) {
export function getBillsPerson(params, signal) {
return request({
method: 'GET',
url: `/bill/BillOverview/billsPerson`,
url: `/api/BillOverview/billsPerson`,
params,
signal
})
......
......@@ -16,7 +16,7 @@
<div :class="{
itemLeftStatus1: item[props.riskLevel] === '特别重大',
itemLeftStatus2: item[props.riskLevel] === '重大风险',
itemLeftStatus3: item[props.riskLevel] === '较大风险',
itemLeftStatus3: item[props.riskLevel] === '较大风险' || item[props.riskLevel] === '中等风险',
itemLeftStatus4: item[props.riskLevel] === '一般风险' || !item[props.riskLevel],
itemLeftStatus5: item[props.riskLevel] === '低风险',
}">
......
<template>
<div class="search-container" v-show="!isShow">
<div class="search-type-tabs" v-if="enableBillTypeSwitch">
<div class="search-type-tab" :class="{ active: billSearchType === 'federal' }"
@click="handleChangeBillSearchType('federal')">
<div
class="search-type-tab"
:class="{ active: billSearchType === 'federal' }"
@click="handleChangeBillSearchType('federal')"
>
联邦议会
</div>
<div class="search-type-tab" :class="{ active: billSearchType === 'state' }"
@click="handleChangeBillSearchType('state')">
<div
class="search-type-tab"
:class="{ active: billSearchType === 'state' }"
@click="handleChangeBillSearchType('state')"
>
州议会
</div>
</div>
<div class="search-main" :class="{ 'search-main-with-tabs': enableBillTypeSwitch }">
<input v-model="store.searchBillText" :placeholder="placeholder" @keyup.enter="handleSearch"
class="search-input" />
<input v-model="store.searchBillText" :placeholder="placeholder" @keyup.enter="handleSearch" class="search-input" />
<div class="search-btn" @click="handleSearch">
<img src="@/assets/icons/search-icon.png" alt />
搜索
......@@ -32,7 +37,7 @@
</div>
</div>
<div class="btn" @click="handleToPosi('position2')">
<div class="btn-text">咨询要闻</div>
<div class="btn-text">资讯要闻</div>
<div class="btn-icon">
<img src="@/assets/icons/arrow-right-icon.png" alt />
</div>
......@@ -62,14 +67,7 @@ import { useWrittingAsstaintStore } from "@/stores/writtingAsstaintStore";
const store = useWrittingAsstaintStore();
const router = useRouter();
const {
countInfo,
containerRef,
placeholder,
areaName,
enableBillTypeSwitch,
defaultBillSearchType
} = defineProps({
const { countInfo, containerRef, placeholder, areaName, enableBillTypeSwitch, defaultBillSearchType } = defineProps({
countInfo: {
type: Array,
default: () => []
......@@ -138,11 +136,9 @@ watchEffect(() => {
if (isShow.value) {
homeMainRef.value.classList.add("scroll-main");
homeMainRef.value.classList.add("scrollHomeMain");
} else {
homeMainRef.value.classList.remove("scroll-main");
homeMainRef.value.classList.remove("scrollHomeMain");
}
store.changeIsShowSearchBar(isShow.value);
......
<script setup>
</script>
<template>
<div class="flex-display box">
<div class="img"></div>
<div class="flex-fill txt text-tip-1">
<slot></slot>
</div>
<div class="arrow"><span></span></div>
</div>
</template>
<style scoped lang="scss">
@use '@/styles/common.scss';
.box {
background-color: var(--color-primary-2);
flex-direction: row;
gap: 10px;
justify-content: center;
align-items: center;
padding: 6px 12px;
border-radius: 4px;
border: 1px solid var(--color-primary-10);
color: var(--color-primary-100);
}
.img {
width: 19px;
height: 20px;
background-image: url("@/assets/icons/model.png");
}
.txt {
flex: 1;
min-width: 0;
word-wrap: break-word;
word-break: break-word;
overflow-wrap: break-word;
max-width: 100%;
}
.arrow {
border-radius: 50%;
min-width: 24px;
width: 24px;
height: 24px;
background: var(--color-primary-10);
display: flex;
align-items: center;
justify-content: center;
span {
font-size: 22px;
font-weight: bold;
position: relative;
top: -3px;
/* 向上偏移2px */
}
}
</style>
\ No newline at end of file
......@@ -7,9 +7,14 @@
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
}
.flex-display{
.flex-display {
display: flex;
}
.flex-fill {
flex: 1;
}
// 文本超出指定行数省略号显示
@mixin text-ellipsis($line-clamp) {
overflow: hidden;
......@@ -26,64 +31,67 @@
word-break: break-word;
/* 允许单词换行 */
}
//禁止换行
.text-nowrap{
.text-nowrap {
white-space: nowrap;
}
/***文本样式***/
.text-base{
color: var(--color-primary-80);
.text-base {
color: var(--color-primary-80);
}
//0级标题
.text-title-0{
.text-title-0 {
@extend .text-base;
color: var(--color-primary-90);
font-size: 32px;
}
.text-title-0-bold{
.text-title-0-bold {
@extend .text-title-0;
font-weight: Bold;
}
.text-title-0-show{
.text-title-0-show {
@extend .text-title-0;
font-size: 48px;
font-family: "YouSheBiaoTiHei";
}
//1级标题
.text-title-1{
.text-title-1 {
@extend .text-base;
color: var(--color-primary-90);
font-size: 24px;
}
.text-title-1-bold{
.text-title-1-bold {
@extend .text-title-1;
font-weight: Bold;
}
.text-title-1-show{
.text-title-1-show {
@extend .text-title-1;
font-size: 30px;
font-family: "YouSheBiaoTiHei";
}
//2级标题
.text-title-2{
.text-title-2 {
@extend .text-base;
color: var(--color-primary-90);
font-size: 20px;
line-height:26px;
line-height: 26px;
}
.text-title-2-bold{
.text-title-2-bold {
@extend .text-title-2;
font-weight: Bold;
}
.text-title-2-show{
.text-title-2-show {
@extend .text-title-2;
font-size: 24px;
font-family: "YouSheBiaoTiHei";
......@@ -91,19 +99,19 @@
}
//3级标题
.text-title-3{
.text-title-3 {
@extend .text-base;
color: var(--color-primary-90);
font-size: 18px;
line-height:24px;
line-height: 24px;
}
.text-title-3-bold{
.text-title-3-bold {
@extend .text-title-3;
font-weight: Bold;
}
.text-title-3-show{
.text-title-3-show {
@extend .text-title-3;
font-size: 20px;
font-family: "YouSheBiaoTiHei";
......@@ -111,58 +119,60 @@
}
//正文
.text-regular{
.text-regular {
@extend .text-base;
font-size: 16px;
line-height:30px;
line-height: 30px;
}
//正文-加粗
.text-bold{
.text-bold {
@extend .text-base;
font-weight: Bold;
}
//正文-紧凑
.text-compact{
.text-compact {
@extend .text-base;
font-size: 16px;
line-height:24px;
line-height: 24px;
}
.text-compact-bold{
.text-compact-bold {
@extend .text-base;
font-size: 16px;
line-height:24px;
line-height: 24px;
font-weight: Bold;
}
//1级提示文字
.text-tip-1{
.text-tip-1 {
@extend .text-base;
color: var(--color-primary-90);
font-size: 16px;
line-height:24px;
line-height: 24px;
}
.text-tip-1-bold{
.text-tip-1-bold {
@extend .text-tip-1;
font-weight: Bold;
}
//2级提示文字
.text-tip-2{
.text-tip-2 {
@extend .text-base;
color: var(--color-primary-90);
font-size: 14px;
line-height:22px;
line-height: 22px;
}
.text-tip-2-bold{
.text-tip-2-bold {
@extend .text-tip-2;
font-weight: Bold;
}
//3级提示文字
.text-tip-3{
.text-tip-3 {
@extend .text-base;
color: var(--color-primary-90);
font-size: 12px;
......
@use "common";
/***通用页面***/
.common-page {
font-family: "Microsoft Yahei", "PingFang SC", sans-serif;
margin: 16px auto;
width: 1600px;
align-items: center;
......
@use "common";
/***没有nav下划线***/
.common-descriptions .el-descriptions__label{
@extend .text-tip-1-bold;
color: var(--text-primary-80-color);
}
.common-descriptions .el-descriptions__content{
@extend .text-tip-1;
color: var(--text-primary-80-color);
/***通用描述组件***/
.common-descriptions {
.el-descriptions__label {
@extend .text-tip-1-bold;
color: var(--text-primary-80-color);
}
.common-descriptions .el-descriptions__content {
@extend .text-tip-1;
color: var(--text-primary-80-color);
}
}
\ No newline at end of file
@use "common";
/***没有nav下划线***/
.tabs-nav-no-wrap .el-tabs__nav-wrap::after{
height: 0px !important;
width: 0px !important;
.tabs-nav-no-wrap {
.el-tabs__nav-wrap::after {
height: 0px !important;
width: 0px !important;
}
}
/***nav as card***/
.tabs-header-as-card .el-tabs__header:not(.disinheritance .el-tabs__header) {
@extend .background-as-card;
padding: 2px;
.tabs-header-as-card {
.el-tabs__header:not(.disinheritance .el-tabs__header) {
@extend .background-as-card;
padding: 2px;
}
}
/***作为按钮样式的tabs-bar***/
/*选中无下划线*/
.tabs-bar-as-btn .el-tabs__active-bar:not(.disinheritance .el-tabs__active-bar) {
height: 0px;
}
.tabs-bar-as-btn {
.el-tabs__active-bar:not(.disinheritance .el-tabs__active-bar) {
height: 0px;
}
/*定义字体*/
.tabs-bar-as-btn .el-tabs__item:not(.disinheritance .el-tabs__item) {
font-size: 20px;
font-family: "Source Han Sans CN-Regular";
font-weight: Regular;
line-height: 26px;
height: 50px;
}
/*定义字体*/
.el-tabs__item:not(.disinheritance .el-tabs__item) {
font-size: 20px;
font-family: "Source Han Sans CN-Regular";
font-weight: Regular;
line-height: 26px;
height: 50px;
}
/*激活时按钮样式*/
.tabs-bar-as-btn .el-tabs__item.is-active:not(.disinheritance .el-tabs__item){
/*激活时按钮样式*/
.el-tabs__item.is-active:not(.disinheritance .el-tabs__item) {
font-size: 24px;
font-family: "Source Han Sans CN-Bold";
font-weight: Bold;
font-size: 24px;
font-family: "Source Han Sans CN-Bold";
font-weight: Bold;
color: var(--color-primary-100);
border-width: 1px;
border-style: solid;
border-color: var(--color-primary-35);
border-radius: 10px;
background-color: var(--color-primary-2);
color: var(--color-primary-100);
border-width: 1px;
border-style: solid;
border-color: var(--color-primary-35);
border-radius: 10px;
background-color: var(--color-primary-2);
}
}
/***tabs-bar左边悬浮***/
.left-float-nav-tabs .el-tabs__item{
position:relative;
}
.left-float-nav-tabs .el-tabs__item.is-active{
background-color: aquamarine;
.left-float-nav-tabs {
// .el-tabs__header {
position: relative;
overflow: visible;
transform: translateZ(0);
/* 双重保障 */
/* 创建新的渲染层 */
/* 创建新的层叠上下文 */
.el-tabs__header {
// position: absolute;
left: 0;
top: 0;
z-index: 999;
background-color: red;
// margin-left: -20px;
}
// }
}
\ No newline at end of file
......@@ -74,7 +74,12 @@
<span>美对华领域打压遏制最新动态</span>
</div>
<div class="title-right-select">
<el-select v-model="selectedFieldForLatest" placeholder="全部领域" class="field-select">
<el-select
v-model="selectedFieldForLatest"
@change="handleFieldChange"
placeholder="全部领域"
class="field-select"
>
<el-option v-for="item in fieldOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</div>
......@@ -131,7 +136,7 @@
<simple-pagination
v-model:current-page="newsCurrentPage"
:page-size="pageSize"
:total="newsList.length"
:total="allNewsList.length"
@page-change="handleNewsPageChange"
/>
</div>
......@@ -215,7 +220,7 @@
<div class="bottom-item">
<div class="bottom-item-title">
<img :src="icon4" alt="" />
<span>美对领域打压遏制时间线</span>
<span>美对领域打压遏制时间线</span>
</div>
<el-select
v-model="selectedFieldTimeline"
......@@ -408,6 +413,12 @@ const newsList = ref([]);
const newsCurrentPage = ref(1);
const pageSize = ref(5); // 每页显示 5 条
const handleFieldChange = domainId => {
console.log("领域改变", domainId);
console.log("领域值 =>", selectedFieldForLatest.value);
getUSGovernmentLatestDynamicData();
};
// 总页数
const totalPages = computed(() => {
return Math.ceil(newsList.value.length / pageSize.value) || 1;
......@@ -445,10 +456,11 @@ const handleNextPage = () => {
const getUSGovernmentLatestDynamicData = async () => {
try {
const params = {
orgId: !!deptValueForLatest.value ? deptValueForLatest.value : null,
domainId: !!selectedFieldForLatest.value ? selectedFieldForLatest.value : null,
pageSize: 50,
currentPage: newsCurrentPage.value
};
console.log("领域值 =>", selectedFieldForLatest.value);
const res = await getUSGovernmentLatestDynamic(params);
if (res.code === 200 && res.data) {
// 将接口数据转换为 newsList 需要的格式
......
......@@ -185,8 +185,8 @@
<simple-pagination
v-model:current-page="rankCurrentPage"
:page-size="pageSize"
:total="rankingList.length"
:page-size="rankingPageSize"
:total="allRankingList.length"
@page-change="handleRankPageChange"
/>
</div>
......@@ -426,6 +426,7 @@ const getUSGovernmentSanctionHistoryData = async () => {
const loadingJointRank = ref(false);
const getUSGovernmentJointSanctionRankData = async () => {
loadingJointRank.value = true;
const params = {};
try {
const res = await getUSGovernmentJointSanctionRank();
if (res.code === 200 && res.data) {
......@@ -494,8 +495,8 @@ const updateDynamicListByPage = () => {
};
const updateRankListByPage = () => {
const start = (rankCurrentPage.value - 1) * pageSize.value;
const end = start + pageSize.value;
const start = (rankCurrentPage.value - 1) * rankingPageSize.value;
const end = start + rankingPageSize.value;
rankingList.value = allRankingList.value.slice(start, end);
};
// 点击科技要闻-跳转详情页
......@@ -792,31 +793,7 @@ const fieldOptions = ref([
{ label: "其他", value: "99" }
]);
const methodOptions = ref([
// { label: "全部制裁手段", value: "" },
// { label: "法案", value: "-1" },
// { label: "政令", value: "-2" },
// { label: "实体清单", value: "1" },
// { label: "特别国民指定清单", value: "2" },
// { label: "涉军企业", value: "3" },
// { label: "行业制裁识别清单", value: "4" },
// { label: "无法核实清单", value: "5" },
// { label: "军事最终用户清单", value: "6" },
// { label: "非SDN中国军工企业名单", value: "7" },
// { label: "拒绝往来人员清单", value: "8" },
// { label: "军事最终用途与最终用户规则", value: "9" },
// { label: "欧盟合并制裁清单", value: "10" },
// { label: "英国制裁清单", value: "11" },
// { label: "加拿大合并自主制裁清单", value: "12" },
// { label: "商业管制清单", value: "13" }
// { label: "232调查", value: "14" },
// { label: "Capta List (CAP) - Treasury Department", value: "15" },
// { label: "ITAR Debarred (DTC) - State Department", value: "16" },
// { label: "Nonproliferation Sanctions (ISN) - State Department", value: "17" },
// { label: "Non-SDN Menu-Based Sanctions List (NS-MBS List) - Treasury Department", value: "18" },
// { label: "Palestinian Legislative Council List (PLC) - Treasury Department", value: "19" },
// { label: "经验证最终用户清单", value: "20" }
]);
const methodOptions = ref([]);
const handleGetSanList = async () => {
const params = {
......@@ -832,16 +809,17 @@ const handleGetSanList = async () => {
value: item.id
};
});
methodValue.value = "";
}
} catch (error) {}
};
watch(
() => methodValue.value,
val => {
getDepartmentListData();
}
);
// watch(
// () => methodValue.value,
// val => {
// getDepartmentListData();
// }
// );
watch(
() => deptValue.value,
......@@ -854,6 +832,7 @@ const allDynamicData = ref([]);
const dynamicList = ref([]);
const newsCurrentPage = ref(1);
const pageSize = ref(5); // 每页显示 5 条
const rankingPageSize = ref(10);
const handleNewsPageChange = page => {
newsCurrentPage.value = page;
......@@ -1669,7 +1648,7 @@ const prev = () => {
// border-radius: 10px;
// border: 1px solid rgb(234, 236, 238);
border-bottom: 1px solid rgb(234, 236, 238);
padding: 12px 24px;
padding: 10px 24px;
margin-bottom: 12px;
box-sizing: border-box;
......
......@@ -6,10 +6,16 @@
<img src="./assets/leftbtn.png" alt class="left-btn" @click="prev" :class="{ disabled: startIndex === 0 }" />
<div class="content">
<div class="carousel-container" :style="{ transform: `translateX(-${startIndex * (307 + 16)}px)` }">
<div class="carousel-item" v-for="item, index in carouselList" :key="index">
<div class="carousel-item" v-for="(item, index) in carouselList" :key="index">
<div class="item-top">
<div class="top-img">
<img :src="ele" :class="{ img1: index !== 0 }" alt v-for="(ele, idx) in item.imageList" :key="idx" />
<img
:src="ele"
:class="{ img1: index !== 0 }"
alt
v-for="(ele, idx) in item.imageList"
:key="idx"
/>
</div>
<div class="top-num">{{ item.count }}</div>
</div>
......@@ -20,13 +26,18 @@
:key="idxx">
{{ ele.industryName }}
</div> -->
<AreaTag v-for="ele, idxx in item.industryList" :key="idxx" :tagName="ele.industryName"></AreaTag>
<AreaTag v-for="(ele, idxx) in item.industryList" :key="idxx" :tagName="ele.industryName"></AreaTag>
</div>
</div>
</div>
</div>
<img src="./assets/rightbtn.png" alt class="right-btn" @click="next"
:class="{ disabled: startIndex >= carouselList.length - 5 }" />
<img
src="./assets/rightbtn.png"
alt
class="right-btn"
@click="next"
:class="{ disabled: startIndex >= carouselList.length - 5 }"
/>
</div>
<!-- 排华联盟分布 -->
......@@ -48,8 +59,13 @@
<div class="item" v-for="(item, index) in countList" :key="index">
<div class="item-left">
<img :src="item.image" alt />
<el-tooltip effect="dark" :content="item.zhName" popper-class="common-prompt-popper" placement="top"
:show-after="500">
<el-tooltip
effect="dark"
:content="item.zhName"
popper-class="common-prompt-popper"
placement="top"
:show-after="500"
>
<span>{{ item.zhName }}</span>
</el-tooltip>
</div>
......@@ -91,13 +107,18 @@
<span>排华联盟最新动态</span>
</div>
<div class="news-content">
<div class="item" v-for="item, index in newsList" :key="index">
<div class="item" v-for="(item, index) in newsList" :key="index">
<div class="item-title">
<img :src="item.image || defaultImg" alt />
<span @click="handleClick(item)">{{ item.title }}</span>
</div>
<el-tooltip effect="dark" :content="item.content" popper-class="common-prompt-popper" placement="top"
:show-after="500">
<el-tooltip
effect="dark"
:content="item.content"
popper-class="common-prompt-popper"
placement="top"
:show-after="500"
>
<div class="item-content">{{ item.content }}</div>
</el-tooltip>
<div class="item-bottom">
......@@ -106,7 +127,7 @@
:key="idx">
<span>{{ ele.industryName }}</span>
</div> -->
<AreaTag v-for="ele, idx in item.industryList" :key="idx" :tagName="ele.industryName"></AreaTag>
<AreaTag v-for="(ele, idx) in item.industryList" :key="idx" :tagName="ele.industryName"></AreaTag>
</div>
<div class="bottom-right">{{ getTime(item.time) }}</div>
</div>
......@@ -123,16 +144,26 @@
<div class="item-title">
<div class="title-left">
<div class="img-list">
<img :src="ele.image || defaultImg" :class="{ img1: index !== 0 }"
@error="e => (e.target.src = defaultImg)" alt v-for="(ele, index) in item.countryList"
:key="index" />
<img
:src="ele.image || defaultImg"
:class="{ img1: index !== 0 }"
@error="e => (e.target.src = defaultImg)"
alt
v-for="(ele, index) in item.countryList"
:key="index"
/>
</div>
<div class="left-content">{{ getContent(item.countryList) }}</div>
</div>
<div class="title-right">{{ item.statementList?.length }}次合作</div>
</div>
<div class="item-content">
<div class="content-list" v-for="(ele, idx) in item.statementList" :key="idx" @click="handleClick(ele)">
<div
class="content-list"
v-for="(ele, idx) in item.statementList"
:key="idx"
@click="handleClick(ele)"
>
<div class="list-left">
<!-- <span>{{ getName(ele.industryList) }}</span> -->
<AreaTag v-if="getName(ele.industryList)" :tagName="getName(ele.industryList)"></AreaTag>
......@@ -945,7 +976,7 @@ const initRightDonut = async () => {
value: res.data[i].amount,
x: Math.random() * 10,
y: Math.random() * 10,
symbolSize: res.data[i].amount * 9,
symbolSize: res.data[i].amount * 9
};
// 先判断data中是否包含上述数据
......@@ -985,8 +1016,8 @@ const initRightDonut = async () => {
// text: 'Basic Graph'
},
tooltip: {
trigger: 'item', // 针对Graph的节点/边触发(必配,否则弹框不生效)
triggerOn: 'click',
trigger: "item", // 针对Graph的节点/边触发(必配,否则弹框不生效)
triggerOn: "click",
formatter: function (params) {
// params.data 是当前点击节点的完整数据对象
const { name, value } = params.data;
......@@ -1018,7 +1049,7 @@ const initRightDonut = async () => {
show: true
},
edgeSymbol: ["circle", ""],
edgeSymbolSize: [4, 40],
edgeSymbolSize: [4, 80],
edgeLabel: {
fontSize: 20
},
......
......@@ -217,9 +217,9 @@ const props = defineProps({
const tabList = ref([
{ name: "国会法案", active: true },
{ name: "国会议员", active: true },
{ name: "国会议员", active: false },
{ name: "议员合作关系", active: false },
{ name: "委员会", active: true }
{ name: "委员会", active: false }
]);
const activeTabName = ref("国会法案");
const handleClickTab = tab => {
......
......@@ -329,7 +329,7 @@ const handleClickToDetailO = item => {
// 查看更多风险信号
const handleToMoreRiskSignal = () => {
const route = router.resolve("/riskSignal");
const route = router.resolve("/viewRiskSignal");
window.open(route.href, "_blank");
};
// 风险信号
......
......@@ -283,7 +283,7 @@ onMounted(() => {
margin: 0 auto;
padding-top: 10px;
.layout-main-header-left-box {
width: 900px;
width: 2600px;
.left-box-top {
height: 64px;
display: flex;
......
......@@ -16,16 +16,16 @@
>
<div class="item-title">{{ item.actionTitle }}</div>
</el-tooltip>
<div class="right">
<!-- <div class="right">
<div class="risk-tag" :class="item.riskClass">{{ item.riskText }}</div>
<div class="arrow">></div>
</div>
</div> -->
</div>
</div>
<div class="empty" v-if="displayList.length === 0">暂无进展数据</div>
</div>
<div class="more" v-if="hasMore">查看更多<img :src="arrowDown"/></div>
<!-- <div class="more" v-if="hasMore">查看更多<img :src="arrowDown"/></div> -->
</div>
</template>
......
......@@ -145,14 +145,14 @@
</div> -->
<AnalysisBox title="法案进展" :showAllBtn="false">
<template #header-btn>
<div class="progress-header-btns">
<!-- <div class="progress-header-btns">
<div class="btn" :class="{ btnActive: progressMode === 'latest' }" @click="handleSwitchProgressMode('latest')">
最新进展
</div>
<div class="btn" :class="{ btnActive: progressMode === 'early' }" @click="handleSwitchProgressMode('early')">
前期进程
</div>
</div>
</div> -->
</template>
<div class="box2-main">
<div class="box2-main-center">
......
......@@ -8,7 +8,7 @@
<!-- 数值区域 -->
<el-space :size="6">
<!-- 数值图标 -->
<div class="item-value-img" />
<div class="item-value-img"></div>
<!-- 数值 -->
<div class="item-value">
{{ t.value }}
......
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import { ElSpace, ElRadioGroup, ElRadio, ElRadioButton } from 'element-plus';
import * as echarts from 'echarts';
import { getStudyList, getSanctionList } from '@/api/companyPages';
import AnalysisBox from '@/components/base/boxBackground/analysisBox.vue';
import AiTipPane from '@/components/base/panes/AiTipPane.vue'
// 定义组件属性
const props = defineProps({
enterpriseInfo: {
type: Object,
default: {}
}
});
const studyList = ref([])
const sanctionList = ref([])
const studyTypes = ref([])
const studyType = ref()
const chartDom = ref()
let myChart = null
onMounted(async () => {
await intData()
// await initChart()
})
onUnmounted(() => myChart?.dispose())
async function intData() {
const { data } = await getStudyList(props.enterpriseInfo.id)
studyList.value = data ?? []
data.forEach(t => t.time = new Date(t.year, 1, 1))
studyTypes.value = [...new Set(data.map(t => t.type))]
const { data: sanctionData } = await getSanctionList(props.enterpriseInfo.id)
sanctionList.value = sanctionData ?? []
sanctionList.value.forEach(t => t.time = new Date(t.sanctionDate))
if (studyTypes.value.length > 0) {
studyType.value = studyTypes.value[0]
}
updateCharts(studyType.value, studyList.value, sanctionList.value)
}
// 辅助函数:获取制裁年份对应的Y值
function getSanctionYValue(sanctionDate, filteredList, defaultYValue) {
const year = sanctionDate.getFullYear()
const yearData = filteredList.find(d => d.year === year)
return yearData ? yearData.currentValue : defaultYValue
}
// 辅助函数:格式化文本内容,实现智能换行(考虑中英文混合)
function formatContent(content, maxWidth = 26) {
if (!content) return ''
const lines = []
let currentLine = ''
let currentWidth = 0
// 中文字符宽度设为2,英文字符宽度设为1
for (let i = 0; i < content.length; i++) {
const char = content[i]
const charWidth = /[\u4e00-\u9fa5]/.test(char) ? 2 : 1
if (currentWidth + charWidth <= maxWidth) {
currentLine += char
currentWidth += charWidth
} else {
lines.push(currentLine)
currentLine = char
currentWidth = charWidth
}
}
if (currentLine) {
lines.push(currentLine)
}
return lines.join('\n')
}
function updateCharts(type, dataStudy, dataSanction) {
const filteredList = dataStudy.filter(t => t.type === type)
if (!filteredList.length) return
// 销毁现有图表实例
if (myChart) {
myChart.dispose()
}
myChart = echarts.init(chartDom.value)
// y轴单位
const unit = filteredList[0].unit
const yValue = Math.max(...filteredList.map(d => d.currentValue))
// 计算x轴范围,扩大活动空间
const allDates = [
...filteredList.map(t => t.time),
...dataSanction.map(t => t.time)
]
const minDate = new Date(Math.min(...allDates))
const maxDate = new Date(Math.max(...allDates))
// 向前扩展1年,向后扩展1年
minDate.setFullYear(minDate.getFullYear() - 1)
maxDate.setFullYear(maxDate.getFullYear() + 1)
myChart.setOption({
textStyle: {
fontSize: 14
},
grid: {
left: 60,
right: 110,
},
tooltip: {
trigger: 'axis',
position: function (pt) {
return [pt[0], '10%'];
},
},
dataZoom: [
{
type: 'inside',
start: 0,
end: 100
},
{
start: 0,
end: 100
}
],
xAxis: {
type: 'time',
boundaryGap: false,
min: minDate,
max: maxDate
},
yAxis: {
type: 'value',
boundaryGap: [0, '100%'],
// 显示y轴单位在顶部
name: unit,
nameLocation: 'end'
},
series: [
{
type: 'line',
//从上到下填充颜色
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: 'rgba(128, 181, 255, 0.8)'
},
{
offset: 1,
color: 'rgba(128, 181, 255, 0)'
}
])
},
data: filteredList.map(t => [t.time, t.currentValue])
},
{
type: 'scatter',
tooltip: { show: false },
data: dataSanction.map(t => {
const currentYValue = getSanctionYValue(t.time, filteredList, yValue) + yValue / 3
return [t.time, currentYValue, t]
}),
markLine: {
lineStyle: {
color: '#ff4d4f',
type: 'dashed',
width: 1
},
data: dataSanction.map(t => {
const currentYValue = getSanctionYValue(t.time, filteredList, yValue) + yValue / 3
return [{
coord: [t.time, 0],
symbol: 'none'
}, {
coord: [t.time, currentYValue],
symbol: 'none',
}]
})
},
coordinateSystem: 'cartesian2d',
symbolSize: 1,
label: {
show: true,
position: 'insideBottomLeft',
formatter: function (params) {
const title = params.data[2].sanctionDate;
const content = params.data[2].content;
const formattedContent = formatContent(content);
return `{title|${title}}\n{content|${formattedContent}}`;
},
rich: {
title: {
fontSize: 16,
lineHeight: 22,
color: '#CE4F51'
},
content: {
fontSize: 15,
fontWeight: 'bold',
width: 200, // 限制宽度
color: '#CE4F51',
lineHeight: 22,
overflow: 'break' // 超出宽度自动换行
}
},
backgroundColor: 'rgba(255, 241, 240, 1)',
borderColor: 'rgba(255, 204, 199, 1)',
borderRadius: 4,
padding: [8, 12],
distance: -1
}
}
],
})
}
function handleStudyTypesChange() {
updateCharts(studyType.value, studyList.value, sanctionList.value)
}
</script>
<template>
<analysis-box title="被制裁时间轴">
<template v-slot:header-btn>
<el-radio-group v-model="studyType" @change="handleStudyTypesChange">
<el-radio-button v-for="item in studyTypes" :key="item" :label="item">{{ item }}</el-radio-button>
</el-radio-group>
</template>
<div class="flex-display content-box">
<div ref="chartDom" class="chart-container"></div>
<ai-tip-pane>123</ai-tip-pane>
</div>
</analysis-box>
</template>
<style lang="scss" scoped>
.content-box {
padding: 10px;
gap: 10px;
flex-direction: column;
}
.chart-container {
height: 500px;
width: 100%;
}
</style>
\ No newline at end of file
<script setup lang="ts">
import '@/styles/tabs.scss'
import { ElTabPane, ElTabs } from 'element-plus';
import SanctionsSituation from './SanctionsSituation.vue';
// 定义组件属性
const props = defineProps({
enterpriseInfo: {
type: Object,
default: {}
}
});
</script>
<template>
<el-tabs tabPosition="left" class="disinheritance tabs-nav-no-wrap left-float-nav-tabs">
<el-tab-pane label="企业规模"></el-tab-pane>
<el-tab-pane label="市值变化"></el-tab-pane>
<el-tab-pane label="研发投入"></el-tab-pane>
<el-tab-pane label="市场占比"></el-tab-pane>
</el-tabs>
<div style="overflow: visible;">
<el-tabs tabPosition="left" class="disinheritance tabs-nav-no-wrap left-float-nav-tabs">
<el-tab-pane label="企业规模">
<sanctions-situation :enterprise-info="enterpriseInfo"></sanctions-situation>
</el-tab-pane>
<!-- <el-tab-pane label="市值变化"></el-tab-pane>
<el-tab-pane label="研发投入"></el-tab-pane>
<el-tab-pane label="市场占比"></el-tab-pane> -->
</el-tabs>
</div>
</template>
\ No newline at end of file
......@@ -4,7 +4,7 @@
</div>
<el-scrollbar>
<div class="common-page">
<el-space wrap :size="16">
<el-space wrap :size="16" fill>
<title-pane :enterprise-info="enterpriseInfo"></title-pane>
<el-tabs stretch class="tabs-header-as-card tabs-nav-no-wrap tabs-bar-as-btn">
<el-tab-pane label="企业详情">
......@@ -14,7 +14,7 @@
</div>
</el-tab-pane>
<el-tab-pane lazy label="经营情况">
<operating-pages />
<operating-pages :enterprise-info="enterpriseInfo" />
</el-tab-pane>
<el-tab-pane lazy label="供应链 / 股权">
<div class="flex-display">
......
......@@ -207,7 +207,7 @@ const handleToRiskDetail = (item) => {
// 查看更多风险信号
const handleToMoreRiskSignal = () => {
const route = router.resolve("/riskSignal");
const route = router.resolve("/vieRiskSignal");
window.open(route.href, "_blank");
};
......
......@@ -26,7 +26,7 @@
</div>
<!-- 资讯要问 -->
<div class="ask" id="position2">
<com-title title="咨询要闻" />
<com-title title="资讯要闻" />
<div class="ask-main">
<askPage />
</div>
......
......@@ -534,7 +534,7 @@ handleGetDepartmentList();
// 查看更多风险信号
const handleToMoreRiskSignal = () => {
const route = router.resolve("/riskSignal");
const route = router.resolve("/viewRiskSignal");
window.open(route.href, "_blank");
};
......
......@@ -550,7 +550,7 @@ const messageList = ref([
]);
// 查看更多风险信号
const handleToMoreRiskSignal = () => {
const route = router.resolve("/riskSignal");
const route = router.resolve("/viewRiskSignal");
window.open(route.href, "_blank");
};
......
......@@ -3,8 +3,13 @@
<div class="main-content" ref="homeMainRef">
<div class="home-top-bg"></div>
<!-- 搜索栏部分 -->
<SearchContainer v-if="homeMainRef" :countInfo="statCountInfo" placeholder="搜索规则限制" :containerRef="homeMainRef"
areaName="" />
<SearchContainer
v-if="homeMainRef"
:countInfo="statCountInfo"
placeholder="搜索规则限制"
:containerRef="homeMainRef"
areaName=""
/>
<!-- 最新动态 -->
<div class="newdata" id="position1">
<com-title title="最新动态" />
......@@ -14,7 +19,7 @@
</div>
<!-- 资讯要问 -->
<div class="ask" id="position2">
<com-title title="咨询要闻" />
<com-title title="资讯要闻" />
<div class="ask-main">
<askPage />
</div>
......
......@@ -19,7 +19,7 @@
</div>
</div>
<div class="btn" @click="handleToPosi('position2')">
<div class="btn-text">咨询要闻</div>
<div class="btn-text">资讯要闻</div>
<div class="btn-icon">
<img src="@/assets/icons/arrow-right-icon.png" alt />
</div>
......@@ -29,7 +29,8 @@
<div class="btn-icon">
<img src="@/assets/icons/arrow-right-icon.png" alt />
</div>
</div>,
</div>
,
<div class="btn" @click="handleToPosi('position4')">
<div class="btn-text">资源库</div>
<div class="btn-icon">
......@@ -85,7 +86,7 @@
</div>
</div>
<div class="btn" @click="handleToPosi('position2')">
<div class="btn-text">咨询要闻</div>
<div class="btn-text">资讯要闻</div>
<div class="btn-icon">
<img src="@/assets/icons/arrow-right-icon.png" alt />
</div>
......@@ -113,7 +114,7 @@
</div>
<!-- 资讯要问 -->
<div class="ask" id="position2">
<com-title title="咨询要闻" />
<com-title title="资讯要闻" />
<div class="ask-main">
<askPage />
</div>
......@@ -145,7 +146,7 @@ import askPage from "./components/askPage/index.vue";
import dataSub from "./components/dataSub/index.vue";
import resLib from "./components/resLib/index.vue";
import { useContainerScroll } from "@/hooks/useScrollShow";
import { getStatCount } from '@/api/ruleRestriction/index.js'
import { getStatCount } from "@/api/ruleRestriction/index.js";
// 搜索框
const input = ref("");
......@@ -154,59 +155,59 @@ const { isShow } = useContainerScroll(homeMainRef);
const router = useRouter();
const statCountInfo = ref({})
const statCountInfo = ref({});
const getStatCountInfo = async () => {
try {
const res = await getStatCount();
if (res && res.code === 200) {
// console.log('----getStatCountInfo', res.data)
statCountInfo.value = res.data
}
} catch (error) {
console.error("获取首页统计接口失败:", error);
}
}
try {
const res = await getStatCount();
if (res && res.code === 200) {
// console.log('----getStatCountInfo', res.data)
statCountInfo.value = res.data;
}
} catch (error) {
console.error("获取首页统计接口失败:", error);
}
};
// 搜索功能
const handleSearch = () => {
console.log("搜索内容:", input.value);
console.log("搜索内容:", input.value);
};
// 锚点跳转
const handleToPosi = id => {
const element = document.getElementById(id);
if (element && homeMainRef.value) {
// 如果当前还未显示吸顶搜索栏,先强制切换状态以稳定布局
if (!isShow.value) {
isShow.value = true;
}
const element = document.getElementById(id);
if (element && homeMainRef.value) {
// 如果当前还未显示吸顶搜索栏,先强制切换状态以稳定布局
if (!isShow.value) {
isShow.value = true;
}
// 使用 nextTick 确保 DOM 状态更新(高度变化生效)后再计算
nextTick(() => {
const containerRect = homeMainRef.value.getBoundingClientRect();
const elementRect = element.getBoundingClientRect();
// 使用 getBoundingClientRect 计算元素相对于容器顶部的绝对距离,不受嵌套布局影响
const top = elementRect.top - containerRect.top + homeMainRef.value.scrollTop;
// 使用 nextTick 确保 DOM 状态更新(高度变化生效)后再计算
nextTick(() => {
const containerRect = homeMainRef.value.getBoundingClientRect();
const elementRect = element.getBoundingClientRect();
// 使用 getBoundingClientRect 计算元素相对于容器顶部的绝对距离,不受嵌套布局影响
const top = elementRect.top - containerRect.top + homeMainRef.value.scrollTop;
homeMainRef.value.scrollTo({
top: top,
behavior: "smooth"
});
});
}
homeMainRef.value.scrollTo({
top: top,
behavior: "smooth"
});
});
}
};
// 返回首页
const handleBackHome = () => {
router.push({
path: "/overview"
});
router.push({
path: "/overview"
});
};
onMounted(async () => {
await getStatCountInfo()
})
await getStatCountInfo();
});
</script>
<style scoped lang="scss">
......
......@@ -14,8 +14,14 @@
<div class="main-content" ref="containerRef">
<div class="home-top-bg"></div>
<!-- 搜索栏部分 -->
<SearchContainer style="margin-bottom: 48px;height: fit-content;" v-if="containerRef" :countInfo="countInfo"
placeholder="搜索科研资助实体、资助记录" :containerRef="containerRef" areaName="" />
<SearchContainer
style="margin-bottom: 48px; height: fit-content"
v-if="containerRef"
:countInfo="countInfo"
placeholder="搜索科研资助实体、资助记录"
:containerRef="containerRef"
areaName=""
/>
<!-- <div class="search"> -->
<!-- <div class="search-main">
......@@ -51,7 +57,7 @@
</div>
</div>
<div class="btn" @click="scrollToTop('position2')">
<div class="btn-text">咨询要闻</div>
<div class="btn-text">资讯要闻</div>
<div class="btn-icon">
<img src="@/assets/icons/arrow-right-icon.png" alt="" />
</div>
......@@ -80,7 +86,7 @@
<div class="data-item-name">{{ item.orgNameEn }}</div>
<div v-if="item.orgAbbEn" class="data-item-abb">{{ item.orgAbbEn }}</div>
</div>
<div class="data-item-num" :style="{ color: color[index] }">{{ item.num + '项' }}</div>
<div class="data-item-num" :style="{ color: color[index] }">{{ item.num + "项" }}</div>
</div>
</div>
<!-- 最新动态 -->
......@@ -92,7 +98,7 @@
</div>
<!-- 资讯要问 -->
<div class="ask" id="position2">
<com-title title="咨询要闻" />
<com-title title="资讯要闻" />
<div class="ask-main">
<askPage />
</div>
......@@ -125,10 +131,7 @@ import dataSub from "./components/dataSub/index.vue";
import resLib from "./components/resLib/index.vue";
import scrollToTop from "@/utils/scrollToTop";
import {
getFundSourceOrg
} from "@/api/scientificFunding/overview";
import { getFundSourceOrg } from "@/api/scientificFunding/overview";
import { useContainerScroll } from "@/hooks/useScrollShow";
......@@ -141,21 +144,21 @@ import img06 from "./assets/images/img06.png";
let containerRef = ref(null);
let countInfo = ref([
{
name: '科研资助机构',
name: "科研资助机构",
count: 18
},
{
name: '科研资助动态',
name: "科研资助动态",
count: 633
},
{
name: '科研资助项目',
name: "科研资助项目",
count: 312
},
{
name: '经费总额(亿美元)',
count: '15,556'
},
name: "经费总额(亿美元)",
count: "15,556"
}
]);
// 搜索框
const input = ref("");
......@@ -231,14 +234,14 @@ const color = ref([
"rgba(64, 150, 255, 1)",
"rgb(33, 129, 57)",
"rgb(5, 95, 194)"
])
]);
//// 来源机构列表
const handleGetFundSourceOrg = async () => {
try {
const res = await getFundSourceOrg();
console.log("来源机构列表", res);
if (res.code === 200 && res.data) {
dataList.value = res.data
dataList.value = res.data;
}
} catch (error) {
console.error("获取来源机构列表error", error);
......@@ -246,7 +249,7 @@ const handleGetFundSourceOrg = async () => {
};
onMounted(async () => {
handleGetFundSourceOrg()
handleGetFundSourceOrg();
});
</script>
......@@ -461,7 +464,9 @@ onMounted(async () => {
box-sizing: border-box;
position: relative;
cursor: pointer;
transition: transform 0.3s ease, box-shadow 0.3s ease;
transition:
transform 0.3s ease,
box-shadow 0.3s ease;
display: flex;
align-items: center;
padding: 0px 24px;
......
......@@ -89,7 +89,8 @@ export default defineConfig({
rewrite: (path) => path.replace(/^\/temporarySearch/, '')
},
'^/bill(?:/|$)': {
target: 'http://172.20.10.3:28080/',
target: 'http://8.140.26.4:9085/',
// target: 'http://172.20.10.3:28080/',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/bill/, '')
},
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论