提交 cb755878 authored 作者: huhuiqing's avatar huhuiqing

Merge branch 'master' of http://8.140.26.4:10003/caijian/risk-monitor into dev_hhq

......@@ -22,6 +22,7 @@
"element-plus": "^2.4.4",
"highlight.js": "^11.11.1",
"json5": "^2.2.3",
"lodash": "^4.17.21",
"markdown-it": "^14.1.0",
"vue": "^3.4.0",
"vue-router": "^4.2.5"
......@@ -4139,7 +4140,7 @@
},
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"license": "MIT"
},
......
......@@ -31,6 +31,7 @@
"element-plus": "^2.4.4",
"highlight.js": "^11.11.1",
"json5": "^2.2.3",
"lodash": "^4.17.21",
"markdown-it": "^14.1.0",
"vue": "^3.4.0",
"vue-router": "^4.2.5"
......
import request from "@/api/request.js";
import {
ElMessage
} from 'element-plus'
const request200 = (requestP) => {
return requestP.then((data) => {
if (data.code === 200) {
return data.data
}
ElMessage({
message: data.message,
type: 'error',
duration: 3 * 1000
})
return null
})
}
// 实体清单总条数统计
/**
* @returns {Promise<number>}
*/
export function getEntitiesDataCount() {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/countData',
}))
}
// 最新实体清单信息查询
/**
* @returns {Promise<{
* chNum: number
* entities:{
* entityNameZh: string
* entityName: string
* }[]
* organization:{
* orgName: string
* }
* domains: string[]
* startTime: string
*}>}
*/
export function getEntitiesDataInfo() {
return request200(request({
method: 'GET',
url: '/api/entitiesDataInfo/latestInfoSelect',
}))
}
/**
* 每年最多领域及该领域发布次数
* @returns {Promise<{
* year?: number
* maxDomain: string
* maxCount: number
* }[]>}
*/
export function getIndustryCountByYear() {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/industryCountByYear',
}))
}
/**
* 不同领域每年数量
* @returns {Promise<{
* data:{
* year?: number
* domainNum: {
* [ key: string]: number;
* }
* }[]
* domains: string[]
* }>}
*/
export function getCountDomainByYear() {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/countDomainByYear',
}))
}
/**
* 历次制裁过程(月份统计)
* @returns {Promise<{
* tittle: string
* entitiesChNum: string
* sanReason: string
* }[]>}
*/
export function getSanctionsInfoCount() {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/sanctionsInfoCount',
}))
}
/**
* 查询发布机构
* @returns {Promise<{
* orgName: string //机构名称
* orgIntroduction: string //相关措施
* orgIntroduction: string //机构职责
* }>}
*/
export function getOrganizationInfo() {
return request200(request({
method: 'GET',
url: '/api/entitiesDataInfo/getOrganizationInfo',
}))
}
/**
* 查询重点人物
* @returns {Promise<{
* name: string
* ename: string
* avatarUrl: string
* positionTitle: string
* }[]>}
*/
export function getPersonList() {
return request200(request({
method: 'GET',
url: '/api/entitiesDataInfo/getPersonList',
}))
}
/**
* 不同领域实体统计
* @param {string} startTime - 统计开始时间,格式为 'YYYY-MM-DD'
* @returns {Promise<{
* domain: string
* count: number
* }[]>}
*/
export function getCountByDomain(startTime) {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/countByDomain',
params: {
startTime
}
}))
}
/**
* 不同类型实体统计
* @param {string} startTime - 统计开始时间,格式为 'YYYY-MM-DD'
* @returns {Promise<{
* type: string
* count: number
* }[]>}
*/
export function getCountByType(startTime) {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/countByType',
params: {
startTime
}
}))
}
/**
* 查询制裁原因
* @param {string} startTime - 统计开始时间,格式为 'YYYY-MM-DD'
* @returns {Promise<string[]>}
*/
export function getSanReasonSelect(startTime) {
return request200(request({
method: 'GET',
url: '/api/entitiesDataInfo/sanReasonSelect',
params: {
startTime
}
}))
}
/**
* 查询实体清单列表
* @param {string} startTime - 统计开始时间,格式为 'YYYY-MM-DD'
* @returns {Promise<{
* entityNameZh: string
* techDomainList: string[]
* startTime: staring
* }[]>}
*/
export function getSelectEntitiesList(startTime) {
return request200(request({
method: 'GET',
url: '/api/entitiesDataInfo/selectEntitiesList',
params: {
startTime
}
}))
}
/**
* 数量比对分析
* @param {string} startTime - 统计开始时间,格式为 'YYYY-MM-DD'
* @returns {Promise<{
* countDomainLast: number
* countDomainNow: number
* countSanLast: number
* countSanNow: number
* countTypeLast: number
* countTypeNow: number
* }>}
*/
export function getCompareCountSan(startTime) {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/compareCountSan',
params: {
startTime
}
}))
}
/**
* 实体清单变化统计
* @param {number} domain
* @param {number} type
* @returns {Promise<{
* year:number
* count:number
* }[]>}
*/
export function getEntitiesChangeCount(domain, type) {
return request200(request({
method: 'GET',
// url: '/api/entitiesDataCount/entitiesChangeCount',
url: '/api/entitiesDataCount/sanCountByYear',
params: {
domain,
type
}
}))
}
/**
* 新增实体数量增长趋势
* @returns {Promise<{
* year: string
* percent: string //百分比'20%'
* }>}
*/
export function getEntitiesGrowthTrend() {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/entitiesGrowthTrend',
}))
}
/**
* 实体清单更新频率
* @returns {Promise<{
* series: number[]
* xAxis: string[]
* }>}
*/
export function getEntitiesUpdateCount() {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/entitiesUpdateCount',
}))
}
/**
* 新增实体领域分布情况
* @param {string} sanTime - 开始时间,格式为 'YYYY-MM-DD'
* @returns {Promise<{
* value: number
* name: string
* }[]>}
*/
export function getEntitiesAreaCountByYear(sanTime) {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/entitiesAreaCountByYear',
params: {
sanTime
}
}))
}
/**
* 历次制裁涉及领域数
* @returns {Promise<{
* series: number[]
* xAxis: string[]
* }>}
*/
export function getEntitiesDomainCount() {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/entitiesDomainCount'
}))
}
/**
* 指定领域每年实体数量查询
* @param {string} param
* @returns {Promise<{
* year: string
* count: number
* }[]>}
*/
export function getCountThisDomain(param) {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/countThisDomain',
params: {
param
}
}))
}
/**
* 历次制裁涉及类别数量
* @returns {Promise<{
* year: string
* count: number
* }[]>}
*/
export function getCountTypeByYear() {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/countTypeByYear',
}))
}
/**
* 新增实体类别统计
* @param {string} startTime - 开始时间,格式为 'YYYY-MM-DD'
* @returns {Promise<{
* type: string
* count: number
* }[]>}
*/
export function getCountSanTypeByTime(startTime) {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/countSanTypeByTime',
params: {
startTime
}
}))
}
/**
* 指定类别每年实体数量查询
* @param {string} param
* @returns {Promise<{
* year: number
* count: number
* }[]>}
*/
export function getCountThisType(param) {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/countThisType',
params: {
param
}
}))
}
import { ref } from 'vue';
export function useRequest(apiFunction, immediate = true) {
const data = ref(null);
const loading = ref(false);
const error = ref(null);
const execute = async (...args) => {
loading.value = true;
error.value = null;
try {
data.value = await apiFunction(...args);
} catch (err) {
error.value = err;
} finally {
loading.value = false;
}
};
if (immediate) {
execute(); // 可选:是否立即执行
}
return {
data,
loading,
error,
execute, // 手动触发函数
};
}
\ No newline at end of file
......@@ -13,6 +13,7 @@ const routes = [
...fileRoutes,
];
const router = createRouter({
history: createWebHistory(),
routes
......
......@@ -14,7 +14,7 @@ const cooperationRestrictionsRoutes = [
},
// 合作限制详情
{
path: "/coopRestriction/detail",
path: "/cooperationRestrictions/detail",
name: "CooperationRestrictionsDetail",
component: CooperationRestrictionsDetail,
meta: {
......
// 规则限制
import RuleRestriction from "@/views/ruleRestriction/index.vue";
import RuleRestrictionDetail from "@/views/ruleRestriction/detail/index.vue";
const ruleRestrictionsRoutes = [
// 规则限制
{
path: "/ruleRestrictions",
name: "RuleRestrictions",
component: RuleRestriction,
meta: {
title: "规则限制"
}
},
// 规则限制详情
{
path: "/ruleRestrictions/detail",
name: "RuleRestrictionsDetail",
component: RuleRestrictionDetail,
meta: {
title: "规则限制详情"
}
},
]
export default ruleRestrictionsRoutes
// 科研资助体系
import ScientificFunding from "@/views/scientificFunding/index.vue";
const scientificFundingRoutes = [
// 科研资助体系
{
path: "/scientificFunding",
name: "ScientificFunding",
component: ScientificFunding,
meta: {
title: "科研资助体系"
}
}
]
export default scientificFundingRoutes
......@@ -4,7 +4,7 @@
<div class="left-title">
<img src="./assets/icon01.png" alt="">
<div class="tit">新闻资讯</div>
<div class="more">更多 +</div>
<div class="more" @click="handleToMoreNews">更多 +</div>
</div>
<div class="left-main">
<div v-for="item in leftList" :key="item.id" class="main-item">
......@@ -55,6 +55,7 @@
<script setup>
import { ref } from "vue";
import router from '@/router'
import image01 from './assets/image01.png'
import image02 from './assets/image02.png'
import image03 from './assets/image03.png'
......@@ -128,6 +129,12 @@ const rightList = ref([
}
])
// 查看更多新闻资讯
const handleToMoreNews = () => {
const route = router.resolve("/newsBrief");
window.open(route.href, "_blank");
};
</script>
<style scoped lang="scss">
......
......@@ -58,7 +58,7 @@
</div>
</div>
<div style="margin: 6px 34px 0 23px">
<div v-for="item in list" :key="item.id" class="right-main">
<div v-for="item in list" :key="item.id" class="right-main" @click="handleClickToDetail()">
<div class="main-left" :class="{ cl4: item.title === '特别重大', cl5: item.title === '重大风险' }">
{{ item.title }}
</div>
......@@ -66,7 +66,7 @@
<div class="main-right">{{ item.time }}</div>
</div>
</div>
<div class="right-mainbtn">
<div class="right-mainbtn" @click="handleToMoreRiskSignal">
<img src="./assets/btn.png" alt="" />
查看更多
</div>
......@@ -76,6 +76,7 @@
<script setup>
import { ref } from "vue";
import router from "@/router";
const list = ref([
{
......@@ -103,6 +104,20 @@ const list = ref([
time: "一天前"
}
]);
// 点击查看详情
const handleClickToDetail = () => {
// router.push("/decreeLayout");
const curRoute = router.resolve("/cooperationRestrictions/detail");
window.open(curRoute.href, "_blank");
};
// 查看更多风险信号
const handleToMoreRiskSignal = () => {
const route = router.resolve("/riskSignal");
window.open(route.href, "_blank");
};
</script>
<style scoped lang="scss">
......@@ -340,11 +355,16 @@ const list = ref([
}
}
.right-main {
width: 463px;
width: 468px;
padding-right: 5px;
height: 47px;
border-radius: 2px;
display: flex;
align-items: center;
cursor: pointer;
&:hover {
background: var(--color-bg-hover);
}
.main-left {
width: 40px;
height: 40px;
......
......@@ -36,47 +36,47 @@
</div>
</div>
<div class="search-bottom">
<div class="btn">
<div class="btn" @click="scrollToTop('position1')">
<div class="btn-text">最新动态</div>
<div class="btn-icon">></div>
</div>
<div class="btn">
<div class="btn" @click="scrollToTop('position2')">
<div class="btn-text">咨询要闻</div>
<div class="btn-icon">></div>
</div>
<div class="btn">
<div class="btn" @click="scrollToTop('position3')">
<div class="btn-text">数据总览</div>
<div class="btn-icon">></div>
</div>
<div class="btn">
<div class="btn" @click="scrollToTop('position4')">
<div class="btn-text">资源库</div>
<div class="btn-icon">></div>
</div>
</div>
</div>
<!-- 最新动态 -->
<div class="newdata">
<div class="newdata" id="position1">
<com-title title="最新动态" />
<div class="newdata-main">
<newData />
</div>
</div>
<!-- 资讯要问 -->
<div class="ask">
<div class="ask" id="position2">
<com-title title="咨询要闻" />
<div class="ask-main">
<askPage />
</div>
</div>
<!-- 数据总览 -->
<div class="datasub">
<div class="datasub" id="position3">
<com-title title="数据总览" />
<div class="datasub-main">
<dataSub />
</div>
</div>
<!-- 资源库 -->
<div class="reslib">
<div class="reslib" id="position4">
<com-title title="资源库" />
<div class="reslib-main">
<resLib />
......@@ -94,6 +94,7 @@ import newData from "./components/dataNew/index.vue";
import askPage from "./components/askPage/index.vue";
import dataSub from "./components/dataSub/index.vue";
import resLib from "./components/resLib/index.vue";
import scrollToTop from "@/utils/scrollToTop";
import { useContainerScroll } from "@/hooks/useScrollShow";
......@@ -153,6 +154,7 @@ const handleBackHome = () => {
width: 960px;
height: 225px;
margin: 0 auto 68px auto;
.search-main {
display: flex;
padding-right: 3px;
......@@ -163,11 +165,14 @@ const handleBackHome = () => {
height: 48px;
background-color: rgba(255, 255, 255, 0.65);
border-radius: 10px;
border: 1px solid #fff;
border: 1px solid transparent;
&:hover {
border: 1px solid var(--color-main-active);
}
.search-input {
border: none;
outline: none;
width: 800px;
width: 838px;
height: 48px;
background-color: transparent;
font-size: 16px;
......@@ -178,12 +183,13 @@ const handleBackHome = () => {
color: rgb(132, 136, 142);
}
.search-btn {
margin-right: -3px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
width: 120px;
height: 42px;
height: 46px;
border-radius: 8px;
background-color: rgb(5, 95, 194);
font-size: 18px;
......
......@@ -6,18 +6,20 @@
<el-select
:style="{ width: '120px', marginRight: '8px' }"
size="mini"
v-model="value1"
v-model="domainValue"
placeholder="领域选择"
>
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </el-option>
<el-option v-for="item in domainOptions" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
<el-select
:style="{ width: '120px', marginRight: '18px' }"
size="mini"
v-model="value2"
v-model="typeValue"
placeholder="类型选择"
>
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </el-option>
<el-option v-for="item in typeOptions" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</template>
<div class="subPanel1">
......@@ -82,28 +84,169 @@
</template>
<script setup>
import { ref, shallowRef, onMounted } from "vue";
import { ref, shallowRef, onMounted, watch } from "vue";
import CardCustom from "../../components/CardCustom.vue";
import { Search } from "@element-plus/icons-vue";
import Echarts from "@/components/Chart/index.vue";
import { getBarChart, getLineChart } from "../../utils/charts";
import Hint from "./hint.vue";
const options = [
import { getEntitiesChangeCount, getEntitiesGrowthTrend, getEntitiesUpdateCount } from "@/api/exportControl";
import _ from "lodash";
import { useRoute } from "vue-router";
const route = useRoute();
const line1Option = shallowRef({});
const bar2Option = shallowRef({});
onMounted(async () => {
try {
const [entitiesGrowthTrendData, entitiesUpdateCountData] = await Promise.all([
getEntitiesGrowthTrend(),
getEntitiesUpdateCount()
]);
const list = _.reverse(entitiesGrowthTrendData);
const xAxisData = _.map(list, "year");
const seriesData = _.map(list, item => {
return parseInt(item.percent);
});
line1Option.value = getLineChart({ xAxisData, seriesData, name: "增长趋势", color: "rgba(146, 84, 222, 1)" }, true);
bar2Option.value = getBarChart(
_.reverse(entitiesUpdateCountData.xAxis),
_.reverse(entitiesUpdateCountData.series),
["rgba(22, 119, 255, 1)", "rgba(22, 119, 255, 0)"],
"更新频率"
);
} catch (err) {
console.log(err);
}
});
const domainOptions = [
{
value: "1",
label: "人工智能"
},
{
value: "2",
label: "生物科技"
},
{
value: "3",
label: "新一代信息技术"
},
{
value: "4",
label: "量子科技"
},
{
value: "5",
label: "新能源"
},
{
value: "6",
label: "集成电路"
},
{
value: "7",
label: "海洋"
},
{
value: "8",
label: "先进制造"
},
{
value: "9",
label: "新材料"
},
{
value: "10",
label: "航空航天"
},
{
value: "11",
label: "深海"
},
{
value: "12",
label: "极地"
},
{
value: "13",
label: "太空"
},
{
value: "14",
label: "核"
},
{
value: "20",
label: "政治"
},
{
value: "21",
label: "外交"
},
{
value: "22",
label: "经济"
},
{
value: "23",
label: "军事"
},
{
value: "24",
label: "科技"
},
{
value: "25",
label: "安全"
},
{
value: "99",
label: "其他"
}
];
const value1 = ref("");
const value2 = ref("");
const value3 = ref("");
const typeOptions = [
{
value: "1",
label: "人物"
},
{
value: "2",
label: "机构"
},
{
value: "7",
label: "地址"
}
];
const domainValue = ref(domainOptions[0].value);
const typeValue = ref(typeOptions[0].value);
const bar1Option = shallowRef({});
const bar2Option = shallowRef({});
const line1Option = shallowRef({});
watch(
[domainValue, typeValue],
async ([domain, type]) => {
let EntitiesChangeCount = await getEntitiesChangeCount(domain, type);
EntitiesChangeCount = _.reverse(EntitiesChangeCount);
bar1Option.value = getBarChart(
_.map(EntitiesChangeCount, "year"),
_.map(EntitiesChangeCount, "count"),
["rgba(255, 159, 22, 1)", "rgba(255, 159, 22, 0)"],
"制裁强度"
);
},
{ immediate: true }
);
// const options = [
// {
// value: "1",
// label: "人工智能"
// },
// {
// value: "2",
// label: "航空航天"
// }
// ];
const subPanel4 = ref([
{
name: "中国科学技术大学",
......@@ -141,21 +284,7 @@ const subPanel4 = ref([
]
}
]);
onMounted(() => {
bar1Option.value = getBarChart(
["2016", "2017", "2018", "2019", "2020", "2021", "2022", "2023", "2024", "2025"],
[219, 228, 129, 159, 152, 157, 78, 34, 56, 78],
["rgba(255, 159, 22, 1)", "rgba(255, 159, 22, 0)"],
"制裁强度"
);
bar2Option.value = getBarChart(
["2016", "2017", "2018", "2019", "2020", "2021", "2022", "2023", "2024", "2025"],
[39, 28, 49, 19, 22, 25, 78, 34, 56, 28],
["rgba(22, 119, 255, 1)", "rgba(22, 119, 255, 0)"],
"更新频率"
);
line1Option.value = getLineChart();
});
const value3 = ref("");
</script>
<style lang="scss" scoped>
......
......@@ -121,9 +121,14 @@ onMounted(() => {
["2016", "2017", "2018", "2019", "2020", "2021", "2022", "2023", "2024", "2025"],
[39, 28, 49, 19, 22, 25, 78, 34, 56, 28],
["rgba(19, 188, 196, 1)", "rgba(19, 188, 196, 0)"],
"更新频率"
"市值变化"
);
line1Option.value = getLineChart();
line1Option.value = getLineChart({
xAxisData: [2013, 2023, 2024, 2015],
seriesData: [434, 24, 453, 322],
name: "融资变化",
color: "rgba(146, 84, 222, 1)"
});
});
</script>
......
......@@ -46,30 +46,51 @@ import { Search } from "@element-plus/icons-vue";
import Echarts from "@/components/Chart/index.vue";
import { getBarChart, getLineChart, getPieOption1 } from "../../utils/charts";
import Hint from "./hint.vue";
import { getEntitiesAreaCountByYear, getEntitiesDomainCount, getCountThisDomain } from "@/api/exportControl";
import _ from "lodash";
import { useRoute } from "vue-router";
const route = useRoute();
const pie1Option = shallowRef({});
const bar2Option = shallowRef({});
const line1Option = shallowRef({});
const line2Option = shallowRef({});
onMounted(() => {
pie1Option.value = getPieOption1(
[
{ name: "半导体与集成电路领域", value: 50 },
{ name: "生物技术与生命科学领域", value: 46 },
{ name: "航天遥感与量子技术领域", value: 12 },
{ name: "航空航天领域", value: 32 },
{ name: "人工智能领域", value: 31 },
{ name: "供应链与物流服务领域", value: 30 },
{ name: "工业软件领域", value: 24 }
]
);
onMounted(async () => {
try {
const [entitiesAreaCountByYearData, countThisDomainData4, entitiesDomainCountData, countThisDomainData10] =
await Promise.all([
getEntitiesAreaCountByYear(route.query.startTime),
getCountThisDomain("4"),
getEntitiesDomainCount(),
getCountThisDomain("10")
]);
pie1Option.value = getPieOption1(entitiesAreaCountByYearData ?? []);
const list4 = _.reverse(countThisDomainData4 ?? []);
line1Option.value = getLineChart({
xAxisData: _.map(list4, "year"),
seriesData: _.map(list4, "count"),
name: "量子科技领域",
color: "rgba(255, 149, 77, 1)"
});
bar2Option.value = getBarChart(
["2016", "2017", "2018", "2019", "2020", "2021", "2022", "2023", "2024", "2025"],
[39, 28, 49, 19, 22, 25, 78, 34, 56, 28],
_.reverse(entitiesDomainCountData?.xAxis ?? []),
_.reverse(entitiesDomainCountData?.series ?? []),
["rgba(19, 188, 196, 1)", "rgba(19, 188, 196, 0)"],
"更新频率"
"领域数"
);
line1Option.value = getLineChart("rgba(255, 149, 77, 1)");
line2Option.value = getLineChart("rgba(146, 84, 222, 1)");
const list10 = _.reverse(countThisDomainData10 ?? []);
line2Option.value = getLineChart({
xAxisData: _.map(list10, "year"),
seriesData: _.map(list10, "count"),
name: "航空航天领域",
color: "rgba(146, 84, 222, 1)"
});
} catch (err) {
console.log(err);
}
});
</script>
......
......@@ -46,28 +46,58 @@ import { Search } from "@element-plus/icons-vue";
import Echarts from "@/components/Chart/index.vue";
import { getBarChart, getLineChart, getPieOption1 } from "../../utils/charts";
import Hint from "./hint.vue";
import { getCountSanTypeByTime, getCountTypeByYear, getCountThisType } from "@/api/exportControl";
import _ from "lodash";
import { useRoute } from "vue-router";
const route = useRoute();
const pie1Option = shallowRef({});
const bar2Option = shallowRef({});
const line1Option = shallowRef({});
const line2Option = shallowRef({});
onMounted(() => {
onMounted(async () => {
try {
const [countSanTypeByTimeData, countThisTypeData1, countTypeByYearData, countThisTypeData2] = await Promise.all([
getCountSanTypeByTime(route.query.startTime),
getCountThisType("1"),
getCountTypeByYear(),
getCountThisType("2")
]);
pie1Option.value = getPieOption1(
[
{ name: "企业", value: 50 },
{ name: "科研院所", value: 40 },
{ name: "高校", value: 32 },
{ name: "政府官员", value: 30 },
{ name: "个人", value: 24},
]
_.map(countSanTypeByTimeData ?? [], item => {
return {
name: item?.type,
value: item?.count
};
})
);
const list1 = _.reverse(countThisTypeData1 ?? []);
line1Option.value = getLineChart({
xAxisData: _.map(list1, "year"),
seriesData: _.map(list1, "count"),
name: "科研院所类",
color: "rgba(255, 149, 77, 1)"
});
const list = _.reverse(countTypeByYearData ?? []);
bar2Option.value = getBarChart(
["2016", "2017", "2018", "2019", "2020", "2021", "2022", "2023", "2024", "2025"],
[39, 28, 49, 19, 22, 25, 78, 34, 56, 28],
_.map(list, "year"),
_.map(list, "count"),
["rgba(19, 188, 196, 1)", "rgba(19, 188, 196, 0)"],
"更新频率"
"实体数"
);
line1Option.value = getLineChart("rgba(255, 149, 77, 1)");
line2Option.value = getLineChart("rgba(146, 84, 222, 1)");
const list2 = _.reverse(countThisTypeData2 ?? []);
line2Option.value = getLineChart({
xAxisData: _.map(list2, "year"),
seriesData: _.map(list2, "count"),
name: "企业类",
color: "rgba(117, 29, 219, 1)"
});
} catch (err) {
console.log(err);
}
});
</script>
......
......@@ -13,31 +13,70 @@
import Echarts from "@/components/Chart/index.vue";
import { getPieOption } from "../../utils/charts";
import { ref, onMounted, shallowRef } from "vue";
import { getCountByDomain, getCountByType } from "@/api/exportControl";
import _ from "lodash";
import { useRoute } from "vue-router";
const route = useRoute();
const pie1Option = shallowRef({});
const pie2Option = shallowRef({});
onMounted(() => {
onMounted(async () => {
try {
const [countByDomainData, countByTypeData] = await Promise.all([
getCountByDomain(route.query.startTime),
getCountByType(route.query.startTime)
]);
pie1Option.value = getPieOption(
[
{ name: "能源领域", value: 30 },
{ name: "集成电路领域", value: 20 },
{ name: "人工智能领域", value: 12 },
{ name: "通信网络领域", value: 18 },
{ name: "量子科技领域", value: 10 },
{ name: "生物科技领域", value: 10 }
],
_.chain(countByDomainData)
.filter(item => item.count > 0)
.map(item => {
return {
name: item?.domain,
value: item?.count
};
})
.value(),
"领域分布"
);
pie2Option.value = getPieOption(
[
{ name: "能源领域", value: 30 },
{ name: "集成电路领域", value: 20 },
{ name: "人工智能领域", value: 12 },
{ name: "通信网络领域", value: 18 },
{ name: "量子科技领域", value: 10 },
{ name: "生物科技领域", value: 10 }
],
"类别分布"
_.chain(countByTypeData)
.filter(item => item.count > 0)
.map(item => {
return {
name: item?.type,
value: item?.count
};
})
.value(),
"类型分布"
);
} catch (err) {
console.log(err);
}
});
onMounted(() => {
// pie1Option.value = getPieOption(
// [
// { name: "能源领域", value: 30 },
// { name: "集成电路领域", value: 20 },
// { name: "人工智能领域", value: 12 },
// { name: "通信网络领域", value: 18 },
// { name: "量子科技领域", value: 10 },
// { name: "生物科技领域", value: 10 }
// ],
// "领域分布"
// );
// pie2Option.value = getPieOption(
// [
// { name: "能源领域", value: 30 },
// { name: "集成电路领域", value: 20 },
// { name: "人工智能领域", value: 12 },
// { name: "通信网络领域", value: 18 },
// { name: "量子科技领域", value: 10 },
// { name: "生物科技领域", value: 10 }
// ],
// "类别分布"
// );
});
</script>
......
......@@ -5,7 +5,7 @@
<div
class="item"
:class="{ activeItem: activePanelId === item.id }"
v-for="item in panelListData"
v-for="item in compareCountSan"
:key="item.id"
@click="setActivePanelId(item.id)"
>
......@@ -44,51 +44,67 @@
</div>
</div>
<div class="row">
<panel1 v-if="activePanelId === panelListData[0].id"></panel1>
<panel2 v-if="activePanelId === panelListData[1].id"></panel2>
<panel3 v-if="activePanelId === panelListData[2].id"></panel3>
<panel4 v-if="activePanelId === panelListData[3].id"></panel4>
<panel1 v-if="activePanelId === compareCountSan[0]?.id"></panel1>
<panel2 v-if="activePanelId === compareCountSan[1]?.id"></panel2>
<panel3 v-if="activePanelId === compareCountSan[2]?.id"></panel3>
<panel4 v-if="activePanelId === compareCountSan[3]?.id"></panel4>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
import { ref, onMounted, shallowRef } from "vue";
import Panel1 from "../components/panel1.vue";
import Panel2 from "../components/panel2.vue";
import Panel3 from "../components/panel3.vue";
import Panel4 from "../components/panel4.vue";
const panelListData = [
import { getCompareCountSan } from "@/api/exportControl";
import { useRoute } from "vue-router";
const route = useRoute();
const compareCountSan = shallowRef([]);
const activePanelId = ref(null);
onMounted(async () => {
try {
const [compareCountSanData] = await Promise.all([getCompareCountSan(route.query.startTime)]);
const { countSanNow, countSanLast, countDomainNow, countDomainLast, countTypeNow, countTypeLast } =
compareCountSanData ?? {};
compareCountSan.value = [
{
id: 1,
name: "新增实体数量",
number: "37",
isUp: true,
ComparisonNumber: "31"
number: countSanNow,
isUp: countSanNow - countSanLast >= 0,
ComparisonNumber: Math.abs(countSanNow - countSanLast)
},
{
id: 2,
name: "上市企业数量",
number: "6",
number: "--",
isUp: true,
ComparisonNumber: "2"
ComparisonNumber: "--"
},
{
id: 3,
name: "涉及领域数量",
number: "2",
isUp: false,
ComparisonNumber: "1"
number: countDomainNow,
isUp: countDomainNow - countDomainLast >= 0,
ComparisonNumber: Math.abs(countDomainNow - countDomainLast)
},
{
id: 4,
name: "实体类别数量",
number: "4",
isUp: true,
ComparisonNumber: "1"
number: countTypeNow,
isUp: countTypeNow - countTypeLast >= 0,
ComparisonNumber: Math.abs(countTypeNow - countTypeLast)
}
];
const activePanelId = ref(panelListData[0].id);
];
activePanelId.value = compareCountSan.value[0].id;
} catch (err) {
console.log(err);
}
});
const setActivePanelId = id => {
activePanelId.value = id;
};
......
......@@ -3,26 +3,26 @@
<div class="row">
<CardCustom title="实体清单发布机构" :style="{ width: '984px', height: '284px' }">
<div class="panel1">
<img :src="panel1.img" alt="" class="img" />
<img :src="organizationInfo.img" alt="" class="img" />
<div class="infoWrap">
<div class="item">
<div class="name">机构名称:</div>
<div class="doc">{{ panel1.mingcheng }}</div>
<div class="doc">{{ organizationInfo.mingcheng }}</div>
</div>
<div class="item">
<div class="name">相关措施:</div>
<div class="doc">{{ panel1.cuoshi }}</div>
<div class="doc">{{ organizationInfo.cuoshi }}</div>
</div>
<div class="item">
<div class="name">机构职责:</div>
<div class="doc zhize">{{ panel1.zhize }}</div>
<div class="doc zhize">{{ organizationInfo.zhize }}</div>
</div>
</div>
</div>
</CardCustom>
<CardCustom title="重点人物" :style="{ width: '600px', height: '284px' }">
<div class="panel2">
<div class="item" v-for="(item, index) in panel2" :key="index">
<div class="item" v-for="(item, index) in personLis" :key="index">
<img :src="item.img" alt="" class="img" />
<div class="infoWrap">
<div class="name">{{ item.name }}</div>
......@@ -64,7 +64,7 @@
</CardCustom>
<CardCustom title="制裁原因" :style="{ width: '600px', height: '520px' }">
<div class="panel4">
<div class="item" v-for="(item, index) in panel4" :key="index">
<div class="item" v-for="(item, index) in sanReasonSelect" :key="index">
<div class="icon1">{{ index + 1 }}</div>
<div class="text">{{ item.text }}</div>
<div class="icon2"></div>
......@@ -96,7 +96,7 @@
</div>
<div class="tableWrap">
<el-table
:data="panel5MockData"
:data="selectEntitiesList"
class="sanction-table"
stripe
empty-text="暂无数据"
......@@ -106,7 +106,10 @@
<el-table-column prop="name" label="实体清单" min-width="180">
<template #default="{ row }">
<div style="font-weight: 500" class="name">
<img :src="row.img" alt="" class="img" />
<img v-if="row.img" :src="row.img" alt="" class="img" />
<div v-else class="imgUndefined">
{{ row.name?.match(/[\u4e00-\u9fa5a-zA-Z0-9]/)?.[0] }}
</div>
{{ row.name }}
</div>
</template>
......@@ -122,7 +125,7 @@
</template>
</el-table-column>
<el-table-column prop="address" label="上市地点" width="100" align="center">
<el-table-column prop="address" label="上市地点" width="90" align="center">
<template #default="{ row }">
{{ row.address }}
</template>
......@@ -180,8 +183,7 @@ import PieCharts from "../components/pieCharts.vue";
import MapCharts from "../components/mapCharts.vue";
import ButtonList from "@/components/buttonList/buttonList.vue";
import Hint from "../components/hint.vue";
import { onMounted, reactive, ref } from "vue";
import { onMounted, reactive, ref, shallowRef } from "vue";
import panel1_1 from "../../assets/images/panel1_1.png";
import panel2_1 from "../../assets/images/panel2_1.png";
import panel2_2 from "../../assets/images/panel2_2.png";
......@@ -195,43 +197,39 @@ import panel5_5 from "../../assets/images/panel5_5.png";
import panel5_6 from "../../assets/images/panel5_6.png";
import panel5_7 from "../../assets/images/panel5_7.png";
import panel5_8 from "../../assets/images/panel5_8.png";
const panel1 = ref({
img: panel1_1,
mingcheng: "美国商务部工业与安全局",
cuoshi: "出口管制条例(EAR)、实体清单、商业管制清单(CCL)、232调查等",
zhize: "美国商务部工业与安全局(BIS)是美国商务部下属机构,核心职责围绕国家安全与战略技术管控展开,具体包括:以维护商业管制清单(CCL)和出口管制分类号(ECCN)的方式,对敏感货物及两用技术实施出口管制并确定许可要求;通过出口执行局(OEE)执行出口管制、反抵制等相关法律,对违规行为采取行政、刑事等处罚措施;在出口管制和战略贸易问题上与其他国家合作,参与并领导国际出口管制制度。"
});
const panel2 = ref([
{
name: "吉娜·雷蒙多",
enName: "Gina Raimondo",
party: "美国民主党",
img: panel2_1
},
{
name: "迈克・约翰逊",
enName: "Mike Johnson",
party: "美国共和党",
img: panel2_2
},
{
name: "艾伦·埃斯特韦斯",
enName: "Alan Estevez",
party: "美国民主党",
img: panel2_3
},
{
name: "凯・格兰杰",
enName: "Kay Granger",
party: "美国共和党",
img: panel2_4
}
import { getOrganizationInfo, getPersonList, getSanReasonSelect, getSelectEntitiesList } from "@/api/exportControl";
import _ from "lodash";
import { useRoute } from "vue-router";
import { formatAnyDateToChinese } from "../../utils";
const route = useRoute();
const organizationInfo = shallowRef({});
const personLis = shallowRef([
// {
// name: "吉娜·雷蒙多",
// enName: "Gina Raimondo",
// party: "美国民主党",
// img: panel2_1
// },
// {
// name: "迈克・约翰逊",
// enName: "Mike Johnson",
// party: "美国共和党",
// img: panel2_2
// },
// {
// name: "艾伦·埃斯特韦斯",
// enName: "Alan Estevez",
// party: "美国民主党",
// img: panel2_3
// },
// {
// name: "凯・格兰杰",
// enName: "Kay Granger",
// party: "美国共和党",
// img: panel2_4
// }
]);
const panel3ActiveIndex = ref(1);
const setPanel3ActiveIndex = index => {
panel3ActiveIndex.value = index;
};
const panel4 = ref([
const sanReasonSelect = shallowRef([
{
text: "获取美国产物项,以支持中国量子技术;"
},
......@@ -248,6 +246,54 @@ const panel4 = ref([
text: "将中国定位为“通过强制技术转让获取先进制程的威胁”"
}
]);
const selectEntitiesList = shallowRef([]);
onMounted(async () => {
try {
const [organizationInfoData, personListData, sanReasonSelectData, selectEntitiesListData] = await Promise.all([
getOrganizationInfo(),
getPersonList(),
getSanReasonSelect(route.query.startTime),
getSelectEntitiesList(route.query.startTime)
]);
organizationInfo.value = {
img: panel1_1,
mingcheng: organizationInfoData?.orgName,
cuoshi: organizationInfoData?.cuoshi || "美国商务部工业与安全局",
zhize: organizationInfoData?.orgIntroduction || "--"
};
personLis.value = _.map(personListData, item => {
return {
name: item.name,
enName: item.enName,
party: item.positionTitle,
img: item.avatarUrl
};
});
sanReasonSelect.value = _.map(sanReasonSelectData, item => {
return { text: item };
});
selectEntitiesList.value = _.map(selectEntitiesListData, item => {
return {
name: item?.entityNameZh,
domains: item.techDomainList,
address: "--",
time: formatAnyDateToChinese(item?.startTime),
isUp: true,
revenue: "--",
subCompany: "--",
img: ""
};
});
} catch (err) {
console.log(err);
}
});
const panel3ActiveIndex = ref(1);
const setPanel3ActiveIndex = index => {
panel3ActiveIndex.value = index;
};
const panel5ButtonList = [
{ id: 1, text: "新增实体" },
......@@ -379,7 +425,7 @@ const panel6 = ref([
}
.panel1 {
height: 100%;
padding: 2px 24px 0 24px;
padding: 2px 35px 0 24px;
display: flex;
.img {
width: 90px;
......@@ -414,6 +460,11 @@ const panel6 = ref([
font-size: 16px;
font-weight: 400;
line-height: 24px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 5; /* 控制行数 */
overflow: hidden;
text-overflow: ellipsis;
}
}
}
......@@ -551,6 +602,10 @@ const panel6 = ref([
font-weight: 400;
line-height: 30px;
flex: 1;
overflow: hidden;
white-space: noWrap;
text-overflow: ellipsis;
min-width: 0;
}
.icon2 {
width: 16px;
......@@ -605,6 +660,7 @@ const panel6 = ref([
flex: 1;
margin-top: 14px;
min-height: 0;
overflow: auto;
}
.name {
display: flex;
......@@ -614,6 +670,20 @@ const panel6 = ref([
height: 40px;
margin-right: 6px;
margin-left: 6px;
flex-shrink: 0;
}
.imgUndefined {
width: 40px;
height: 40px;
display: flex;
justify-content: center;
align-items: center;
flex-shrink: 0;
color: rgba(5, 95, 194, 1);
background-color: rgb(236, 245, 255);
border-radius: 20px;
margin-right: 6px;
margin-left: 6px;
}
}
.subCompany {
......
......@@ -125,7 +125,8 @@ import icon2 from "../assets/icons/icon2.png";
import icon2Active from "../assets/icons/icon2_active.png";
import icon3 from "../assets/icons/icon3.png";
import icon3Active from "../assets/icons/icon3_active.png";
import { useRoute } from "vue-router";
const route = useRoute();
const activeName = ref("分析报告");
const handleSwitchActiveName = name => {
......@@ -171,7 +172,12 @@ const activeTitle = ref("制裁概况");
const handleClickMainHeaderBtn = item => {
activeTitle.value = item.name;
// window.sessionStorage.setItem('activeTitle', activeTitle.value)
router.push(item.path);
router.push({
path: item.path,
query: {
...route.query
}
});
};
const activeNavIndex = ref(0);
......
import * as echarts from 'echarts';
import chinaJson from './China.json'
import _ from 'lodash';
//饼图
export function getPieOption(data, title) {
let option = {
......@@ -85,7 +86,7 @@ export function getPieOption1(data, title) {
},
label: {
alignTo: 'edge',
formatter: '{b}\n{two|{c}家 {d}%}',
formatter: `{b}${data.length < 10 ? '\n' : ''} {two|{c}家 {d}%}`,
fontSize: 17.6,
fontWeight: 700,
minMargin: 5,
......@@ -104,12 +105,13 @@ export function getPieOption1(data, title) {
maxSurfaceAngle: 80
},
labelLayout: function (params) {
console.log('labelLayoutparams', params)
const isLeft = params.labelRect.x < 556 / 2;
const points = params.labelLinePoints;
// Update the end point.
points[2][0] = isLeft
? params.labelRect.x
: params.labelRect.x + params.labelRect.width;
? data.length < 10 ? params.labelRect.x : (params.labelRect.x + params.labelRect.width)
: data.length < 10 ? (params.labelRect.x + params.labelRect.width) : params.labelRect.x;
return {
labelLinePoints: points
};
......@@ -600,7 +602,7 @@ export const getBarChart = (nameList, valueList, color = ['rgba(255, 159, 22, 1)
}
return option
}
export const getLineChart = (color = 'rgba(146, 84, 222, 1)') => {
export const getLineChart = (object, isPercent) => {
const option = {
title: {
text: ""
......@@ -611,11 +613,11 @@ export const getLineChart = (color = 'rgba(146, 84, 222, 1)') => {
let result = params[0].name + '<br/>';
params.forEach(function (item, index) {
// 自定义颜色数组
const customColors = [color];
const customColors = [object.color];
const dotColor = customColors[index % customColors.length]; // 循环取色
// 创建彩色圆点图标
const dot = `<span style="display:inline-block;margin-right:5px;border-radius:50%;width:10px;height:10px;background-color:${dotColor};"></span>`;
result += dot + `${item.seriesName}: ${item.value}<br/>`;
result += dot + `${item.seriesName}: ${item.value}${isPercent ? '%' : ''}<br/>`;
});
return result;
}
......@@ -648,7 +650,7 @@ export const getLineChart = (color = 'rgba(146, 84, 222, 1)') => {
// fontSize: 22,
// fontWeight: 400
},
data: ["2015", "2016", "2017", "2018", "2019", "2020", "2021", "2022", "2023"]
data: object.xAxisData
},
yAxis: {
type: "value",
......@@ -662,7 +664,9 @@ export const getLineChart = (color = 'rgba(146, 84, 222, 1)') => {
color: "rgba(95, 101, 108, 1)",
// fontSize: 22,
// fontWeight: 400
formatter: `{value} ${isPercent ? '%' : ''}`
},
splitNumber: 8,
splitLine: {
lineStyle: {
......@@ -675,19 +679,19 @@ export const getLineChart = (color = 'rgba(146, 84, 222, 1)') => {
},
series: [
{
name: "增长趋势",
name: object.name,
type: "line",
symbolSize: 8,
symbol: 'circle',
itemStyle: {
color: "#ffffff",
borderColor: color,
borderColor: object.color,
borderWidth: 3
},
lineStyle: {
color: color,
color: object.color,
},
data: [3, 6, 4, 7, 9, 6, 5, 6, 6]
data: object.seriesData
}
]
};
......@@ -970,3 +974,61 @@ export const getMultipleLineChart = (obj) => {
};
return option;
}
//出口管制主页接口
export const getMultipleBarChart_m = (object) => {
const list = _.chain(object.data).filter('year').orderBy('year', 'asc').value();
const colors = [
['rgba(22, 119, 255, 1)', 'rgba(22, 119, 255, 0)'],
['rgba(206, 79, 81, 1)', 'rgba(206, 79, 81, 0)'],
['rgba(255, 197, 61, 1)', 'rgba(255, 197, 61, 0)'],
['rgba(255, 204, 199, 1)', 'rgba(255, 204, 199, 0)'],
['rgba(179, 127, 235, 1)', 'rgba(179, 127, 235, 0)'],
['rgba(127, 218, 235, 1)', 'rgba(127, 214, 235, 0)'],
];
const names = _.map(list, 'year');
const datas = _.chain(object.domains).splice(0, 6).map((name, index) => {
console.log(_.map(list, name))
return {
name,
data: _.map(list, `domainNum.${name}`),
type: "bar",
barWidth: 12,
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: colors[index % colors.length][0] },
// { offset: 0.5, color: '#188df0' },
{ offset: 1, color: colors[index % colors.length][1] }
]),
borderRadius: [6, 6, 0, 0]
}
}
}).value();
console.log('names', names)
const option = {
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow"
}
},
grid: {
top: 50
},
legend: {
// type: "scroll",
// show: true,
// orient: "horizontal",
icon: "circle",
},
xAxis: {
type: "category",
data: names
},
yAxis: {
type: "value"
},
series: datas
}
return option;
}
export function formatAnyDateToChinese(dateStr) {
// 支持多种分隔符
const date = new Date(dateStr.replace(/\//g, '-'));
if (isNaN(date.getTime())) {
return ''
}
// 手动获取各部分,避免Intl可能存在的兼容性考虑
const year = date.getFullYear();
const month = date.getMonth() + 1; // 月份从0开始,需+1
const day = date.getDate();
return `${year}${month}${day}日`;
}
\ No newline at end of file
......@@ -315,9 +315,9 @@
</div>
<div class="box6-main">
<div class="box6-main-select-box">
<el-select v-model="curAreaYear" placeholder="选择发布时间" style="width: 120px">
<el-select v-model="box6SelectedYear" placeholder="选择时间" style="width: 120px">
<el-option
v-for="item in areaYearList"
v-for="item in box6YearList"
:key="item.value"
:label="item.label"
:value="item.value"
......@@ -348,9 +348,9 @@
<div class="box7-main-left" id="box7Chart1"></div>
<div class="box7-main-right">
<div class="box7-main-right-top">
<el-select v-model="curAreaYear" placeholder="选择发布时间" style="width: 120px">
<el-select v-model="box7SelectedYear" placeholder="选择时间" style="width: 120px">
<el-option
v-for="item in areaYearList"
v-for="item in box7YearList"
:key="item.value"
:label="item.label"
:value="item.value"
......@@ -661,7 +661,7 @@ const chart1Data = ref({
]
});
const areaYearList = ref([
const box7YearList = ref([
{
label: "2025",
value: "2025"
......@@ -688,7 +688,7 @@ const areaYearList = ref([
}
]);
const curAreaYear = ref("2025");
const box7SelectedYear = ref("2025");
const surveyYearList = ref([
{
......@@ -894,6 +894,36 @@ const handleToMoreNews = () => {
window.open(route.href, "_blank");
};
// 制裁领域分布
const box6SelectedYear = ref("2025");
const box6YearList = ref([
{
label: "2025",
value: "2025"
},
{
label: "2024",
value: "2024"
},
{
label: "2023",
value: "2023"
},
{
label: "2022",
value: "2022"
},
{
label: "2021",
value: "2021"
},
{
label: "2020",
value: "2020"
}
]);
const box7Chart1Data = ref([
{
name: "337调查",
......@@ -2154,11 +2184,14 @@ onMounted(async () => {
position: relative;
.box6-main-select-box {
position: absolute;
z-index: 100;
top: 10px;
right: 20px;
}
.box6-mian-chart {
height: 360px;
position: relative;
z-index: 99;
}
}
}
......
......@@ -27,8 +27,8 @@
<div class="item-header-text">打压遏制手段分布</div>
</div>
<div class="item-header-divider"></div>
<div style="display: flex; justify-content: space-between; width: 100%; height: calc(100% - 60px);">
<div class="thematic-btn-left" @click="changeBtn('left')">
<div style="display: flex; justify-content: space-between; width: 100%; height: calc(100% - 60px);" @mouseenter="handleChangeSwiper(false)" @mouseleave="handleChangeSwiper(true)">
<div class="thematic-btn-left" @click="handleSwitch('left')">
<img class="thematic-btn-icon" src="@/assets/images/icon/card-btn-left.png"></img>
</div>
......@@ -45,7 +45,7 @@
</div>
</div>
</div>
<div class="thematic-btn-right" @click="changeBtn('right')">
<div class="thematic-btn-right" @click="handleSwitch('right')">
<img class="thematic-btn-icon" src="@/assets/images/icon/card-btn-right.png"></img>
</div>
</div>
......@@ -169,7 +169,7 @@
</template>
<script setup>
import { onMounted, ref, computed } from "vue";
import { onMounted, ref, computed, onUnmounted } from "vue";
import router from "@/router/index";
import * as echarts from "echarts";
import DivideHeader from "@/components/DivideHeader.vue";
......@@ -232,8 +232,7 @@ const course = ref([
}
]);
//打压遏制手段分布
const distribution = ref([
const totalDistribution = ref([
{
titlle: "法案",
value: 80,
......@@ -287,9 +286,126 @@ const distribution = ref([
change: "较上个月+1",
path: "/marketAccessRestrictions",
color: ["#FFE3B9", "#FFEDCE", "#FFF7E6", "#D46B08"]
}
},
{
titlle: "合作限制",
value: 41,
text: "127",
unit: "次",
change: "较上个月+3",
path: "/cooperationRestrictions",
color: ["rgba(139,69,19,0.4)", "rgba(139,69,19,0.5)", "rgba(139,69,19,0.3)", "rgba(139,69,19,1)"]
},
{
titlle: "规则限制",
value: 24,
text: "724",
unit: "个",
change: "较上月+5",
path: "/ruleRestrictions",
color: ["#9AC8FF", "#BCDCFF", "#E7F4FF", "#0F5EDB"]
},
{
titlle: "科研资助体系",
value: 64,
text: "128",
unit: "个",
change: "较上月+8",
path: "/scientificFunding",
color: ["#FDE19A", "#FEECBD", "#FFFBE6", "#D68E16"]
},
]);
const startIndex = ref(0);
const handleSwitch = flag => {
if (flag == "left") {
if (startIndex.value === 0) {
startIndex.value = totalDistribution.value.length - 6;
} else {
startIndex.value--;
}
} else {
if (startIndex.value === totalDistribution.value.length - 6) {
startIndex.value = 0;
} else {
startIndex.value++;
}
}
};
//打压遏制手段分布
const distribution = computed(() => {
return totalDistribution.value.slice(startIndex.value, startIndex.value + 6);
});
//打压遏制手段分布
// const distribution = ref([
// {
// titlle: "法案",
// value: 80,
// text: "1626",
// unit: "个",
// change: "较上月+3",
// path: "/billHome",
// color: ["#9AC8FF", "#BCDCFF", "#E7F4FF", "#0F5EDB"]
// },
// {
// titlle: "行政令",
// value: 20,
// text: "1626",
// unit: "个",
// change: "较上月+1",
// path: "/decree",
// color: ["#FDE19A", "#FEECBD", "#FFFBE6", "#D68E16"]
// },
// {
// titlle: "科技智库",
// value: 10,
// text: "66",
// unit: "次",
// change: "较上月+2",
// path: "/thinkTank",
// color: ["#C9AAF0", "#DFCAF6", "#FAF1FF", "#531DAC"]
// },
// {
// titlle: "出口管制",
// value: 33,
// text: "66",
// unit: "次",
// change: "较上月+1",
// path: "/exportControl",
// color: ["#96DFDD", "#BCEFEC", "#E7FFFB", "#006E75"]
// },
// {
// titlle: "投融资限制",
// value: 80,
// text: "119",
// unit: "次",
// change: "较上月+1",
// path: "/finance",
// color: ["#F5BEBC", "#F7D3D0", "#FEF1F0", "#C64C4E"]
// },
// {
// titlle: "市场准入",
// value: 50,
// text: "223",
// unit: "次",
// change: "较上个月+1",
// path: "/marketAccessRestrictions",
// color: ["#FFE3B9", "#FFEDCE", "#FFF7E6", "#D46B08"]
// },
// {
// titlle: "合作限制",
// value: 41,
// text: "127",
// unit: "次",
// change: "较上个月+3",
// path: "/cooperationRestrictions",
// color: ["rgba(139,69,19,0.4)", "rgba(139,69,19,0.5)", "rgba(139,69,19,0.3)", "rgba(139,69,19,1)"]
// }
// ]);
//随机生成颜色
const makeColors = () => {
let A = Math.floor(Math.random() * 360); // 随机色相
......@@ -380,7 +496,20 @@ const handleClickItem = item => {
});
};
const swiper = ref(null);
const isOnSwiper = ref(true)
const handleChangeSwiper = (val) => {
isOnSwiper.value = val
}
onMounted(() => {
swiper.value = setInterval(() => {
if (isOnSwiper.value) {
handleSwitch("right");
}
}, 3600);
let char1 = getBarChart(chart1Data.value.name, chart1Data.value.value, true);
setChart(char1, "chart1");
......@@ -388,12 +517,15 @@ onMounted(() => {
let char2 = radarChart();
setChart(char2, "char2");
});
onUnmounted(() => {
clearInterval(swiper.value);
});
</script>
<style lang="scss" scoped>
.cup-box {
overflow-x: auto;
.cup-item-box {
width: 240px;
text-align: center;
......@@ -534,12 +666,14 @@ onMounted(() => {
height: 100%;
width: 24px;
padding-top: 130px;
cursor: pointer;
}
.thematic-btn-right {
height: 100%;
width: 24px;
padding-top: 130px;
cursor: pointer;
}
.thematic-btn-icon {
......
<template>
<div class="com-title">
<div class="cl1"></div>
<div class="cl2"></div>
<div class="title">{{ title }}</div>
<div class="cl3"></div>
</div>
</template>
<script setup>
import { ref } from "vue";
// 传入的title数据
const props = defineProps({
title: {
type: String,
default: ""
}
});
</script>
<style scoped lang="scss">
* {
margin: 0;
padding: 0;
}
.com-title {
width: 1575px;
height: 42px;
display: flex;
align-items: center;
.cl1 {
width: 24px;
height: 30px;
background-color: rgba(174, 214, 255, 1);
margin-right: 8px;
}
.cl2 {
width: 8px;
height: 30px;
background-color: rgba(174, 214, 255, 1);
margin-right: 8px;
}
.title {
width: 152px;
height: 42px;
text-align: center;
font-size: 32px;
font-weight: 700;
font-family: 'Microsoft YaHei';
line-height: 42px;
margin-right: 8px;
}
.cl3 {
width: 1367px;
height: 1px;
background-color: rgba(174, 214, 255, 1);
box-sizing: border-box;
}
}
</style>
差异被折叠。
差异被折叠。
差异被折叠。
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论