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

合并分支 'hsx' 到 'master'

feat:企业详情供应链关系 查看合并请求 !163
<svg viewBox="0 0 52 52" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="52.000000" height="52.000000" fill="none" customFrame="#000000">
<defs>
<g id="pixso_custom_effect_0">
<effect x="0.000000" y="0.000000" visibility="visible" fill="rgb(0,0,0)" fill-opacity="0.100000001" effectType="dropShadow" stdDeviation="8" radius="0" />
</g>
<filter id="filter_0" width="52.000000" height="52.000000" x="0.000000" y="0.000000" filterUnits="userSpaceOnUse" customEffect="url(#pixso_custom_effect_0)" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feOffset dx="0.000000" dy="0.000000" in="SourceAlpha" />
<feGaussianBlur stdDeviation="2.66666675" />
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0 " />
<feBlend result="effect_dropShadow_1" in2="BackgroundImageFix" mode="normal" />
<feBlend result="shape" in="SourceGraphic" in2="effect_dropShadow_1" mode="normal" />
</filter>
<clipPath id="clipPath_0">
<rect width="16.000000" height="16.000000" x="18.000000" y="18.000000" fill="rgb(255,255,255)" />
</clipPath>
</defs>
<rect id="普通企业节点" width="36.000000" height="36.000000" x="8.000000" y="8.000000" />
<g filter="url(#filter_0)">
<circle id="椭圆 25" cx="26" cy="26" r="18" fill="rgb(246,250,255)" />
<circle id="椭圆 25" cx="26" cy="26" r="17.5" stroke="rgb(231,243,255)" stroke-width="1.000000" />
</g>
<g id="企业 " clip-path="url(#clipPath_0)" customFrame="url(#clipPath_0)">
<rect id="企业 " width="16.000000" height="16.000000" x="18.000000" y="18.000000" />
<path id="矢量 370" d="M33.4667 31.9231L32.9333 31.9231L32.9333 24.3846C32.9333 23.2 31.9733 22.2308 30.8 22.2308L27.6 22.2308L27.6 21.1538C27.6 19.9692 26.64 19 25.4667 19L21.2 19C20.0267 19 19.0667 19.9692 19.0667 21.1538L19.0667 31.9231L18.5333 31.9231C18.2347 31.9231 18 32.16 18 32.4615C18 32.7631 18.2347 33 18.5333 33L33.4667 33C33.7653 33 34 32.7631 34 32.4615C34 32.16 33.7653 31.9231 33.4667 31.9231ZM26.5333 22.2308L26.5333 23.3077L26.5333 31.9231L20.1333 31.9231L20.1333 21.1538C20.1333 20.5615 20.6133 20.0769 21.2 20.0769L25.4667 20.0769C26.0533 20.0769 26.5333 20.5615 26.5333 21.1538L26.5333 22.2308ZM31.8667 31.9231L27.6 31.9231L27.6 23.3077L30.8 23.3077C31.3867 23.3077 31.8667 23.7923 31.8667 24.3846L31.8667 31.9231ZM24.9333 22.2308L21.7333 22.2308C21.4347 22.2308 21.2 22.4677 21.2 22.7692C21.2 23.0708 21.4347 23.3077 21.7333 23.3077L24.9333 23.3077C25.232 23.3077 25.4667 23.0708 25.4667 22.7692C25.4667 22.4677 25.232 22.2308 24.9333 22.2308ZM24.9333 25.4615L21.7333 25.4615C21.4347 25.4615 21.2 25.6985 21.2 26C21.2 26.3015 21.4347 26.5385 21.7333 26.5385L24.9333 26.5385C25.232 26.5385 25.4667 26.3015 25.4667 26C25.4667 25.6985 25.232 25.4615 24.9333 25.4615ZM24.9333 28.6923L21.7333 28.6923C21.4347 28.6923 21.2 28.9292 21.2 29.2308C21.2 29.5323 21.4347 29.7692 21.7333 29.7692L24.9333 29.7692C25.232 29.7692 25.4667 29.5323 25.4667 29.2308C25.4667 28.9292 25.232 28.6923 24.9333 28.6923ZM30.2667 25.4615L29.2 25.4615C28.9013 25.4615 28.6667 25.6985 28.6667 26C28.6667 26.3015 28.9013 26.5385 29.2 26.5385L30.2667 26.5385C30.5653 26.5385 30.8 26.3015 30.8 26C30.8 25.6985 30.5653 25.4615 30.2667 25.4615ZM30.2667 28.6923L29.2 28.6923C28.9013 28.6923 28.6667 28.9292 28.6667 29.2308C28.6667 29.5323 28.9013 29.7692 29.2 29.7692L30.2667 29.7692C30.5653 29.7692 30.8 29.5323 30.8 29.2308C30.8 28.9292 30.5653 28.6923 30.2667 28.6923Z" fill="rgb(5,95,194)" fill-rule="nonzero" />
</g>
</svg>
<svg viewBox="0 0 52 52" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="52.000000" height="52.000000" fill="none" customFrame="#000000">
<defs>
<g id="pixso_custom_effect_1">
<effect x="0.000000" y="0.000000" visibility="visible" fill="rgb(0,0,0)" fill-opacity="0.100000001" effectType="dropShadow" stdDeviation="8" radius="0" />
</g>
<filter id="filter_1" width="52.000000" height="52.000000" x="0.000000" y="0.000000" filterUnits="userSpaceOnUse" customEffect="url(#pixso_custom_effect_1)" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feOffset dx="0.000000" dy="0.000000" in="SourceAlpha" />
<feGaussianBlur stdDeviation="2.66666675" />
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0 " />
<feBlend result="effect_dropShadow_1" in2="BackgroundImageFix" mode="normal" />
<feBlend result="shape" in="SourceGraphic" in2="effect_dropShadow_1" mode="normal" />
</filter>
<clipPath id="clipPath_1">
<rect width="16.000000" height="16.000000" x="18.000000" y="18.000000" fill="rgb(255,255,255)" />
</clipPath>
</defs>
<rect id="普通企业节点" width="36.000000" height="36.000000" x="8.000000" y="8.000000" />
<g filter="url(#filter_1)">
<circle id="椭圆 25" cx="26" cy="26" r="18" fill="rgb(255,255,255)" />
<circle id="椭圆 25" cx="26" cy="26" r="17.5" stroke="rgb(230,231,232)" stroke-width="1.000000" />
</g>
<g id="企业 " clip-path="url(#clipPath_1)" customFrame="url(#clipPath_1)">
<rect id="企业 " width="16.000000" height="16.000000" x="18.000000" y="18.000000" />
<path id="矢量 370" d="M33.4667 31.9231L32.9333 31.9231L32.9333 24.3846C32.9333 23.2 31.9733 22.2308 30.8 22.2308L27.6 22.2308L27.6 21.1538C27.6 19.9692 26.64 19 25.4667 19L21.2 19C20.0267 19 19.0667 19.9692 19.0667 21.1538L19.0667 31.9231L18.5333 31.9231C18.2347 31.9231 18 32.16 18 32.4615C18 32.7631 18.2347 33 18.5333 33L33.4667 33C33.7653 33 34 32.7631 34 32.4615C34 32.16 33.7653 31.9231 33.4667 31.9231ZM26.5333 22.2308L26.5333 23.3077L26.5333 31.9231L20.1333 31.9231L20.1333 21.1538C20.1333 20.5615 20.6133 20.0769 21.2 20.0769L25.4667 20.0769C26.0533 20.0769 26.5333 20.5615 26.5333 21.1538L26.5333 22.2308ZM31.8667 31.9231L27.6 31.9231L27.6 23.3077L30.8 23.3077C31.3867 23.3077 31.8667 23.7923 31.8667 24.3846L31.8667 31.9231ZM24.9333 22.2308L21.7333 22.2308C21.4347 22.2308 21.2 22.4677 21.2 22.7692C21.2 23.0708 21.4347 23.3077 21.7333 23.3077L24.9333 23.3077C25.232 23.3077 25.4667 23.0708 25.4667 22.7692C25.4667 22.4677 25.232 22.2308 24.9333 22.2308ZM24.9333 25.4615L21.7333 25.4615C21.4347 25.4615 21.2 25.6985 21.2 26C21.2 26.3015 21.4347 26.5385 21.7333 26.5385L24.9333 26.5385C25.232 26.5385 25.4667 26.3015 25.4667 26C25.4667 25.6985 25.232 25.4615 24.9333 25.4615ZM24.9333 28.6923L21.7333 28.6923C21.4347 28.6923 21.2 28.9292 21.2 29.2308C21.2 29.5323 21.4347 29.7692 21.7333 29.7692L24.9333 29.7692C25.232 29.7692 25.4667 29.5323 25.4667 29.2308C25.4667 28.9292 25.232 28.6923 24.9333 28.6923ZM30.2667 25.4615L29.2 25.4615C28.9013 25.4615 28.6667 25.6985 28.6667 26C28.6667 26.3015 28.9013 26.5385 29.2 26.5385L30.2667 26.5385C30.5653 26.5385 30.8 26.3015 30.8 26C30.8 25.6985 30.5653 25.4615 30.2667 25.4615ZM30.2667 28.6923L29.2 28.6923C28.9013 28.6923 28.6667 28.9292 28.6667 29.2308C28.6667 29.5323 28.9013 29.7692 29.2 29.7692L30.2667 29.7692C30.5653 29.7692 30.8 29.5323 30.8 29.2308C30.8 28.9292 30.5653 28.6923 30.2667 28.6923Z" fill="rgb(59,65,75)" fill-rule="nonzero" />
</g>
</svg>
...@@ -164,4 +164,11 @@ export function getRelevantMeasures(params) { ...@@ -164,4 +164,11 @@ export function getRelevantMeasures(params) {
// url: `/api/organization/relate/news`, // url: `/api/organization/relate/news`,
// data, // data,
// }) // })
// } // }
\ No newline at end of file
export function getRuleOrg(params) {
return request({
method: 'POST',
url: `/api/organization/relate/ruleOrg`, data: params
})
}
\ No newline at end of file
<template>
<div class="color-svg" v-if="svgContent">
<div v-html="processedSvgContent" class="svg-container"></div>
</div>
<div class="color-svg-loading" v-else>
<div class="loading-spinner"></div>
</div>
</template>
<script setup lang="ts">
import { size } from 'lodash';
import { ref, computed, watch, onMounted } from 'vue';
// 组件属性
const props = defineProps({
// SVG地址
svgUrl: {
type: String,
required: true
},
// SVG颜色
color: {
type: String,
default: '#000'
}
, size: {
type: Number,
default: null
}
});
// 组件事件
const emit = defineEmits(['svg-loaded', 'svg-error']);
// 状态管理
const svgContent = ref<string>('');
const isLoading = ref<boolean>(false);
const error = ref<string>('');
// 处理后的SVG内容
const processedSvgContent = computed(() => {
if (!svgContent.value) return '';
// 替换SVG中的颜色
let processed = svgContent.value;
// 替换fill属性
processed = processed.replace(/fill="([^"]*)"/g, (match, p1) => {
// 保留透明和none值
if (p1 === 'none' || p1 === 'transparent') {
return match;
}
return `fill="${props.color}"`;
});
// 替换stroke属性
processed = processed.replace(/stroke="([^"]*)"/g, (match, p1) => {
// 保留透明和none值
if (p1 === 'none' || p1 === 'transparent') {
return match;
}
return `stroke="${props.color}"`;
});
// 替换width属性
processed = processed.replace(/width="([^"]*)"/g, (match, p1) => {
if (props.size !== null) {
return `width="${props.size}"`;
}
return match;
});
// 替换height属性
processed = processed.replace(/height="([^"]*)"/g, (match, p1) => {
if (props.size !== null) {
return `height="${props.size}"`;
}
return match;
});
console.log(processed)
return processed;
});
// 加载SVG内容
const loadSvgContent = async () => {
if (!props.svgUrl) return;
isLoading.value = true;
error.value = '';
try {
const response = await fetch(props.svgUrl);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const content = await response.text();
svgContent.value = content;
emit('svg-loaded', content);
} catch (err) {
error.value = err instanceof Error ? err.message : 'Failed to load SVG';
emit('svg-error', error.value);
console.error('Error loading SVG:', err);
} finally {
isLoading.value = false;
}
};
// 监听属性变化
watch(
() => props.svgUrl,
() => {
loadSvgContent();
}
);
watch(
() => props.color,
() => {
// 颜色变化时重新处理SVG,不需要重新加载
}
);
// 组件挂载时加载SVG
onMounted(() => {
loadSvgContent();
});
</script>
<style scoped>
.color-svg {
display: inline-block;
}
.svg-container {
display: inline-block;
width: 100%;
height: 100%;
}
.color-svg-loading {
display: flex;
align-items: center;
justify-content: center;
width: 100px;
height: 100px;
}
.loading-spinner {
width: 20px;
height: 20px;
border: 2px solid #f3f3f3;
border-top: 2px solid #3498db;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>
\ No newline at end of file
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
border-radius: 4px; border-radius: 4px;
border: 1px solid var(--color-primary-10); border: 1px solid var(--color-primary-10);
color: var(--color-primary-100); color: var(--color-primary-100);
margin: 10px;
} }
.img { .img {
......
<template> <template>
<el-space @click="onClick(person)"> <el-space @click="onClick(person)">
<ElAvatar :size="48" :src="person[img]" alignment="center" /> <el-avatar :size="48" :src="person[img]" alignment="center" />
<el-space :size="0" direction="vertical" alignment="flex-start"> <el-space :size="0" direction="vertical" alignment="flex-start">
<div class="text-header">{{ person[name] }}</div> <div class="text-header">{{ person[name] }}</div>
<div class="person-position">{{ person[position] }}</div> <div class="person-position">{{ person[position] }}</div>
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
<script setup> <script setup>
import '@/styles/common.scss' import '@/styles/common.scss'
import { ElSpace } from 'element-plus'; import { ElSpace, ElAvatar } from 'element-plus';
const props = defineProps({ const props = defineProps({
// 新闻列表数据 // 新闻列表数据
......
<template>
<el-space :size="16" class="text-tip-1-bold box">
<div class="color-prefix"></div>
<slot></slot>
</el-space>
</template>
<script setup lang="ts">
import '@/styles/common.scss';
import { ElSpace } from 'element-plus';
const props = defineProps({
color: {
type: String,
default: 'var(--color-primary-100)'
}
})
</script>
<style lang="scss" scoped>
.color-prefix {
width: 8px;
height: 16px;
background-color: v-bind(color);
}
.box {
color: v-bind(color);
}
</style>
\ No newline at end of file
...@@ -9,7 +9,7 @@ const companyPagesRoutes = [ ...@@ -9,7 +9,7 @@ const companyPagesRoutes = [
{ {
path: "/companyPages/:id", path: "/companyPages/:id",
name: "companyPages", name: "companyPages",
component: companyPages, component: companyPages2,
meta: { meta: {
title: "企业主页", title: "企业主页",
dynamicTitle: true dynamicTitle: true
...@@ -19,7 +19,7 @@ const companyPagesRoutes = [ ...@@ -19,7 +19,7 @@ const companyPagesRoutes = [
{ {
path: "/companyPages2/:id", path: "/companyPages2/:id",
name: "companyPages2", name: "companyPages2",
component: companyPages2, component: companyPages,
meta: { meta: {
title: "企业主页", title: "企业主页",
dynamicTitle: true dynamicTitle: true
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
border-radius: 10px; border-radius: 10px;
border: 1px solid var(--bg-white-100); border: 1px solid var(--bg-white-100);
border-radius: 10px; border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1); box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.15);
} }
.flex-display { .flex-display {
...@@ -33,6 +33,10 @@ ...@@ -33,6 +33,10 @@
flex: 1; flex: 1;
} }
.full-width {
width: 100%;
}
// 文本超出指定行数省略号显示 // 文本超出指定行数省略号显示
@mixin text-ellipsis($line-clamp) { @mixin text-ellipsis($line-clamp) {
overflow: hidden; overflow: hidden;
...@@ -57,13 +61,13 @@ ...@@ -57,13 +61,13 @@
/***文本样式***/ /***文本样式***/
.text-base { .text-base {
color: var(--color-primary-80); color: var(--text-primary-80);
} }
//0级标题 //0级标题
.text-title-0 { .text-title-0 {
@extend .text-base; @extend .text-base;
color: var(--color-primary-90); color: var(--text-primary-90);
font-size: 32px; font-size: 32px;
} }
...@@ -81,7 +85,7 @@ ...@@ -81,7 +85,7 @@
//1级标题 //1级标题
.text-title-1 { .text-title-1 {
@extend .text-base; @extend .text-base;
color: var(--color-primary-90); color: var(--text-primary-90);
font-size: 24px; font-size: 24px;
} }
...@@ -99,7 +103,7 @@ ...@@ -99,7 +103,7 @@
//2级标题 //2级标题
.text-title-2 { .text-title-2 {
@extend .text-base; @extend .text-base;
color: var(--color-primary-90); color: var(--text-primary-90);
font-size: 20px; font-size: 20px;
line-height: 26px; line-height: 26px;
} }
...@@ -119,7 +123,7 @@ ...@@ -119,7 +123,7 @@
//3级标题 //3级标题
.text-title-3 { .text-title-3 {
@extend .text-base; @extend .text-base;
color: var(--color-primary-90); color: var(--text-primary-90);
font-size: 18px; font-size: 18px;
line-height: 24px; line-height: 24px;
} }
...@@ -166,7 +170,7 @@ ...@@ -166,7 +170,7 @@
//1级提示文字 //1级提示文字
.text-tip-1 { .text-tip-1 {
@extend .text-base; @extend .text-base;
color: var(--color-primary-90); color: var(--text-primary-90);
font-size: 16px; font-size: 16px;
line-height: 24px; line-height: 24px;
} }
...@@ -179,7 +183,7 @@ ...@@ -179,7 +183,7 @@
//2级提示文字 //2级提示文字
.text-tip-2 { .text-tip-2 {
@extend .text-base; @extend .text-base;
color: var(--color-primary-90); color: var(--text-primary-90);
font-size: 14px; font-size: 14px;
line-height: 22px; line-height: 22px;
} }
...@@ -192,7 +196,7 @@ ...@@ -192,7 +196,7 @@
//3级提示文字 //3级提示文字
.text-tip-3 { .text-tip-3 {
@extend .text-base; @extend .text-base;
color: var(--color-primary-90); color: var(--text-primary-90);
font-size: 12px; font-size: 12px;
} }
......
...@@ -5,7 +5,7 @@ const span = 12 ...@@ -5,7 +5,7 @@ const span = 12
</script> </script>
<template> <template>
<el-row class="wrapper"> <el-row class="wrapper layout-grid-line">
<el-col :span="span"> <el-col :span="span">
<pre> <pre>
{{ `import '@/styles/common.scss'; {{ `import '@/styles/common.scss';
...@@ -25,7 +25,7 @@ const span = 12 ...@@ -25,7 +25,7 @@ const span = 12
<style lang="scss" scoped> <style lang="scss" scoped>
.wrapper { .wrapper {
background-color: rgba(0, 0, 0, 0.068); // background-color: rgba(0, 0, 0, 0.068);
padding: 10px; padding: 10px;
} }
</style> </style>
\ No newline at end of file
<script setup lang="ts">
import { ElRow, ElCol } from 'element-plus';
import '@/styles/common.scss'
import ColorSvg from '@/components/base/images/ColorSvg.vue';
const span = 12
</script>
<template>
<el-row class="wrapper layout-grid-line">
<el-col :span="span">
<pre>
{{ `import ColorSvg from '@/components/base/images/ColorSvg.vue';
<template>
<color-svg :size="64" :svg-url="'/icon/arrow-up.svg'" :color="'var(--color-orange-100)'" />
<color-svg :size="16" :svg-url="'/icon/arrow-up.svg'" :color="'var(--color-green-100)'" />
</template>
`}}
</pre>
<color-svg :size="64" :svg-url="'/icon/arrow-up.svg'" :color="'var(--color-orange-100)'" />
<color-svg :size="16" :svg-url="'/icon/arrow-up.svg'" :color="'var(--color-green-100)'" />
</el-col>
</el-row>
</template>
<style lang="scss" scoped></style>
\ No newline at end of file
<script setup lang="ts">
import { ElRow, ElCol } from 'element-plus';
import '@/styles/common.scss'
import PersonAvatar from '@/components/base/people/PersonAvatar.vue';
const span = 12
</script>
<template>
<el-row class="wrapper layout-grid-line">
<el-col :span="span">
<pre>
{{ `import PersonAvatar from '@/components/base/people/PersonAvatar.vue';
<template>
<person-avatar class="person-avatar" :person="{
name: '张三',
position: 'CEO,CTO',
avatarUrl: '/icon/美国.png'
}">
</person-avatar>
</template>
`}}
</pre>
<person-avatar class="person-avatar" :person="{
name: '张三',
position: 'CEO,CTO',
avatarUrl: '/icon/美国.png'
}">
</person-avatar>
</el-col>
</el-row>
</template>
<style lang="scss" scoped>
.person-avatar {
width: 200px;
}
</style>
\ No newline at end of file
...@@ -8,7 +8,7 @@ const span = 12 ...@@ -8,7 +8,7 @@ const span = 12
</script> </script>
<template> <template>
<el-row> <el-row class="layout-grid-line">
<el-col :span="span"> <el-col :span="span">
<pre> <pre>
{{ `import '@/styles/radio.scss'; {{ `import '@/styles/radio.scss';
......
<script setup lang="ts"> <script setup lang="ts">
import { ElTabs, ElTabPane, ElSpace, ElRow, ElCol } from 'element-plus'; import { ElTabs, ElTabPane, ElSpace, ElRow, ElCol } from 'element-plus';
import { ref } from 'vue';
import '@/styles/tabs.scss' import '@/styles/tabs.scss'
const span = 12 const span = 12
</script> </script>
<template> <template>
<el-row> <el-row :gutter="16" class="layout-grid-line">
<el-col :span="span"> <el-col :span="span">
<pre> <pre>
{{ `import '@/styles/tabs.scss'; {{ `import '@/styles/tabs.scss';
...@@ -22,6 +21,21 @@ const span = 12 ...@@ -22,6 +21,21 @@ const span = 12
<el-tab-pane label="tab3">tab3</el-tab-pane> <el-tab-pane label="tab3">tab3</el-tab-pane>
</el-tabs> </el-tabs>
</el-col> </el-col>
<el-col :span="span">
<pre>{{ `import '@/styles/tabs.scss';\n<template>
//确保父级position: relative;
<el-tabs tabPosition="left" class="tabs-nav-no-wrap left-float-nav-tabs">
</template>
`}}
</pre>
<div style="margin-left: 160px;position: relative; height: 200px;">
<el-tabs tabPosition="left" class="tabs-nav-no-wrap left-float-nav-tabs">
<el-tab-pane label="tab1">tab1</el-tab-pane>
<el-tab-pane label="tab2">tab2</el-tab-pane>
<el-tab-pane label="tab3">tab3</el-tab-pane>
</el-tabs>
</div>
</el-col>
</el-row> </el-row>
</template> </template>
......
<script setup lang="ts">
import { ElSpace, ElRow, ElCol } from 'element-plus';
import '@/styles/tabs.scss'
import ColorPrefixTitle from '@/components/base/texts/ColorPrefixTitle.vue';
import AiTipPane from '@/components/base/panes/AiTipPane.vue';
const span = 12
</script>
<template>
<el-row class="layout-grid-line">
<el-col :span="span">
<pre>
{{ `import ColorPrefixTitle from '@/components/base/texts/ColorPrefixTitle.vue';
<template>
<color-prefix-title>科技领域</color-prefix-title>
<color-prefix-title color="var(--color-yellow-100)">科技领域</color-prefix-title>
<color-prefix-title color="red">科技领域</color-prefix-title>
</template>
`}}
</pre>
<el-space direction="vertical">
<color-prefix-title>科技领域</color-prefix-title>
<color-prefix-title color="var(--color-yellow-100)">科技领域</color-prefix-title>
<color-prefix-title color="red">科技领域</color-prefix-title>
</el-space>
</el-col>
<el-col :span="span">
<pre>{{ `import AiTipPane from '@/components/base/panes/AiTipPane.vue';\n<template>
<ai-tip-pane>huidadadadadasda</ai-tip-pane>
</template>
`}}
</pre>
<ai-tip-pane>huidadadadadasda</ai-tip-pane>
</el-col>
</el-row>
</template>
<style lang="scss" scoped></style>
\ No newline at end of file
.layout-grid-line {
.el-col {
border: 1px double var(--bg-black-5);
}
}
\ No newline at end of file
<template> <template>
<el-scrollbar> <el-scrollbar>
<div class="common-page"> <div class="common-page box">
<el-space direction="vertical" :size="20" alignment="flex-start" fill> <el-space direction="vertical" :size="20" alignment="flex-start" fill>
<div class="text-title-0-show">开发样式</div> <div class="text-title-0-show">开发样式</div>
<div class="text-title-1-show">样式变量</div> <div class="text-title-1-show">样式变量</div>
...@@ -8,17 +8,28 @@ ...@@ -8,17 +8,28 @@
<div class="text-title-1-show">文字样式</div> <div class="text-title-1-show">文字样式</div>
<TextStyle /> <TextStyle />
<div class="text-title-1-show">通用样式/组件</div> <div class="text-title-1-show">通用样式/组件</div>
<el-tabs tabPosition="left"> <div style="position: relative; min-height: 300px;">
<el-tab-pane label="通用" lazy> <el-tabs tabPosition="left" class="tabs-nav-no-wrap left-float-nav-tabs">
<common-page /> <el-tab-pane label="通用" lazy>
</el-tab-pane> <common-page />
<el-tab-pane label="单选框" lazy> </el-tab-pane>
<radio-page /> <el-tab-pane label="文本" lazy>
</el-tab-pane> <text-page />
<el-tab-pane label="选项卡" lazy> </el-tab-pane>
<tabs-page /> <el-tab-pane label="图片" lazy>
</el-tab-pane> <images-page />
</el-tabs> </el-tab-pane>
<el-tab-pane label="单选框" lazy>
<radio-page />
</el-tab-pane>
<el-tab-pane label="选项卡" lazy>
<tabs-page />
</el-tab-pane>
<el-tab-pane label="人物" lazy>
<people-page />
</el-tab-pane>
</el-tabs>
</div>
</el-space> </el-space>
</div> </div>
</el-scrollbar> </el-scrollbar>
...@@ -26,12 +37,20 @@ ...@@ -26,12 +37,20 @@
<script setup> <script setup>
import "@/styles/container.scss" import "@/styles/container.scss"
import "./devStyle.scss"
import TextStyle from './textStyle.vue'; import TextStyle from './textStyle.vue';
import ConstStyle from './constStyle.vue'; import ConstStyle from './constStyle.vue';
import { ElTabs, ElTabPane, ElSpace } from "element-plus"; import { ElTabs, ElTabPane, ElSpace } from "element-plus";
import RadioPage from './RadioPage/index.vue'; import RadioPage from './RadioPage/index.vue';
import TabsPage from './TabsPage/index.vue'; import TabsPage from './TabsPage/index.vue';
import CommonPage from './CommonPage/index.vue'; import CommonPage from './CommonPage/index.vue';
import TextPage from './TextPage/index.vue';
import ImagesPage from './Images/index.vue';
import PeoplePage from './People/index.vue';
</script> </script>
<style lang="scss" scoped></style> <style lang="scss" scoped>
\ No newline at end of file .box {
padding-bottom: 20px;
}
</style>
\ No newline at end of file
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
/***通用页面***/ /***通用页面***/
.common-page { .common-page {
margin: 16px auto; padding: 16px 160px;
width: 1600px; // width: 1600px;
align-items: center; align-items: center;
} }
\ No newline at end of file
...@@ -25,20 +25,13 @@ ...@@ -25,20 +25,13 @@
/*定义字体*/ /*定义字体*/
.el-tabs__item:not(.disinheritance .el-tabs__item) { .el-tabs__item:not(.disinheritance .el-tabs__item) {
font-size: 20px; @extend .text-title-2;
font-family: "Source Han Sans CN-Regular"; color: var(--text-primary-80-color);
font-weight: Regular;
line-height: 26px;
height: 50px;
} }
/*激活时按钮样式*/ /*激活时按钮样式*/
.el-tabs__item.is-active:not(.disinheritance .el-tabs__item) { .el-tabs__item.is-active:not(.disinheritance .el-tabs__item) {
@extend .text-title-1-bold;
font-size: 24px;
font-family: "Source Han Sans CN-Bold";
font-weight: Bold;
color: var(--color-primary-100); color: var(--color-primary-100);
border-width: 1px; border-width: 1px;
border-style: solid; border-style: solid;
...@@ -48,27 +41,54 @@ ...@@ -48,27 +41,54 @@
} }
} }
/***允许tab-pane内部元素溢出***/
.tab-pane-overflow-visible {
.el-tab-pane {
overflow: visible !important;
}
// 同时确保父容器也允许溢出
.el-tabs__content {
overflow: visible !important;
}
}
/***tabs-bar左边悬浮***/ /***tabs-bar左边悬浮***/
.left-float-nav-tabs { .left-float-nav-tabs {
.el-tabs__header.is-left {
position: absolute;
left: -140px;
top: 0px;
// .el-tabs__header { .el-tabs__nav {
gap: 16px;
position: relative; }
overflow: visible;
transform: translateZ(0);
/* 双重保障 */
/* 创建新的渲染层 */ .el-tabs__active-bar {
/* 创建新的层叠上下文 */ background-color: transparent;
.el-tabs__header { right: 12px;
top: 11px;
height: 8px !important;
border-top: 6px solid transparent;
/* 顶部边框透明 */
border-bottom: 6px solid transparent;
/* 底部边框透明 */
border-left: 8px solid var(--bg-white-100);
/* 左侧边框有颜色 */
}
}
// position: absolute; .el-tabs__item.is-left {
left: 0; @extend .text-tip-1;
top: 0; color: var(--text-primary-65-color);
z-index: 999; height: 32px;
background-color: red; padding: 4px 26px 4px 28px;
// margin-left: -20px; border-radius: 16px 16px 16px 16px;
justify-content: center;
} }
// } .el-tabs__item.is-left.is-active {
color: var(--bg-white-100);
background-color: var(--color-primary-100);
}
} }
\ No newline at end of file
<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16.000000" height="16.000000" fill="none">
<rect id="机械设备 1" width="16.000000" height="16.000000" x="0.000000" y="0.000000" />
<path id="矢量 1620" d="M11.6932 12.3121L9.37157 12.3121C9.37514 12.1495 9.33467 11.9889 9.25445 11.8474L5.77115 5.86676C5.44431 6.35635 4.98227 6.74044 4.44121 6.97234C3.90015 7.20425 3.30337 7.27397 2.72342 7.17305L5.71648 12.3118L3.62339 12.3118C3.4668 12.312 3.31301 12.3533 3.17743 12.4317C3.04185 12.51 2.92925 12.6226 2.85091 12.7582C2.77257 12.8938 2.73124 13.0475 2.73107 13.2041L2.73107 14.1023C2.73124 14.2589 2.77257 14.4127 2.85091 14.5483C2.92925 14.6839 3.04185 14.7965 3.17743 14.8748C3.31301 14.9531 3.4668 14.9945 3.62339 14.9946L11.6932 14.9946C11.8498 14.9944 12.0035 14.9531 12.1391 14.8748C12.2747 14.7964 12.3873 14.6838 12.4656 14.5483C12.544 14.4127 12.5853 14.2589 12.5855 14.1023L12.5855 13.2044C12.5855 13.0478 12.5443 12.8939 12.466 12.7582C12.3877 12.6225 12.2751 12.5099 12.1394 12.4316C12.0037 12.3532 11.8498 12.312 11.6932 12.3121L11.6932 12.3121ZM3.22705 1.96949C2.79606 1.96946 2.37474 2.09724 2.01638 2.33667C1.65801 2.5761 1.37869 2.91642 1.21375 3.3146C1.0488 3.71277 1.00564 4.15092 1.08972 4.57363C1.17379 4.99634 1.38133 5.38462 1.68608 5.68938C1.99084 5.99413 2.37912 6.20167 2.80183 6.28574C3.22454 6.36982 3.66269 6.32665 4.06086 6.16171C4.45904 5.99677 4.79936 5.71745 5.03879 5.35908C5.27822 5.00072 5.406 4.5794 5.40597 4.14841C5.4058 3.76598 5.30503 3.39032 5.11376 3.05915C4.9225 2.72798 4.64748 2.45296 4.31631 2.2617C3.98514 2.07043 3.60948 1.96966 3.22705 1.96949ZM3.22705 4.92756C3.07297 4.92756 2.92236 4.88188 2.79425 4.79628C2.66614 4.71068 2.56629 4.58901 2.50733 4.44666C2.44837 4.30432 2.43294 4.14768 2.463 3.99657C2.49306 3.84546 2.56725 3.70665 2.6762 3.5977C2.78515 3.48875 2.92395 3.41456 3.07507 3.3845C3.22618 3.35444 3.38282 3.36987 3.52516 3.42883C3.66751 3.48779 3.78918 3.58764 3.87478 3.71575C3.96038 3.84386 4.00606 3.99447 4.00606 4.14855C4.00587 4.28523 3.96977 4.41946 3.90136 4.5378C3.83296 4.65613 3.73466 4.75441 3.61631 4.8228C3.49797 4.89118 3.36373 4.92726 3.22705 4.92743L3.22705 4.92756ZM14.3101 4.88274L11.8948 6.26679L10.8052 4.89435L10.8052 3.39673L11.8948 2.02416L14.3101 3.40848C14.3917 3.45427 14.4856 3.47325 14.5785 3.46275C14.6715 3.45226 14.7588 3.4128 14.8281 3.34998C14.8974 3.28715 14.9452 3.20413 14.9647 3.11266C14.9843 3.02118 14.9745 2.92588 14.937 2.84022C14.8994 2.75457 14.8358 2.6829 14.7553 2.63534L12.0081 1.05968C11.9467 1.02425 11.8778 1.00397 11.807 1.00053C11.7362 0.997082 11.6656 1.01057 11.6011 1.03988C11.5366 1.06918 11.4799 1.11345 11.436 1.16902L10.362 2.52013L9.18871 2.52013C9.00972 2.52002 8.83488 2.57403 8.68714 2.67508C8.53941 2.77613 8.42568 2.9195 8.3609 3.08635L6.109 3.08635C6.23779 3.43142 6.30261 3.79707 6.30028 4.16539C6.29794 4.5337 6.22849 4.8985 6.09533 5.2419L8.36145 5.2419C8.42665 5.40889 8.54076 5.5523 8.68883 5.65336C8.8369 5.75441 9.01204 5.8084 9.19131 5.80826L10.3914 5.80826L11.436 7.1222C11.4778 7.17467 11.531 7.21702 11.5915 7.2461C11.652 7.27518 11.7183 7.29024 11.7854 7.29017C11.8634 7.28993 11.94 7.2698 12.0081 7.23168L14.7551 5.65588C14.8239 5.61728 14.8812 5.56114 14.9212 5.49319C14.9612 5.42524 14.9825 5.34789 14.9829 5.26904C14.9832 5.19018 14.9627 5.11263 14.9234 5.0443C14.884 4.97596 14.8273 4.91927 14.7589 4.88001C14.6905 4.84075 14.6129 4.82032 14.5341 4.82079C14.4552 4.82127 14.3779 4.84265 14.31 4.88274L14.3101 4.88274Z" fill="rgb(5,95,194)" fill-rule="nonzero" />
</svg>
<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16.000000" height="16.000000" fill="none">
<rect id="1-资金管理 1" width="16.000000" height="16.000000" x="0.000000" y="0.000000" />
<path id="矢量 1620" d="M11.7086 10.5216C11.9447 10.5216 12.1365 10.7062 12.1365 10.9337C12.1365 11.1612 11.9447 11.3457 11.7086 11.3457L10.6554 11.3457L10.6554 12.0432C10.6551 12.2707 10.4632 12.4552 10.2275 12.4552C9.99168 12.4552 9.7995 12.2707 9.7995 12.0432L9.7995 11.3457L8.74632 11.3457C8.50991 11.3457 8.31836 11.1612 8.31836 10.9337C8.31836 10.7062 8.50991 10.5216 8.746 10.5216L9.7995 10.5216L9.7995 9.76022L8.74632 9.76022C8.50991 9.76022 8.31836 9.57568 8.31836 9.34818C8.31836 9.12067 8.50991 8.93613 8.746 8.93613L9.28818 8.93613L8.48477 8.04681C8.43563 7.99294 8.40209 7.9267 8.38774 7.85521C8.3734 7.78372 8.37879 7.70968 8.40334 7.64102C8.42789 7.57236 8.47067 7.51168 8.52709 7.46549C8.58441 7.41784 8.65292 7.38556 8.72617 7.3717C8.79941 7.35785 8.87498 7.36287 8.94575 7.38629C9.01652 7.40971 9.08016 7.45077 9.13068 7.50558L10.2275 8.7204L11.3239 7.5059C11.3744 7.45108 11.4381 7.41003 11.5088 7.38661C11.5796 7.36319 11.6552 7.35817 11.7284 7.37202C11.8017 7.38588 11.8702 7.41816 11.9275 7.46581C11.984 7.51193 12.0269 7.57259 12.0515 7.64127C12.0761 7.70995 12.0815 7.78404 12.0671 7.85556C12.0527 7.92708 12.0191 7.99331 11.9698 8.04713L11.1667 8.93645L11.7086 8.93645C11.9447 8.93645 12.1365 9.12099 12.1365 9.34849C12.1365 9.57599 11.9447 9.76054 11.7086 9.76054L10.6554 9.76054L10.6554 10.5216L11.7086 10.5216L11.7086 10.5216ZM10.2275 5.45522C7.76695 5.45522 5.77291 7.44958 5.77291 9.90977C5.77291 12.3703 7.76695 14.3643 10.2275 14.3643C12.6876 14.3643 14.682 12.3703 14.682 9.90977C14.682 7.44958 12.6876 5.45522 10.2275 5.45522ZM6.01886 12.7734L2.2729 12.7734L2.2729 10.8643L4.50018 10.8643C4.60094 10.8643 4.69911 10.8323 4.78061 10.7731C4.86212 10.7138 4.92278 10.6303 4.95391 10.5345C4.98504 10.4387 4.98504 10.3354 4.95391 10.2396C4.92278 10.1438 4.86211 10.0602 4.78061 10.001C4.69911 9.94174 4.60094 9.90981 4.50018 9.90977L2.2729 9.90977L2.2729 8.15977L5.13654 8.15977C5.2373 8.15972 5.33547 8.12779 5.41698 8.06854C5.49848 8.0093 5.55914 7.92578 5.59027 7.82994C5.6214 7.73411 5.6214 7.63088 5.59027 7.53504C5.55914 7.43921 5.49848 7.35569 5.41698 7.29644C5.33547 7.23719 5.2373 7.20526 5.13654 7.20522L2.2729 7.20522L2.2729 5.7734L7.26709 5.7734C7.95348 5.28046 8.7525 4.96748 9.59109 4.86308L9.59109 2.27308C9.59109 2.16138 9.56168 2.05164 9.50583 1.9549C9.44998 1.85816 9.36965 1.77783 9.27291 1.72198C9.17617 1.66612 9.06643 1.63672 8.95472 1.63672L1.95472 1.63672C1.84302 1.63672 1.73328 1.66612 1.63654 1.72198C1.5398 1.77783 1.45947 1.85816 1.40362 1.9549C1.34776 2.05164 1.31836 2.16138 1.31836 2.27308L1.31836 13.0913C1.31836 13.203 1.34776 13.3127 1.40362 13.4094C1.45947 13.5062 1.5398 13.5865 1.63654 13.6424C1.73328 13.6982 1.84302 13.7276 1.95472 13.7276L6.86777 13.7276C6.54602 13.4462 6.26082 13.1255 6.01886 12.7731L6.01886 12.7734Z" fill="rgb(5,95,194)" fill-rule="nonzero" />
</svg>
...@@ -101,7 +101,7 @@ watch(() => props.enterpriseInfo, (newVal, oldVal) => { ...@@ -101,7 +101,7 @@ watch(() => props.enterpriseInfo, (newVal, oldVal) => {
.item-value-img { .item-value-img {
width: 8px; width: 8px;
height: 6px; height: 6px;
background-image: url(../images/Regular_polygon_11097_225086.png); background-image: url(../assets/images/Regular_polygon_11097_225086.png);
background-size: 100% 100%; background-size: 100% 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
position: relative; position: relative;
......
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, onUnmounted, watch } from 'vue'; import { ref, onMounted, onUnmounted, watch } from 'vue';
import { ElRadioGroup, ElRadioButton } from 'element-plus'; import { ElRadioGroup, ElRadioButton, ElSpace } from 'element-plus';
import * as echarts from 'echarts'; import * as echarts from 'echarts';
import { getSanctionList } from '@/api/companyPages'; import { getSanctionList } from '@/api/companyPages';
import AnalysisBox from '@/components/base/boxBackground/analysisBox.vue'; import AnalysisBox from '@/components/base/boxBackground/analysisBox.vue';
...@@ -263,7 +263,9 @@ function handleStudyTypesChange() { ...@@ -263,7 +263,9 @@ function handleStudyTypesChange() {
<analysis-box title="被制裁时间轴"> <analysis-box title="被制裁时间轴">
<template v-if="lineTypes.length > 1" v-slot:header-btn> <template v-if="lineTypes.length > 1" v-slot:header-btn>
<el-radio-group class="radio-group-as-gap-btn" v-model="lineType" @change="handleStudyTypesChange"> <el-radio-group class="radio-group-as-gap-btn" v-model="lineType" @change="handleStudyTypesChange">
<el-radio-button v-for="item in lineTypes" :key="item" :label="item">{{ item }}</el-radio-button> <el-space>
<el-radio-button v-for="item in lineTypes" :key="item" :label="item">{{ item }}</el-radio-button>
</el-space>
</el-radio-group> </el-radio-group>
</template> </template>
<div class="flex-display content-box"> <div class="flex-display content-box">
......
<script setup lang="ts">
import { ref, onMounted, onUnmounted, watch } from 'vue';
import * as echarts from 'echarts';
export interface GraphNode {
id: string
name: string
type: string
x: number
y: number
}
export interface GraphLink {
source: string
target: string
type: string
}
// 定义组件属性
const props = defineProps({
nodes: {
type: Array<GraphNode>,
default: () => []
}
, links: {
type: Array<GraphLink>,
default: () => []
}
});
const chartDom = ref()
let myChart = null
onMounted(async () => {
})
watch(() => props.nodes, () => {
nodeTopBottomLayout(props.nodes)
updateCharts()
})
watch(() => props.links, updateCharts)
onUnmounted(() => myChart?.dispose())
function nodeTopBottomLayout(nodes: Array<any>) {
if (nodes.length < 1) return
// 中心节点放在中间
const centerNode = nodes[0]
centerNode.x = 0
centerNode.y = 0
// 其余节点分成上下两列
const otherNodes = nodes.slice(1)
const tops = []
const bottoms = []
otherNodes.forEach((item) => {
if (item.type === 'to') {
tops.push(item)
} else {
bottoms.push(item)
}
})
// 计算每列的节点数
const topCount = tops.length
const bottomCount = bottoms.length
// 列间距
const columnSpacing = 60
// 上下列距离中心的距离
const verticalDistance = 100
let ci = (topCount - 1) / 2
// 处理上列节点
for (let i = 0; i < topCount; i++) {
const node = tops[i]
// 计算x坐标,居中排列
const offsetX = (i - ci) * columnSpacing
node.x = offsetX
node.y = -verticalDistance
}
ci = (bottomCount - 1) / 2
// 处理下列节点
for (let i = 0; i < bottomCount; i++) {
const node = bottoms[i]
// 计算x坐标,居中排列
const offsetX = (i - ci) * columnSpacing
node.x = offsetX
node.y = verticalDistance
}
}
// 辅助函数:更新图表数据
function updateCharts() {
// 销毁现有图表实例
if (myChart) {
myChart.dispose()
}
myChart = echarts.init(chartDom.value)
const ys = props.nodes.map((item) => item.y)
const minY = Math.min(...ys)
const maxY = Math.max(...ys)
myChart.setOption({
grid: {
top: 0,
bottom: 0,
left: 0,
right: 0,
},
// 关闭不必要的交互以提高性能
tooltip: {
show: false
},
// 优化渲染性能
// progressive: 500,
// progressiveThreshold: 300,
animation: false,
animationDuration: 1000,
animationEasing: 'cubicOut',
series: [{
type: 'graph',
// zoom: Math.max(1, props.nodes.length / 10.0), // 放大显示
itemStyle: {
color: '#73C0DE'
},
height: '80%',
layout: 'none',
data: props.nodes,
links: props.links,
center: [0, (minY + maxY) / 2 + 10],
nodeScaleRatio: 0,
// categories: categories,
roam: true,
label: {
show: true,
position: 'bottom',
offset: [0, -10],
formatter: '{b}',
fontSize: 14,
textBorderColor: 'rgb(255 255 255)',
// fontWeight: 'bold',
color: 'rgb(5, 95, 194)',
padding: [4, 6],
borderRadius: 4,
// 限制宽度并自动换行
width: 120, // 限制标签宽度
overflow: 'break', // 超出宽度自动换行
lineHeight: 16 // 设置行高,确保多行显示正常
},
lineStyle: {
// color: 'source',
curveness: 0,
width: 1,
color: '#AED6FF'
},
edgeSymbol: ['arrow', 'none'],
}]
})
}
</script>
<template>
<div class="flex-display content-box">
<div ref="chartDom" class="chart-container"></div>
</div>
</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/common.scss';
import { getSupplyAreaList, getSupplyCountryList, getSupplyList } from "@/api/companyPages/index.js";
import { onMounted, ref } from 'vue';
import { ElCheckbox, ElCheckboxGroup, ElRow, ElCol, ElMessage, ElRadioGroup, ElRadioButton } from 'element-plus';
import ColorPrefixTitle from '@/components/base/texts/ColorPrefixTitle.vue';
import GraphChart from './GraphChart.vue'
import { forEach } from 'lodash';
import AiTipPane from '@/components/base/panes/AiTipPane.vue';
import ColorSvg from '@/components/base/images/ColorSvg.vue'
import MachineImg from '../../assets/images/机械设备.svg'
import FundImg from '../../assets/images/资金管理.svg'
const CompanyImg = "/icon/company/普通企业节点.svg"
const CompanyImg2 = "/icon/company/普通企业节点2.svg"
import { getSingleSanctionEntityEquity } from '@/api/exportControlV2.0';
// 定义组件属性
const props = defineProps({
enterpriseInfo: {
type: Object,
default: {}
}
});
const supplyAreaList = ref([]);
const supplyCountryList = ref([]);
const supplyTypeList = [{
name: '上游', id: 'supply'
}, {
name: '下游', id: 'customer'
}];
const dataTypeList = ref([{
name: '供应链', id: 'supply',
icon: MachineImg
}, {
name: '股权', id: 'equity',
icon: FundImg
}])
const selectedSupplyAreas = ref([]);
const selectedSupplyCountries = ref([]);
const selectedSupplyTypes = ref([]);
const selectedDataType = ref('supply')
const nodes = ref([])
const links = ref([])
onMounted(async () => {
await initData()
await updateData()
})
async function initData() {
const { data } = await getSupplyAreaList(props.enterpriseInfo.id);
supplyAreaList.value = data ?? [];
const { data: countryData } = await getSupplyCountryList(props.enterpriseInfo.id);
supplyCountryList.value = countryData ?? [];
}
async function updateData() {
if (selectedDataType.value === 'supply') {
await updateDataSupply()
} else if (selectedDataType.value === 'equity') {
await updateDataEquity()
}
}
async function updateDataSupply() {
const params = {
arealist: selectedSupplyAreas.value ? selectedSupplyAreas.value.join(",") : null,
countrylist: selectedSupplyCountries.value ? selectedSupplyCountries.value.join(",") : null,
type: selectedSupplyTypes.value.length === 2 ? 'all' : selectedSupplyTypes.value ? selectedSupplyTypes.value : null,
id: props.enterpriseInfo.id
}
const { data } = await getSupplyList(params)
if (!data) {
ElMessage.error('获取供应链数据失败')
return
}
// 提取所有公司名称
const companyMap: Map<string, any> = new Map();
data.forEach(item => {
companyMap.set(item.orgId, { name: item.orgName, type: item.type })
companyMap.set(item.otherOrgId, { name: item.otherOrgName, type: item.type })
})
// 创建nodes数组
nodes.value = Array.from(companyMap).map(([orgId, item]) => (createNode(orgId, item.name, item.type, false)));
const linksData = []
forEach(data, item => {
const link = createLink(item.orgId, item.otherOrgId, '供应商', false)
if (item.type === 'from') {
link.source = item.otherOrgId
link.target = item.orgId
link.label.formatter = '客户'
}
linksData.push(link)
})
// 创建links数组
links.value = linksData
}
function createNode(orgId: string, orgName: string, type: string, isSanctioned: boolean) {
return {
id: orgId,
name: orgName,
type: type,
symbolSize: 50,
symbol: `image://${isSanctioned ? CompanyImg2 : CompanyImg}`,
isSanctioned
}
}
function createLink(source: string, target: string, formatter: string, isSanctioned: boolean) {
return {
source: source,
target: target,
label: {
show: true,
formatter: formatter,
color: isSanctioned ? 'rgba(255, 102, 102, 1)' : 'rgba(137, 193, 255, 1)',
backgroundColor: isSanctioned ? 'rgba(255, 102, 102, 0.2)' : 'rgba(137, 193, 255, 0.2)',
padding: [4, 4],
borderRadius: 10
},
}
}
async function updateDataEquity() {
const { data } = await getSingleSanctionEntityEquity({ orgId: props.enterpriseInfo.id, rule: true })
if (!data) {
ElMessage.error('获取股权数据失败')
return
}
const cnode = createNode(data.orgId, data.orgName, "to", false)
const linksData = []
const nodesData = [cnode]
const { parentOrgList, childrenOrgList } = data
childrenOrgList.forEach((item, i) => {
if (!item.id) item.id = i
nodesData.push(createNode(item.id, item.name, "to", item.isSanctioned))
linksData.push(createLink(cnode.id, item.id, item.description, item.isSanctioned))
})
parentOrgList.forEach((item, i) => {
if (!item.id) item.id = i
nodesData.push(createNode(item.id, item.name, "from", item.isSanctioned))
linksData.push(createLink(item.id, cnode.id, item.description, item.isSanctioned))
})
nodes.value = nodesData
links.value = linksData
console.log(nodesData, linksData)
}
async function handleOptionsChnage() {
await updateData()
}
async function handleDataTypeChange() {
await updateData()
}
</script>
<template>
<div class="flex-display box-div">
<div class="background-as-card options-pane">
<color-prefix-title>科技领域</color-prefix-title>
<el-checkbox-group class="checkbox-group" v-model="selectedSupplyAreas" @change="handleOptionsChnage">
<el-row>
<el-col v-for="item in supplyAreaList" :span="12">
<el-checkbox :label="item.name + '(' + item.num + ')'" :value="item.id" />
</el-col>
</el-row>
</el-checkbox-group>
<color-prefix-title>国家/地区</color-prefix-title>
<el-checkbox-group class="checkbox-group" v-model="selectedSupplyCountries" @change="handleOptionsChnage">
<el-row>
<el-col v-for="item in supplyCountryList" :span="12">
<el-checkbox :label="item.name + '(' + item.num + ')'" :value="item.id" />
</el-col>
</el-row>
</el-checkbox-group>
<color-prefix-title>上下游</color-prefix-title>
<el-checkbox-group class="checkbox-group" v-model="selectedSupplyTypes" @change="handleOptionsChnage">
<el-row>
<el-col v-for="item in supplyTypeList" :span="12">
<el-checkbox :label="item.name" :value="item.id" />
</el-col>
</el-row>
</el-checkbox-group>
</div>
<div class="background-as-card flex-fill">
<el-radio-group v-model="selectedDataType" class="data-type-group" @change="handleDataTypeChange">
<el-radio-button v-for="item in dataTypeList" :label="item.id" :value="item.id">
<color-svg :size="16" :svg-url="item.icon"
:color="item.id === selectedDataType ? 'var(--bg-white-100)' : 'var(--color-primary-100)'">
</color-svg>
<span class="text-title-3">
{{ item.name }}
</span>
</el-radio-button>
</el-radio-group>
<graph-chart :nodes="nodes" :links="links" />
<ai-tip-pane v-if="enterpriseInfo.id === '914403001922038216'">
华为构建了覆盖全球的复杂供应链网络,以自身为核心,辐射芯片、显示、摄像头等关键领域。其供应链深度扎根中国,同时整合美国高通、韩国三星、日本索尼等国际顶尖供应商,形成多元化供应格局。面对外部技术封锁,华为通过扶持海思等子公司强化垂直整合,并积极拓展本土替代资源,在保持技术领先的同时增强供应链韧性,展现出卓越的全球资源调配与风险管控能力。
</ai-tip-pane>
</div>
</div>
</template>
<style lang="css" scoped>
.options-pane {
width: 360px;
padding-top: 16px;
margin-right: 16px;
}
.chart-box {
padding: 10px 0px;
background-color: var(--bg-white-100);
}
.checkbox-group {
padding: 0px 25px;
margin-bottom: 20px;
}
.data-type-group {
padding: 10px 16px;
top: 16px;
}
</style>
\ No newline at end of file
...@@ -4,9 +4,9 @@ ...@@ -4,9 +4,9 @@
</div> </div>
<el-scrollbar> <el-scrollbar>
<div class="common-page"> <div class="common-page">
<el-space wrap :size="16" fill> <el-space wrap :size="16" fill class="full-width">
<title-pane :enterprise-info="enterpriseInfo"></title-pane> <title-pane :enterprise-info="enterpriseInfo"></title-pane>
<el-tabs stretch class="tabs-header-as-card tabs-nav-no-wrap tabs-bar-as-btn"> <el-tabs stretch class="tabs-header-as-card tabs-nav-no-wrap tabs-bar-as-btn tab-pane-overflow-visible">
<el-tab-pane label="企业详情"> <el-tab-pane label="企业详情">
<div class="flex-display"> <div class="flex-display">
<news-pane :enterprise-info="enterpriseInfo" /> <news-pane :enterprise-info="enterpriseInfo" />
...@@ -17,8 +17,7 @@ ...@@ -17,8 +17,7 @@
<operating-pages :enterprise-info="enterpriseInfo" /> <operating-pages :enterprise-info="enterpriseInfo" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane lazy label="供应链 / 股权"> <el-tab-pane lazy label="供应链 / 股权">
<div class="flex-display"> <supply-chain :enterprise-info="enterpriseInfo" />
</div>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</el-space> </el-space>
...@@ -33,6 +32,7 @@ import TitlePane from './component/TitlePane.vue'; ...@@ -33,6 +32,7 @@ import TitlePane from './component/TitlePane.vue';
import NewsPane from './component/DetailsPages/NewsPane.vue'; import NewsPane from './component/DetailsPages/NewsPane.vue';
import BaseInfo from './component/DetailsPages/BaseInfo.vue'; import BaseInfo from './component/DetailsPages/BaseInfo.vue';
import OperatingPages from './component/OperatingPages/index.vue'; import OperatingPages from './component/OperatingPages/index.vue';
import SupplyChain from './component/SupplyChain/index.vue';
import '@/styles/tabs.scss' import '@/styles/tabs.scss'
import '@/styles/container.scss' import '@/styles/container.scss'
import { ElScrollbar, ElSpace, ElTabs, ElTabPane } from 'element-plus'; import { ElScrollbar, ElSpace, ElTabs, ElTabPane } from 'element-plus';
......
...@@ -64,7 +64,8 @@ ...@@ -64,7 +64,8 @@
</div> </div>
</div> --> </div> -->
<div class="home-main-header-item-box"> <div class="home-main-header-item-box">
<div class="item" v-for="(item, index) in govInsList" :key="index" @click="handleToInstitution(item)"> <div class="item" v-for="(item, index) in govInsList" :key="index"
@click="handleToInstitution(item)">
<div class="item-left"> <div class="item-left">
<img :src="item.img ? item.img : DefaultIcon2" alt="" /> <img :src="item.img ? item.img : DefaultIcon2" alt="" />
</div> </div>
...@@ -122,7 +123,8 @@ ...@@ -122,7 +123,8 @@
}" v-for="(tag, index) in item.industryList" :key="index"> }" v-for="(tag, index) in item.industryList" :key="index">
{{ tag.industryName }} {{ tag.industryName }}
</div> --> </div> -->
<AreaTag v-for="(tag, index) in item.industryList" :key="index" :tagName="tag.industryName"> <AreaTag v-for="(tag, index) in item.industryList" :key="index"
:tagName="tag.industryName">
</AreaTag> </AreaTag>
</div> </div>
<div class="box1-main-right-center"> <div class="box1-main-right-center">
...@@ -185,16 +187,17 @@ ...@@ -185,16 +187,17 @@
<div class="text">{{ "查看更多" }}</div> <div class="text">{{ "查看更多" }}</div>
</div> </div>
</div> --> </div> -->
<RiskSignal :list="warningList" @item-click="handleClickToDetail" @more-click="handleToMoreRiskSignal" <RiskSignal :list="warningList" @item-click="handleClickToDetail"
riskLevel="signalLevel" postDate="signalTime" name="signalTitle"> @more-click="handleToMoreRiskSignal" riskLevel="signalLevel" postDate="signalTime"
name="signalTitle">
</RiskSignal> </RiskSignal>
</div> </div>
<DivideHeader id="position2" class="divide2" :titleText="'资讯要闻'"></DivideHeader> <DivideHeader id="position2" class="divide2" :titleText="'资讯要闻'"></DivideHeader>
<div class="center-center"> <div class="center-center">
<NewsList :newsList="newsList" @item-click="handleToNewsAnalysis" @more-click="handleToMoreNews" /> <NewsList :newsList="newsList" @item-click="handleToNewsAnalysis" @more-click="handleToMoreNews" />
<!-- <NewsList :newsList="newsList" /> --> <!-- <NewsList :newsList="newsList" /> -->
<MessageBubble :messageList="messageList" @person-click="handleClickPerson" @info-click="handleGetMessage" <MessageBubble :messageList="messageList" @person-click="handleClickPerson"
imageUrl="img" @more-click="handleToSocialDetail" /> @info-click="handleGetMessage" imageUrl="img" @more-click="handleToSocialDetail" />
</div> </div>
<DivideHeader id="position3" class="divide3" :titleText="'数据总览'"></DivideHeader> <DivideHeader id="position3" class="divide3" :titleText="'数据总览'"></DivideHeader>
<div class="center-footer"> <div class="center-footer">
...@@ -209,7 +212,8 @@ ...@@ -209,7 +212,8 @@
<div class="box5-selectbox"> <div class="box5-selectbox">
<el-select @change="handleBox5YearChange" v-model="box5SelectedYear" placeholder="选择时间" <el-select @change="handleBox5YearChange" v-model="box5SelectedYear" placeholder="选择时间"
style="width: 120px"> style="width: 120px">
<el-option v-for="item in box5YearList" :key="item.value" :label="item.label" :value="item.value" /> <el-option v-for="item in box5YearList" :key="item.value" :label="item.label"
:value="item.value" />
</el-select> </el-select>
</div> </div>
</div> </div>
...@@ -227,7 +231,8 @@ ...@@ -227,7 +231,8 @@
<div class="box6-selectbox"> <div class="box6-selectbox">
<el-select @change="handleBox6YearChange" v-model="box6SelectedYear" placeholder="选择时间" <el-select @change="handleBox6YearChange" v-model="box6SelectedYear" placeholder="选择时间"
style="width: 120px"> style="width: 120px">
<el-option v-for="item in box6YearList" :key="item.value" :label="item.label" :value="item.value" /> <el-option v-for="item in box6YearList" :key="item.value" :label="item.label"
:value="item.value" />
</el-select> </el-select>
</div> </div>
</div> </div>
...@@ -243,7 +248,8 @@ ...@@ -243,7 +248,8 @@
<div class="header-title">{{ "关键行政令" }}</div> <div class="header-title">{{ "关键行政令" }}</div>
</div> </div>
<div class="box7-main"> <div class="box7-main">
<div class="box7-item" v-for="(item, index) in keyDecreeList" :key="index" @click="handleKeyDecree(item)"> <div class="box7-item" v-for="(item, index) in keyDecreeList" :key="index"
@click="handleKeyDecree(item)">
<div class="icon"> <div class="icon">
<img src="./assets/images/warning.png" alt="" /> <img src="./assets/images/warning.png" alt="" />
</div> </div>
...@@ -299,9 +305,9 @@ ...@@ -299,9 +305,9 @@
</div> </div>
<div class="select-main"> <div class="select-main">
<div class="checkbox-group"> <div class="checkbox-group">
<el-checkbox v-for="type in decreeTypeList" :key="type.id" v-model="checkedDecreeType" <el-checkbox v-for="type in decreeTypeList" :key="type.id"
:label="type.typeId" style="width: 180px" class="filter-checkbox" v-model="checkedDecreeType" :label="type.typeId" style="width: 180px"
@change="handleChangeCheckedDecreeType"> class="filter-checkbox" @change="handleChangeCheckedDecreeType">
{{ type.typeName }} {{ type.typeName }}
</el-checkbox> </el-checkbox>
</div> </div>
...@@ -314,8 +320,9 @@ ...@@ -314,8 +320,9 @@
</div> </div>
<div class="select-main"> <div class="select-main">
<div class="checkbox-group"> <div class="checkbox-group">
<el-checkbox v-for="cate in govInsList" :key="cate.id" v-model="checkedGovIns" :label="cate.id" <el-checkbox v-for="cate in govInsList" :key="cate.id" v-model="checkedGovIns"
style="width: 180px" class="filter-checkbox" @change="handleChangeCheckedGovIns"> :label="cate.id" style="width: 180px" class="filter-checkbox"
@change="handleChangeCheckedGovIns">
{{ cate.name }} {{ cate.name }}
</el-checkbox> </el-checkbox>
</div> </div>
...@@ -328,8 +335,8 @@ ...@@ -328,8 +335,8 @@
</div> </div>
<div class="select-main"> <div class="select-main">
<div class="checkbox-group"> <div class="checkbox-group">
<el-checkbox v-for="time in pubTime" :key="time.id" v-model="activePubTime" :label="time.id" <el-checkbox v-for="time in pubTime" :key="time.id" v-model="activePubTime"
style="width: 100px" class="filter-checkbox" :label="time.id" style="width: 100px" class="filter-checkbox"
@change="checked => handlePubTimeChange(time.id, checked)"> @change="checked => handlePubTimeChange(time.id, checked)">
{{ time.name }} {{ time.name }}
</el-checkbox> </el-checkbox>
...@@ -343,8 +350,9 @@ ...@@ -343,8 +350,9 @@
</div> </div>
<div class="select-main select-main1"> <div class="select-main select-main1">
<div class="checkbox-group"> <div class="checkbox-group">
<el-checkbox v-for="area in areaList" :key="area.id" v-model="activeAreaList" :label="area.id" <el-checkbox v-for="area in areaList" :key="area.id" v-model="activeAreaList"
style="width: 100px" @change="checked => handleAreaChange(area.id, checked)"> :label="area.id" style="width: 100px"
@change="checked => handleAreaChange(area.id, checked)">
{{ area.name }} {{ area.name }}
</el-checkbox> </el-checkbox>
</div> </div>
...@@ -359,7 +367,8 @@ ...@@ -359,7 +367,8 @@
<div class="title">{{ "政令库" }}</div> <div class="title">{{ "政令库" }}</div>
</div> </div>
<div class="content-box" v-show="decreeList"> <div class="content-box" v-show="decreeList">
<div class="main-item" v-for="(item, index) in decreeList" :key="index" @click="handleClickDecree(item)"> <div class="main-item" v-for="(item, index) in decreeList" :key="index"
@click="handleClickDecree(item)">
<div class="main-item-left"> <div class="main-item-left">
<div class="left-left"> <div class="left-left">
{{ item.time.split("-")[0] }}<br />{{ item.time.split("-")[1] }}月{{ {{ item.time.split("-")[0] }}<br />{{ item.time.split("-")[1] }}月{{
...@@ -401,8 +410,9 @@ ...@@ -401,8 +410,9 @@
{{ `共 ${totalDecreesNum} 项` }} {{ `共 ${totalDecreesNum} 项` }}
</div> </div>
<div class="footer-right"> <div class="footer-right">
<el-pagination @current-change="handleCurrentChange" :pageSize="10" :current-page="currentPage" <el-pagination @current-change="handleCurrentChange" :pageSize="10"
background layout="prev, pager, next" :total="totalDecreesNum" /> :current-page="currentPage" background layout="prev, pager, next"
:total="totalDecreesNum" />
</div> </div>
</div> </div>
</div> </div>
...@@ -413,7 +423,7 @@ ...@@ -413,7 +423,7 @@
</template> </template>
<script setup> <script setup>
import NewsList from "@/components/base/NewsList/index.vue"; import NewsList from "@/components/base/newsList/index.vue";
import { onMounted, ref, computed, watch, nextTick } from "vue"; import { onMounted, ref, computed, watch, nextTick } from "vue";
import router from "@/router"; import router from "@/router";
import { import {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论