提交 6eb0131b authored 作者: 张烨's avatar 张烨

fix:政令模块细节优化

上级 6b9cc944
...@@ -20,6 +20,14 @@ export function getDecreehylyList() { ...@@ -20,6 +20,14 @@ export function getDecreehylyList() {
}) })
} }
// 获取受影响实体列表
export function getDecreeEntities(params) {
return request({
method: 'GET',
url: `/api/administrativeOrderInfo/relatedEntities/${params.id}`,
})
}
// 根据政行业领域ID获取公司列表 // 根据政行业领域ID获取公司列表
/** /**
* @param {cRelated, id} * @param {cRelated, id}
......
...@@ -324,8 +324,8 @@ watch(isTranslate, () => { ...@@ -324,8 +324,8 @@ watch(isTranslate, () => {
.report-main { .report-main {
flex: auto; flex: auto;
box-sizing: border-box; height: 20px;
padding-top: 10px; padding: 10px 0;
.no-content { .no-content {
height: 100%; height: 100%;
......
...@@ -5,25 +5,25 @@ ...@@ -5,25 +5,25 @@
<div class="box1-main"> <div class="box1-main">
<div class="data-filter"> <div class="data-filter">
<div class="filter-select"> <div class="filter-select">
<el-select v-model="curAreaId" :empty-values="[null, undefined]" style="width: 100%"> <el-select v-model="areaInfo.id" :empty-values="[null, undefined]" style="width: 100%">
<el-option label="全部领域" value="" /> <el-option label="全部领域" value="" />
<el-option v-for="item in areaList" :key="item.id" :label="item.name" :value="item.id" /> <el-option v-for="item in areaInfo.list" :key="item.id" :label="item.name" :value="item.id" />
</el-select> </el-select>
</div> </div>
<div class="filter-input"> <div class="filter-input">
<el-input v-model="commandWord" @keyup.enter="handleSearch" style="width: 100%; height: 100%;" :suffix-icon="Search" placeholder="搜索实体" /> <el-input v-model="entityInfo.keyword" @keyup.enter="onDecreeEntities(1)" :suffix-icon="Search" placeholder="搜索实体" />
</div> </div>
</div> </div>
<div class="data-title">实体名称</div> <div class="data-title">实体名称</div>
<div style="height: 20px; flex: auto;"> <div style="height: 20px; flex: auto;">
<el-empty v-if="!showCompanyList?.length" style="padding: 60px 0;" description="暂无数据" :image-size="100" /> <el-empty v-if="!entityInfo.list?.length" style="padding: 60px 0;" description="暂无数据" :image-size="100" />
<el-scrollbar height="100%" always> <el-scrollbar height="100%" always>
<div class="list-data"> <div class="list-data">
<div class="list-item" v-for="item in showCompanyList" :key="item.id" :class="{ 'item-active': activeEntityId === item.id }" @click="handleToCompanyDetail(item)"> <div class="list-item" v-for="item in entityInfo.list" :key="item.id" :class="{ 'item-active': entityInfo.id==item.id }" @click="handleToCompanyDetail(item)">
<div class="item-icon"> <div class="item-icon">
<img :src="defaultIcon2" alt="" class="item-img" /> <img :src="defaultIcon2" alt="" class="item-img" />
</div> </div>
<div class="item-name one-line-ellipsis">{{ item.name }}</div> <div class="item-name one-line-ellipsis">{{ item.companyName }}</div>
<div class="item-icon item-icon-tag"> <div class="item-icon item-icon-tag">
<img :src="noticeIcon" alt="" class="item-img" /> <img :src="noticeIcon" alt="" class="item-img" />
</div> </div>
...@@ -33,16 +33,16 @@ ...@@ -33,16 +33,16 @@
</el-scrollbar> </el-scrollbar>
</div> </div>
<div class="pagination-info"> <div class="pagination-info">
<div class="pagination-left">{{ `共 ${companyTotalNum} 家企业` }}</div> <div class="pagination-left">{{ `共 ${entityInfo.total} 家企业` }}</div>
<div class="pagination-right"> <div class="pagination-right">
<el-pagination <el-pagination
@current-change="handleCurrentChange" @current-change="onDecreeEntities"
:pageSize="pageSize" :pageSize="entityInfo.pageSize"
:current-page="currentPage" :current-page="entityInfo.pageNum"
background background
layout="prev, pager, next" layout="prev, pager, next"
size="small" size="small"
:total="companyTotalNum" :total="entityInfo.total"
/> />
</div> </div>
</div> </div>
...@@ -68,9 +68,8 @@ ...@@ -68,9 +68,8 @@
</div> </div>
</div> </div>
<div class="title-right" v-if="contentType==1"> <div class="title-right" v-if="contentType==1">
<el-select v-model="curAreaId" :empty-values="[null, undefined]" style="width: 100%"> <el-select v-model="industryChain.id" style="width: 100%">
<el-option label="全部领域" value="" /> <el-option v-for="item in industryChain.list" :key="item.id" :label="item.name" :value="item.id" />
<el-option v-for="item in areaList" :key="item.id" :label="item.name" :value="item.id" />
</el-select> </el-select>
</div> </div>
</div> </div>
...@@ -78,10 +77,10 @@ ...@@ -78,10 +77,10 @@
<div class="box2-main"> <div class="box2-main">
<AiTips :tips="tips" /> <AiTips :tips="tips" />
<div class="graph-box" v-if="contentType==1"> <div class="graph-box" v-if="contentType==1">
<ChartChain /> <ChartChain :listData="fishbone.list" :baseData="fishbone.base" />
</div> </div>
<div class="graph-box" v-if="contentType==2"> <div class="graph-box" v-if="contentType==2">
<GraphChart :nodes="graphData.nodes" :links="graphData.links" layoutType="force" /> <GraphChart :nodes="graphInfo.nodes" :links="graphInfo.links" layoutType="force" />
</div> </div>
</div> </div>
</AnalysisBox> </AnalysisBox>
...@@ -91,8 +90,9 @@ ...@@ -91,8 +90,9 @@
<script setup> <script setup>
import { ref, onMounted, reactive } from "vue"; import { ref, onMounted, reactive } from "vue";
import { useRoute } from "vue-router";
import { Search } from '@element-plus/icons-vue' import { Search } from '@element-plus/icons-vue'
import { getDecreehylyList, getDecreeCompany } from "@/api/decree/influence"; import { getDecreehylyList, getDecreeEntities } from "@/api/decree/influence";
import ChartChain from "./com/ChartChain.vue"; import ChartChain from "./com/ChartChain.vue";
import AiTips from "./com/AiTips.vue"; import AiTips from "./com/AiTips.vue";
import GraphChart from "@/components/base/GraphChart/index.vue"; import GraphChart from "@/components/base/GraphChart/index.vue";
...@@ -104,9 +104,73 @@ import icon1620 from "./assets/images/icon1620.png"; ...@@ -104,9 +104,73 @@ import icon1620 from "./assets/images/icon1620.png";
import icon1621 from "./assets/images/icon1621.png"; import icon1621 from "./assets/images/icon1621.png";
import company from "./assets/images/company.png"; import company from "./assets/images/company.png";
const route = useRoute();
const tips = "这项政令标志着中美AI竞争进入一个新阶段,其核心特征是 “精准封锁”与“体系输出”相结合。它短期内无疑会给中国AI产业链带来压力,但长期看,这场竞争更可能是一场围绕技术路线、生态系统和治理规则的持久战。" const tips = "这项政令标志着中美AI竞争进入一个新阶段,其核心特征是 “精准封锁”与“体系输出”相结合。它短期内无疑会给中国AI产业链带来压力,但长期看,这场竞争更可能是一场围绕技术路线、生态系统和治理规则的持久战。"
// 关系图数据
const graphData = reactive({ // 行业领域
const areaInfo = reactive({
list: [],
id: "",
})
const handleGetHylyList = async () => {
try {
const res = await getDecreehylyList();
console.log("行业领域:", res);
if (res.code === 200) {
areaInfo.list = res.data || [];
}
} catch (error) {
areaInfo.list = [];
}
};
// 受影响实体
const entityInfo = reactive({
keyword: "",
pageSize: 10,
pageNum: 1,
total: 0,
list: [],
id: '',
})
const onDecreeEntities = async (page=1) => {
entityInfo.pageNum = page;
try {
const res = await getDecreeEntities({id: route.query.id});
console.log("受影响实体:", res);
if (res.code === 200 && res.data) {
entityInfo.list = res.data.companies;
entityInfo.total = res.data.companies.length;
}
} catch (error) {
console.log("获取受影响实体失败", error);
}
};
const handleToCompanyDetail = (item) => {
entityInfo.id = item.id;
};
const contentType = ref(1);
const headerContentType = (type) => {
contentType.value = type;
};
// 产业链
const industryChain = reactive({
list: [],
id: "",
})
// 产业链鱼骨图
const fishbone = reactive({
list: [],
base: {},
})
// 实体关系
const graphInfo = reactive({
leader: { id: 0, name: "泰丰先行" }, leader: { id: 0, name: "泰丰先行" },
list: [ list: [
{ id: 1, name: "国轩高科", formatter: '持股' }, { id: 1, name: "国轩高科", formatter: '持股' },
...@@ -122,9 +186,9 @@ const graphData = reactive({ ...@@ -122,9 +186,9 @@ const graphData = reactive({
links: [], links: [],
}); });
const initGraphChart = () => { const initGraphChart = () => {
graphData.links = graphData.list.map(onFormatLink) graphInfo.links = graphInfo.list.map(onFormatLink)
graphData.nodes = graphData.list.map(onFormatNode) graphInfo.nodes = graphInfo.list.map(onFormatNode)
graphData.nodes.unshift(onFormatNode(graphData.leader)) graphInfo.nodes.unshift(onFormatNode(graphInfo.leader))
} }
const onFormatLink = (item, index) => { const onFormatLink = (item, index) => {
return { return {
...@@ -163,86 +227,8 @@ const onWordWrap = (word, num) => { ...@@ -163,86 +227,8 @@ const onWordWrap = (word, num) => {
return label; return label;
} }
// 受影响实体
const companyList = ref([]);
const activeEntityId = ref(1);
const currentPage = ref(1);
const pageSize = ref(10);
const handleToCompanyDetail = (item) => {
activeEntityId.value = item.id;
};
const handleCurrentChange = page => {
currentPage.value = page;
};
const showCompanyList = ref([
{ id: 1, name: "北京市", status: "上市" },
{ id: 2, name: "上海市", status: "上市" },
{ id: 3, name: "广州市", status: "上市" },
{ id: 4, name: "深圳市", status: "上市" },
{ id: 5, name: "成都市", status: "上市" },
{ id: 7, name: "天津市", status: "上市" },
{ id: 9, name: "武汉市", status: "上市" },
{ id: 10, name: "西安市", status: "上市" },
]);
const handleGetCompanyListByArea = async () => {
const params = {
id: curAreaId.value
};
try {
const res = await getDecreeCompany(params);
console.log("行业领域公司列表", res);
if (res.code === 200 && res.data) {
companyList.value = res.data.map(item => {
return {
name: item.name,
id: item.id,
status: item.marketChange
};
});
companyTotalNum.value = companyList.value.length;
if (res.data?.length) handleToCompanyDetail(res.data[0])
} else {
companyList.value = [];
companyTotalNum.value = 0;
}
} catch (error) {
companyList.value = [];
companyTotalNum.value = 0;
}
};
// 指令搜索
const commandWord = ref("");
const handleSearch = () => {
};
// 行业领域
const curAreaId = ref("");
const areaList = ref([]);
const handleGetHylyList = async () => {
try {
const res = await getDecreehylyList();
console.log("行业领域列表", res);
if (res.code === 200 && res.data) {
areaList.value = res.data;
}
} catch (error) {
areaList.value = [];
}
};
// 产业链/实体关系
const contentType = ref(1);
const headerContentType = (type) => {
contentType.value = type;
};
// 企业影响分析
const companyTotalNum = ref(0); // 企业数量
onMounted(() => { onMounted(() => {
// handleGetCompanyListByArea(); onDecreeEntities();
initGraphChart() initGraphChart()
handleGetHylyList(); handleGetHylyList();
}); });
...@@ -283,6 +269,11 @@ onMounted(() => { ...@@ -283,6 +269,11 @@ onMounted(() => {
box-shadow: 0 0 0 1px var(--el-border-color) inset; box-shadow: 0 0 0 1px var(--el-border-color) inset;
box-sizing: border-box; box-sizing: border-box;
height: 32px; height: 32px;
:deep(.el-input) {
height: 100%;
width: 100%;
}
} }
} }
......
...@@ -53,7 +53,7 @@ export default defineConfig({ ...@@ -53,7 +53,7 @@ export default defineConfig({
'/api': { '/api': {
target: 'http://8.140.26.4:9085/', target: 'http://8.140.26.4:9085/',
// target: 'http://192.168.0.6:28080/', // target: 'http://172.20.10.3:28080/',
changeOrigin: true, changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '') rewrite: (path) => path.replace(/^\/api/, '')
}, },
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论