提交 6acd36c2 authored 作者: yanpeng's avatar yanpeng

merge conflict

流水线 #490 已通过 于阶段
in 1 分 42 秒
......@@ -11,10 +11,11 @@ export function getStatCount(params) {
}
// 分类接口
export function getStatSort() {
export function getStatSort(params) {
return request({
method: 'GET',
url: `/api/marketsearchHome/statSort`
url: `/api/marketsearchHome/statSort`,
params
})
}
......@@ -39,6 +40,18 @@ export function getStatNum(params) {
})
}
// 查询关税税率
/**
* @param {byYorM}
*/
export function getSearchTariff(params) {
return request({
method: 'GET',
url: `/api/marketsearchDetails/getSearchTariff`,
params
})
}
// 制裁领域分布
/**
* @param {years}
......@@ -178,6 +191,14 @@ export function getSearchBlurb(params) {
})
}
// 获取原文
export function getOriginalUrl(params) {
return request({
method: 'GET',
url: `/api/marketsearchDetails/getOriginalUrl/${params.id}`,
})
}
// 获取相关事件
export function getRelatedEvents(params) {
return request({
......
......@@ -3,7 +3,10 @@
<div class="icon">
<img src="./tip-icon.svg" alt="">
</div>
<div class="text text-tip-2 text-primary-50-clor">{{ tipText }}</div>
<div class="text text-tip-2 text-primary-50-clor">
<div v-if="ellipsis" :title="tipText" class="one-line-ellipsis">{{ tipText }}</div>
<div v-else>{{ tipText }}</div>
</div>
</div>
</template>
......@@ -23,7 +26,10 @@ const props = defineProps({
type: String,
default: '2023.1至2025.12'
},
ellipsis: {
type: Boolean,
default: false
}
})
const tipText = computed(() => props.text || `数据来源:${props.dataSource},数据时间:${props.dataTime}`)
......@@ -48,5 +54,9 @@ const tipText = computed(() => props.text || `数据来源:${props.dataSource}
height: 100%;
}
}
.text {
width: 20px;
flex: auto;
}
}
</style>
\ No newline at end of file
......@@ -383,9 +383,9 @@ const handleToModule = (item, index) => {
} else {
const curRoute = router.resolve({
path: item.path,
query: {
titleIndex: 2
}
// query: {
// titleIndex: 2
// }
});
window.open(curRoute.href, "_blank");
}
......
......@@ -6,6 +6,7 @@ const MarketAccessCase = () => import('@/views/marketAccessRestrictions/marketAc
const MarketSingleCaseLayout = () => import('@/views/marketAccessRestrictions/singleCaseLayout/index.vue')
const MarketSingleCaseOverview = () => import('@/views/marketAccessRestrictions/singleCaseLayout/overview/index.vue')
const MarketSingleCaseDeepdig = () => import('@/views/marketAccessRestrictions/singleCaseLayout/deepdig/index.vue')
const MarketSingleReportOriginal = () => import('@/views/marketAccessRestrictions/pages/reportOriginal.vue')
const marketAccessRestrictionsRoutes = [
// 市场准入限制首页
......@@ -42,7 +43,6 @@ const marketAccessRestrictionsRoutes = [
}
]
},
{
path: "/marketSingleCaseLayout",
name: "MarketSingleCaseLayout",
......@@ -67,7 +67,12 @@ const marketAccessRestrictionsRoutes = [
}
]
},
{
path: "reportOriginal",
name: "MarketSingleReportOriginal",
component: MarketSingleReportOriginal,
meta: { noTitle: true }
}
]
export default marketAccessRestrictionsRoutes
\ No newline at end of file
......@@ -859,11 +859,42 @@ const handleCommitteeCurrentChange = page => {
// 议员合作关系跳转至数据资源库
const handleCooperationToDataLibrary = (item) => {
console.log('item', item);
console.log('activeAreaList', activeAreaList.value);
console.log('areaOptions', areaOptions.value);
// console.log('item', item);
// console.log('activeAreaList', activeAreaList.value);
// console.log('areaOptions', areaOptions.value);
// console.log('footerSelect1', footerSelect1.value);
// console.log('委员会列表', postOrgList.value);
const postOrgStr = postOrgList.value.filter(item => item.departmentId === footerSelect1.value)[0].departmentName
const areaList = activeAreaList.value.map(item => {
return areaOptions.value.filter(val => val.id === item)[0].name
})
const memberList = [item.left.name, item.right.name]
console.log(postOrgStr, areaList, memberList);
let param
if (areaList.length > 2) {
param = {
selectedOrg: postOrgStr,
selectedmember: JSON.stringify(memberList),
selectedAreaList: JSON.stringify(areaList)
}
} else {
param = {
selectedOrg: postOrgStr,
selectedmember: JSON.stringify(memberList),
domains: areaList[0]
}
}
const route = router.resolve({
path: "/dataLibrary/countryBill",
query: param
});
window.open(route.href, "_blank");
}
......@@ -872,10 +903,10 @@ const handleToDataLibrary = (item) => {
let congressStr = '全部议院'
console.log('item', item);
console.log('activeYyList', activeYyList.value);
if(activeYyList.value && activeYyList.value.length === 1) {
if(activeYyList.value[0] === 'S') {
if (activeYyList.value && activeYyList.value.length === 1) {
if (activeYyList.value[0] === 'S') {
congressStr = '参议院'
} else if(activeYyList.value[0] === 'H') {
} else if (activeYyList.value[0] === 'H') {
congressStr = '众议院'
}
}
......
......@@ -21,7 +21,7 @@
moreText="查看全部委员会"
:moreCardMinCount="7"
@time-click="handleCommitteeTimeClick"
@name-click="handleToDataLibrary"
@name-click="handleToInstitution"
@count-click="handleToDataLibrary"
@more-click="handleToCommitteeMore"
/>
......@@ -1414,28 +1414,46 @@ const handleResize = () => {
box9ChartInstance && box9ChartInstance.resize();
};
// 下钻至资源库
const handleToDataLibrary = (item) => {
window.sessionStorage.setItem("curTabName", item.id);
// 跳转行政机构主页
const handleToInstitution = item => {
window.sessionStorage.setItem("curTabName", item.orgName);
const curRoute = router.resolve({
path: "/institution",
query: {
id: item.id
id: item.orgId
}
});
window.open(curRoute.href, "_blank");
// router.push({
// path: "/institution",
// query: {
// id: item.orgId
// }
// })
};
// console.log('item', item);
// const selectParam = {
// selectedOrg: item.name,
// selectedCongress: item.chamber
// 下钻至资源库
const handleToDataLibrary = (item) => {
// window.sessionStorage.setItem("curTabName", item.id);
// const curRoute = router.resolve({
// path: "/institution",
// query: {
// id: item.id
// }
// const route = router.resolve({
// path: "/dataLibrary/countryBill",
// query: selectParam
// });
// window.open(route.href, "_blank");
// window.open(curRoute.href, "_blank");
// console.log('item', item);
const selectParam = {
selectedOrg: item.name,
selectedCongress: item.chamber
}
const route = router.resolve({
path: "/dataLibrary/countryBill",
query: selectParam
});
window.open(route.href, "_blank");
}
......
<template>
<div class="wrapper">
<div class="header">
<div class="header-content">
<div class="header-item">首页</div>
<div class="header-item">></div>
<div class="header-item back-item" @click="handleBackHome">综合检索</div>
<div class="header-item">></div>
<div class="header-item">智能问答</div>
</div>
</div>
<div class="main">
<div class="left">
<div class="left-header">
......@@ -199,12 +190,6 @@ const areaList = ref([
}
]);
// 返回综合检索
const handleBackHome = () => {
router.push({
path: "/comprehensiveSearch"
});
};
const contentContainer = ref(null);
......
......@@ -2,7 +2,7 @@
<div class="select-wrapper" :class="{ 'select-wrapper-custom': selectValue === '自定义' }">
<div class="select-left text-tip-1">{{ selectTitle + ':' }}</div>
<div class="select-right" :class="{ 'select-right-custom': selectValue === '自定义' }">
<el-select v-model="selectValue" :placeholder="placeholderName" filterable style="width: 240px">
<el-select v-model="selectValue" :placeholder="placeholderName" filterable :multiple="isMultiple" style="width: 240px">
<!-- <el-option label="全部领域" value="全部领域" /> -->
<el-option v-for="item in selectList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
......@@ -37,6 +37,10 @@ const props = defineProps({
customTime: {
type: String,
default: ''
},
isMultiple: {
type: Boolean,
default: false
}
})
......@@ -58,7 +62,7 @@ const customTimeValue = computed({
<style lang="scss" scoped>
.select-wrapper {
width: 348px;
height: 28px;
min-height: 28px;
display: flex;
justify-content: space-between;
align-items: center;
......
......@@ -721,12 +721,12 @@ const handleSelectEntityType = value => {
const handleGetEntityTypes = async () => {
try {
const res = await getEntityTypes()
console.log('获取实体类型列表');
console.log('获取实体类型列表', res);
if (res.code === 200 && res.data) {
entityTypeList.value = res.data.map(item => {
return {
name: item.name,
id: item.code
id: item.id
}
})
}
......@@ -814,7 +814,6 @@ const fetchTableData = async () => {
provinceName: selectedProvince.value === '全部省份' ? null : selectedProvince.value, // 实体省份
entityTypeCode: selectedEntityType.value === '全部实体类型' ? null : selectedEntityType.value, // 实体类别
ratio: isHalfRule.value ? 'Y' : null, // 50%规则
isInvolveCn: isCnEntityOnly.value ? 'Y' : null, // 是否只看中国实体
sort: isSort.value ? 0 : 1 // 0 先按分数降序 后按时间降序 1 先按分数降序,再按时间升序
}
try {
......@@ -905,7 +904,6 @@ const fetchAllData = async () => {
provinceName: selectedProvince.value === '全部省份' ? null : selectedProvince.value, // 实体省份
entityTypeCode: selectedEntityType.value === '全部实体类型' ? null : selectedEntityType.value, // 实体类别
ratio: isHalfRule.value ? 'Y' : null, // 50%规则
isInvolveCn: isCnEntityOnly.value ? 'Y' : null, // 是否只看中国实体
sort: isSort.value ? 0 : 1 // 0 先按分数降序 后按时间降序 1 先按分数降序,再按时间升序
}
try {
......@@ -1064,11 +1062,16 @@ const initParam = () => {
}
selectedProvince.value = route.query.selectedProvince ? provinceList.value.filter(item => item.name.indexOf(route.query.selectedProvince) > -1)[0].name : '全部省份'
selectedCountry.value = route.query.selectedCountryId ? route.query.selectedCountryId : '全部国家'
isHalfRule.value = route.query.isHalfRule ? true : false
isHalfRule.value = route.query.isHalfRule === 'true' ? true : false
isCnEntityOnly.value = route.query.isCnEntityOnly ? true : false
if (isCnEntityOnly.value) {
selectedCountry.value = '0101'
} else {
selectedCountry.value = route.query.selectedCountryId ? route.query.selectedCountryId : '全部国家'
}
selectedEntityType.value = route.query.selectedEntityType ? entityTypeList.value.filter(item => item.name === route.query.selectedEntityType)[0].id : '全部实体类型'
......@@ -1083,17 +1086,32 @@ const initParam = () => {
selectedDate.value = '自定义'
customTime.value = JSON.parse(savedQuery.selectedDate)
}
isHalfRule.value = savedQuery.isHalfRule ? true : false
isHalfRule.value = savedQuery.isHalfRule === 'true' ? true : false
selectedProvince.value = savedQuery.selectedProvince ? provinceList.value.filter(item => item.name.indexOf(savedQuery.selectedProvince) > -1)[0].name : '全部省份'
selectedCountry.value = route.query.selectedCountryId ? route.query.selectedCountryId : '全部国家'
isCnEntityOnly.value = savedQuery.isCnEntityOnly ? true : false
if (isCnEntityOnly.value) {
selectedCountry.value = '0101'
} else {
selectedCountry.value = route.query.selectedCountryId ? route.query.selectedCountryId : '全部国家'
}
selectedEntityType.value = savedQuery.selectedEntityType ? entityTypeList.value.filter(item => item.name === savedQuery.selectedEntityType)[0].id : '全部实体类型'
}
}
watch(
() => isCnEntityOnly.value,
val => {
if (val) {
selectedCountry.value = '0101'
} else {
selectedCountry.value = '全部国家'
}
}
)
// 跳转机构详情
const handleClickToDetail = (curEntity) => {
console.log('curEntity', curEntity);
......
......@@ -180,6 +180,7 @@ import BarChart from '../../components/BarChart/index.vue'
import RaderChart from '../../components/RadarChart/idnex.vue'
import SelectBox from '../../components/SelectBox/index.vue'
import DataChartSwitchBox from '../../components/dataChartSwitchBox/index.vue'
import { useRoute } from "vue-router";
import router from '@/router'
......@@ -813,7 +814,7 @@ const fetchTableData = async () => {
provinceName: selectedProvince.value === '全部省份' ? null : selectedProvince.value, // 实体省份
entityTypeCode: selectedEntityType.value === '全部实体类型' ? null : selectedEntityType.value, // 实体类别
ratio: isHalfRule.value ? 'Y' : null, // 50%规则
isInvolveCn: isCnEntityOnly.value ? 'Y' : null, // 是否只看中国实体
// isInvolveCn: isCnEntityOnly.value ? 'Y' : null, // 是否只看中国实体
sort: isSort.value ? 0 : 1 // 0 先按分数降序 后按时间降序 1 先按分数降序,再按时间升序
}
try {
......@@ -861,7 +862,17 @@ const fetchTableData = async () => {
setTimeout(() => {
activeChart.value = curDemensionItem.chartTypeList[0]
if (curDemension.value === '制裁时间') {
if (selectedTime.value === '按月度统计') {
curChartData.value = curDemensionItem.data
} else if (selectedTime.value === '按季度统计') {
curChartData.value = curDemensionItem.quatarData
} else {
curChartData.value = curDemensionItem.yearData
}
} else {
curChartData.value = curDemensionItem.data
}
})
loading.value = false
} catch (error) {
......@@ -894,7 +905,7 @@ const fetchAllData = async () => {
provinceName: selectedProvince.value === '全部省份' ? null : selectedProvince.value, // 实体省份
entityTypeCode: selectedEntityType.value === '全部实体类型' ? null : selectedEntityType.value, // 实体类别
ratio: isHalfRule.value ? 'Y' : null, // 50%规则
isInvolveCn: isCnEntityOnly.value ? 'Y' : null, // 是否只看中国实体
// isInvolveCn: isCnEntityOnly.value ? 'Y' : null, // 是否只看中国实体
sort: isSort.value ? 0 : 1 // 0 先按分数降序 后按时间降序 1 先按分数降序,再按时间升序
}
try {
......@@ -1053,11 +1064,16 @@ const initParam = () => {
}
selectedProvince.value = route.query.selectedProvince ? provinceList.value.filter(item => item.name.indexOf(route.query.selectedProvince) > -1)[0].name : '全部省份'
selectedCountry.value = route.query.selectedCountryId ? route.query.selectedCountryId : '全部国家'
isHalfRule.value = route.query.isHalfRule ? true : false
isHalfRule.value = route.query.isHalfRule === 'true' ? true : false
isCnEntityOnly.value = route.query.isCnEntityOnly ? true : false
if (isCnEntityOnly.value) {
selectedCountry.value = '0101'
} else {
selectedCountry.value = route.query.selectedCountryId ? route.query.selectedCountryId : '全部国家'
}
selectedEntityType.value = route.query.selectedEntityType ? entityTypeList.value.filter(item => item.name === route.query.selectedEntityType)[0].id : '全部实体类型'
......@@ -1072,17 +1088,32 @@ const initParam = () => {
selectedDate.value = '自定义'
customTime.value = JSON.parse(savedQuery.selectedDate)
}
isHalfRule.value = savedQuery.isHalfRule ? true : false
isHalfRule.value = savedQuery.isHalfRule === 'true' ? true : false
selectedProvince.value = savedQuery.selectedProvince ? provinceList.value.filter(item => item.name.indexOf(savedQuery.selectedProvince) > -1)[0].name : '全部省份'
selectedCountry.value = route.query.selectedCountryId ? route.query.selectedCountryId : '全部国家'
isCnEntityOnly.value = savedQuery.isCnEntityOnly ? true : false
if (isCnEntityOnly.value) {
selectedCountry.value = '0101'
} else {
selectedCountry.value = route.query.selectedCountryId ? route.query.selectedCountryId : '全部国家'
}
selectedEntityType.value = savedQuery.selectedEntityType ? entityTypeList.value.filter(item => item.name === savedQuery.selectedEntityType)[0].id : '全部实体类型'
}
}
watch(
() => isCnEntityOnly.value,
val => {
if (val) {
selectedCountry.value = '0101'
} else {
selectedCountry.value = '全部国家'
}
}
)
// 跳转机构详情
const handleClickToDetail = (curEntity) => {
console.log('curEntity', curEntity);
......@@ -1207,9 +1238,17 @@ onMounted(async () => {
}
.chart-main-box {
width: 1568px;
height: 809px;
margin: 0 auto;
background: rgba(255, 255, 255);
border: 1px solid var(--bg-black-5);
border-radius: 10px;
.info-box {
margin: 0 auto;
width: 1568px;
margin-top: 16px;
width: 1520px;
height: 30px;
display: flex;
justify-content: space-between;
......@@ -1229,14 +1268,13 @@ onMounted(async () => {
.content-box {
margin: 0 auto;
margin-top: 16px;
width: 1568px;
height: 766px;
border-radius: 10px;
background: rgba(255, 255, 255);
border: 1px solid var(--bg-black-5);
width: 1520px;
height: 726px;
border: none;
.content-header {
margin: 16px 24px;
margin: 16px 0;
width: 1520px;
height: 28px;
}
......
......@@ -1213,4 +1213,6 @@ onMounted(async () => {
// :deep(.el-table__header th:first-child) {
// background-color: #e6f7ff;
// color: #1890ff;
// }</style>
\ No newline at end of file
// }
</style>
......@@ -152,7 +152,7 @@
</div>
<div class="ai-pane">
<AiButton />
<AiPane :aiContent="summarize1" />
<AiPane :aiContent="aiContent.content1" />
</div>
</div>
......@@ -188,7 +188,7 @@
</div>
<div class="ai-pane">
<AiButton />
<AiPane :aiContent="summarize2" />
<AiPane :aiContent="aiContent.content2" />
</div>
</div>
</div>
......@@ -442,6 +442,7 @@ import setChart from "@/utils/setChart";
import DefaultIcon2 from "@/assets/icons/default-icon2.png";
import tipsTcon from "./assets/images/tips-icon.png";
import { ElMessage } from "element-plus";
import { getAIReport, getNearYearList } from "@/views/marketAccessRestrictions/utils/index.ts"
import { useGotoNewsDetail } from '@/router/modules/news';
......@@ -722,17 +723,16 @@ const handleClickPerson = async item => {
} catch (error) { }
};
// 获取最近年份列表
const currentYear = new Date().getFullYear();
const getYearList = (count = 6) => {
const yearOptions = [];
for (let i = 0; i < count; i++) {
const year = currentYear - i;
yearOptions.push({ label: year.toString(), value: year.toString() });
}
return yearOptions;
};
const yearList = getYearList();
const yearList = getNearYearList();
// 获取AI智能报告
const aiContent = reactive({
content1: "正在生成...",
content2: "正在生成...",
})
const onAIReport = (data, key) => {
getAIReport(data).then(res => { aiContent[key] = res })
}
// 行政令发布频度
const chart1Data = ref({
......@@ -745,7 +745,6 @@ const box5Params = reactive({
proposeName: '',
loading: false,
})
const summarize1 = ref()
const handleGetDecreeYearOrder = async () => {
box5Params.loading = true
try {
......@@ -763,61 +762,17 @@ const handleGetDecreeYearOrder = async () => {
chart1Data.value.dataY = res.data.map(item => {
return item.count;
});
onChartInterpretation({ type: "柱状图", name: "数量变化趋势", data: res.data }, summarize1)
onAIReport({ type: "柱状图", name: "数量变化趋势", data: res.data }, "content1")
} else {
chart1Data.value.dataX = [];
chart1Data.value.dataY = [];
aiContent.content1 = ""
}
} catch (error) {
console.error("行政令发布频度error", error);
}
box5Params.loading = false
};
// AI智能总结
const onChartInterpretation = async (text, param) => {
param.value = "正在生成..."
// 👇 新增:超时 + 终止请求(只加这一段)
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 10000); // 10秒超时
try {
const response = await fetch('/aiAnalysis/chart_interpretation', {
method: 'POST',
headers: {
"X-API-Key": "aircasKEY19491001",
'Content-Type': 'application/json',
},
body: JSON.stringify({ text }),
signal: controller.signal // 👇 新增:绑定中断信号
});
clearTimeout(timeout); // 👇 新增:请求成功清除定时器
if (!response.ok) throw new Error(`HTTP 错误 ${response.status}`);
const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = '';
let summarize = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const lines = buffer.split('\n');
buffer = lines.pop() || '';
for (const line of lines) {
if (line.startsWith('data: ')) {
const content = line.substring(6);
const textMatch = content.match(/"解读":\s*"([^"]*)"/);
if (textMatch && textMatch[1]) summarize = textMatch[1];
}
}
}
param.value = summarize
} catch (err) {
param.value = "系统异常,生成失败";
}
}
const handleBox5 = async () => {
await handleGetDecreeYearOrder();
......@@ -863,7 +818,6 @@ const box6Params = reactive({
proposeName: '',
loading: false,
});
const summarize2 = ref()
const handleGetDecreeArea = async () => {
box6Params.loading = true
try {
......@@ -880,7 +834,10 @@ const handleGetDecreeArea = async () => {
value: item.count
};
});
onChartInterpretation({ type: "环形图", name: "领域分布情况", data: res.data }, summarize2)
onAIReport({ type: "环形图", name: "领域分布情况", data: res.data }, "content2")
} else {
chart2Data.value = []
aiContent.content2 = ""
}
} catch (error) {
console.error("政令科技领域error", error);
......
......@@ -53,7 +53,7 @@
<div v-for="(subSubItem, subSubIndex) in subItem.slaver" :key="subSubIndex"
class="sub-sub-item">
<div class="sub-sub-item-dot">{{ ALPHABET[subSubIndex % 26] }}.</div>
<div class="sub-sub-item-word" v-html="subItem.content"></div>
<div class="sub-sub-item-word" v-html="subSubItem.content"></div>
</div>
</div>
</div>
......@@ -157,6 +157,7 @@ import ActionButton from '@/components/base/ActionButton/index.vue'
import DefaultIcon1 from "@/assets/icons/default-icon1.png";
import DefaultIcon2 from "@/assets/icons/default-icon2.png";
import defaultCom from "@/views/coopRestriction/assets/images/default-icon2.png"
import { onNumToChinese } from "@/views/marketAccessRestrictions/utils/index"
const route = useRoute();
......@@ -185,70 +186,7 @@ const handleGetAreaList = async () => {
// 主要指令
const isHighlight = ref(false);
const commandWord = ref("");
const contentList = ref([
// {
// content: "建立美国人工智能出口计划建立美国人工智能出口计划建立美国人工智能出口计划建立美国人工智能出口计划建立美国人工智能出口计划",
// slaver: [
// {
// content: '在本命令发布之日起 90 天内,商务部长应与国务卿及科学技术政策办公室(OSTP)主任协商,建立并实施美国人工智能出口计划(计划),以支持美国全栈人工智能出口软件包的开发和部署。'
// },
// {
// content: '商务部长应公开征集由行业主导的联盟提案,以纳入该计划。公开征集要求每项提案必须:',
// slaver: [
// {
// content: '包含一套全栈人工智能技术包,涵盖:',
// slaver: [
// {
// content: 'AI 优化的计算机硬件(如芯片、服务器和加速器)、数据中心存储、云服务和网络,以及这些设备是否以及在多大程度上在美国制造的描述;'
// },
// {
// content: '数据管道和标签系统;'
// },
// {
// content: '人工智能模型与系统;'
// },
// {
// content: '采取措施保障人工智能模型和系统的安全性和网络安全;'
// },
// {
// content: '针对特定用例的人工智能应用(如软件工程、教育、医疗保健、农业或交通运输);'
// }
// ]
// },
// {
// content: '确定出口参与者的具体目标国家或区域集团;'
// },
// {
// content: '描述一个业务和运营模型,以在高层次上说明哪些实体将建设、拥有和运营数据中心及相关基础设施;'
// },
// {
// content: '联邦激励和支持机制请求的细节;'
// },
// {
// content: '遵守所有相关的美国出口管制制度、出境投资法规和终端用户政策,包括美国法典第 50 编第 58 章及商务部工业与安全局的相关指导。'
// }
// ]
// },
// {
// content: '商务部要求提案须在公开征集后不超过 90 天内提交,并应滚动考虑提案纳入项目。'
// },
// {
// content: '商务部长应与国务卿、国防部长、能源部长及 OSTP 主任协商,评估提交的纳入计划提案。商务部长与国务卿、国防部长、能源部长及 OSTP 主任协商后选定的提案,将被指定为优先 AI 出口包,并通过优先访问本命令第 4 节指定的工具予以支持,符合适用法律。'
// }
// ]
// },
// {
// content: "动员联邦融资工具",
// slaver: [
// {
// content: '经济外交行动小组(EDAG),于 2024 年 6 月 21 日总统备忘录中成立,由国务卿主持,并与商务部长和美国贸易代表协商,并根据 2019 年《通过外交倡导美国企业法案》(公共法 116-94 J 部分第七章)第 708 条(CABDA)所述,应协调联邦融资工具的动员,以支持优先的人工智能出口方案。'
// },
// {
// content: '我将根据 CABDA α 第 708 (c) (3) 条授权小企业管理局局长和 OSTP 主任任命各自执行部门和机构的高级官员担任 EDAG 。'
// }
// ]
// }
]);
const contentList = ref([]);
const ALPHABET = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"];
const onMainContentData = async () => {
try {
......@@ -257,7 +195,7 @@ const onMainContentData = async () => {
console.log("主要指令", res);
if (res && res.code === 200) {
contentList.value = res.data || [];
contentList.value.forEach((item, index) => { item.content = `(${simpleNumToChinese(index + 1)}) ${item.content}` })
contentList.value.forEach((item, index) => { item.content = `(${onNumToChinese(index + 1)}) ${item.content}` })
if (keyword) {
let word = keyword.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
contentList.value.forEach(item => { onHighlight(word, item) })
......@@ -279,30 +217,6 @@ const onHighlight = (word, row) => {
row.slaver.forEach(item => { onHighlight(word, item) })
}
}
// 数字转中文(支持 0-99 整数)
const simpleNumToChinese = (num) => {
// 1. 基础校验:只处理 0-99 的整数
if (!Number.isInteger(num) || num < 0 || num > 99) return '100';
// 2. 定义基础字符
const singleChars = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'];
const tenChar = '十';
// 3. 核心转换逻辑
if (num < 10) {
// 0-9 直接返回对应字符
return singleChars[num];
} else if (num === 10) {
// 10 特殊处理
return tenChar;
} else if (num < 20) {
// 11-19:十 + 个位(如十一、十九)
return tenChar + singleChars[num - 10];
} else {
// 20-99:十位 + 十 + 个位(个位为0则省略,如二十、二十九)
const ten = Math.floor(num / 10); // 十位数字
const unit = num % 10; // 个位数字
return singleChars[ten] + tenChar + (unit === 0 ? '' : singleChars[unit]);
}
}
// 思维导图
const isTreeDialog = ref(false);
......
......@@ -7,7 +7,7 @@
<div class="sub-title">{{ subtitle }}</div>
</div>
<div class="description">{{ description }}</div>
<div v-if="quantity > 0" class="quantity" :style="{ color: color }">
<div v-if="quantity > 0" class="quantity" :style="{ color: color }" @click.stop="handleClickNum(title)">
{{ quantity }}{{ unit || "个" }}
<div class="quantity-title-des" v-if="desMap[title]">
<img class="info-icon" :src="infoIcon" alt="" />
......@@ -20,6 +20,28 @@
<script setup>
import infoIcon from "../assets/icons/info-icon.png";
import { useRouter } from "vue-router";
const router = useRouter()
const emits = defineEmits(['num-click'])
const handleClickNum = (item) => {
if (item === '实体清单') {
const route = router.resolve({
path: "/dataLibrary/dataEntityList",
query: {
isCnEntityOnly: true
}
});
window.open(route.href, "_blank");
} else if (item === '商业管制清单') {
const route = router.resolve({
path: "/dataLibrary/dataCommerceControlList",
});
window.open(route.href, "_blank");
}
}
defineProps({
title: {
type: String,
......@@ -135,6 +157,7 @@ const desMap = {
display: flex;
flex-direction: column;
align-items: flex-end;
.quantity-title-des {
display: flex;
align-items: center;
......@@ -143,6 +166,7 @@ const desMap = {
font-weight: 400;
color: rgba(95, 101, 108, 1);
line-height: 1.4;
.info-icon {
width: 16px;
height: 16px;
......
......@@ -136,7 +136,7 @@
</div>
</div>
</div>
<div class="box1-absolute">
<div class="box1-absolute" @click="handleToDataLibrary(item)">
<div class="box1-absolute-des">
<el-icon>
<Warning color="rgba(206, 79, 81, 1)" />
......@@ -889,7 +889,8 @@ const handleTitleClick = item => {
path: "/exportControl/singleSanction",
query: {
id: item.id,
sanTypeId: item.sanTypeId
sanTypeId: item.sanTypeId,
date: `${item.year}-${item.dateStr}`
}
});
window.open(route.href, "_blank");
......@@ -1769,7 +1770,8 @@ const handleSanc = item => {
path: "/exportControl/singleSanction",
query: {
id: item.id,
sanTypeId: activeResourceTabItem.value.id
sanTypeId: activeResourceTabItem.value.id,
date: item.postDate
}
});
window.open(route.href, "_blank");
......@@ -1825,7 +1827,7 @@ const handleSearch = () => {
const handleEntityRowClick = row => {
console.log("row", row);
const params = {
domains: row.tags[0],
// domains: row.tags[0],
selectedDate: JSON.stringify([row.year + "-01-01", row.year + "-12-31"])
};
const route = router.resolve({
......@@ -1839,7 +1841,7 @@ const handleEntityRowClick = row => {
const handleCommercialRowClick = row => {
console.log("row", row);
const params = {
domains: row.tags[0],
// domains: row.tags[0],
selectedDate: JSON.stringify([row.year + "-01-01", row.year + "-12-31"])
};
const route = router.resolve({
......@@ -1865,18 +1867,31 @@ const handleRadarChartClick = value => {
// 点击制裁清单数量增长趋势
const handleMultiBarChartClick = val => {
// console.log('value', val);
const params = {
isHalfRule: trendChecked.value,
domains: val.seriesName,
isCnEntityOnly: true,
selectedDate: JSON.stringify([val.name + "-01-01", val.name + "-12-31"])
};
const route = router.resolve({
path: "/dataLibrary/dataEntityListEvent",
path: selectedEntityId.value === 1 ? "/dataLibrary/dataEntityList" : "/dataLibrary/dataCommerceControlList",
query: params
});
window.open(route.href, "_blank");
};
// 跳转到数据资源库
const handleToDataLibrary = (item) => {
const route = router.resolve({
path: "/dataLibrary/dataEntityList",
query: {
isCnEntityOnly: true,
selectedDate: JSON.stringify([item.postDate, item.postDate])
}
});
window.open(route.href, "_blank");
}
onMounted(async () => {
handleGetHylyList();
let chart1 = getMultiLineChart(chart1Data.value.title, chart1Data.value.data[0].value, chart1Data.value.data[1].value);
......@@ -1990,7 +2005,7 @@ const handleMediaClick = item => {
padding-right: 50px;
box-sizing: border-box;
background: linear-gradient(to right, rgba(206, 79, 81, 0), rgba(206, 79, 81, 0.3));
cursor: pointer;
&-des {
display: flex;
gap: 5px;
......
<template>
<div class="data-statistics">
<div class="nav">
<div class="nav-item">
<div class="nav-item" @click="handleToDataLibrary">
<div class="item-position"></div>
<div class="content">
<div class="info">
......@@ -13,7 +13,7 @@
</div>
</div>
</div>
<div class="nav-item">
<div class="nav-item" @click="handleToDataLibrary1">
<div class="item-position"></div>
<div class="content">
<div class="info">
......@@ -26,7 +26,7 @@
</div>
</div>
</div>
<div class="nav-item">
<div class="nav-item" @click="handleToDataLibrary2">
<div class="item-position"></div>
<div class="content">
<div class="info">
......@@ -38,7 +38,7 @@
</div>
</div>
</div>
<div class="nav-item">
<div class="nav-item" @click="handleToDataLibrary3(totalCount.latestTime)">
<div class="item-position"></div>
<div class="content">
<div class="info">
......@@ -412,6 +412,8 @@ const totalCount = ref(0);
const getTotalCountData = async () => {
try {
const res = await getTotalCount(sanTypeId.value);
console.log('统计', res);
totalCount.value = res.data || 0;
} catch (error) {
console.error("获取实体清单-数据统计-总量统计失败:", error);
......@@ -1193,7 +1195,49 @@ const handlePieChartClick1 = val => {
query: params
});
window.open(route.href, "_blank");
};
}
// 跳转到数据资源库
const handleToDataLibrary = () => {
const route = router.resolve({
path: "/dataLibrary/dataEntityList",
query:{
isCnEntityOnly: true
}
});
window.open(route.href, "_blank");
}
const handleToDataLibrary1 = () => {
const route = router.resolve({
path: "/dataLibrary/dataEntityList",
query:{
isCnEntityOnly: true,
isHalfRule: true
}
});
window.open(route.href, "_blank");
}
const handleToDataLibrary2 = () => {
const route = router.resolve({
path: "/dataLibrary/dataEntityList",
query:{
selectedDate: JSON.stringify([currentYear+'01-01', currentYear+ '12-31'])
}
});
window.open(route.href, "_blank");
}
const handleToDataLibrary3 = (time) => {
const route = router.resolve({
path: "/dataLibrary/dataEntityList",
query:{
selectedDate: JSON.stringify([time, time])
}
});
window.open(route.href, "_blank");
}
onMounted(() => {
sanTypeId.value = route.query.sanTypeId || "";
......@@ -1235,6 +1279,10 @@ onMounted(() => {
background-color: #fff;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
position: relative;
cursor: pointer;
&:hover{
background: var(--color-primary-2);
}
.item-position {
position: absolute;
......
......@@ -75,17 +75,9 @@
<AnalysisBox title="实体清单更新历史" :showAllBtn="false">
<template #header-btn>
<div class="filters">
<el-select
v-model="selectedDomain"
placeholder="Select"
style="width: 150px; height: 32px; margin-right: 16px"
>
<el-option
v-for="item in domainOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
<el-select v-model="selectedDomain" placeholder="Select"
style="width: 150px; height: 32px; margin-right: 16px">
<el-option v-for="item in domainOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<el-checkbox v-model="onlyChina">只看涉华动态</el-checkbox>
</div>
......@@ -99,20 +91,15 @@
<img :src="item.icon || title" alt="" />
<div class="main">
<div class="main-title" @click="handleClick(item)">{{ item.name }}</div>
<el-tooltip
effect="dark"
:content="item.summary"
popper-class="common-prompt-popper"
placement="top"
:show-after="500"
>
<el-tooltip effect="dark" :content="item.summary" popper-class="common-prompt-popper" placement="top"
:show-after="500">
<div class="main-desc">{{ item.summary }}</div>
</el-tooltip>
<div class="tag-box">
<div v-for="tag in item.techDomainList" :key="tag" class="tag-item">{{ tag }}</div>
</div>
<div :class="{ 'count-tag': item.cnEntityCount }">
<div :class="{ 'count-tag': item.cnEntityCount }" @click="handleToDataLibrary">
{{ item.cnEntityCount ? `${item.cnEntityCount}家中国实体` : "" }}
</div>
</div>
......@@ -120,14 +107,8 @@
</div>
<div class="left-footer">
<div class="total-count"> {{ totalAll }} </div>
<el-pagination
v-model:current-page="currentPageAll"
:page-size="pageSizeAll"
:total="totalAll"
layout="prev, pager, next"
background
@current-change="handlePageChangeAll"
/>
<el-pagination v-model:current-page="currentPageAll" :page-size="pageSizeAll" :total="totalAll"
layout="prev, pager, next" background @current-change="handlePageChangeAll" />
</div>
</AnalysisBox>
</div>
......@@ -149,12 +130,8 @@
<span>关键人物</span>
</div>
<div class="key-person-list">
<div
class="person-item"
v-for="(item, index) in publishInfo.personList"
:key="index"
@click="handlePerClick(item)"
>
<div class="person-item" v-for="(item, index) in publishInfo.personList" :key="index"
@click="handlePerClick(item)">
<img :src="item.imageUrl" alt="" />
<div class="person-info">
<CommonPrompt :content="item.name">
......@@ -242,7 +219,8 @@ const handleClick = item => {
path: "/exportControl/singleSanction",
query: {
id: item.id,
sanTypeId: item.sanTypeId || 1
sanTypeId: item.sanTypeId || 1,
date: `${item.year}-${item.date}`
}
});
window.open(route.href, "_blank");
......@@ -421,6 +399,30 @@ const getEntityInfoFn = async id => {
};
const sanTypeId = ref("");
// 跳转到数据资源库
const handleToDataLibrary = () => {
let domainStr = domainOptions.filter(item => item.value === selectedDomain.value)[0].label
let params
if (domainStr === '全部领域') {
params = {
isCnEntityOnly: true,
}
} else {
params = {
isCnEntityOnly: true,
domains: domainStr
};
}
const route = router.resolve({
path: "/dataLibrary/dataEntityList",
query: params
});
window.open(route.href, "_blank");
}
onMounted(() => {
sanTypeId.value = route.query.sanTypeId;
// 获取实体清单基本信息
......
......@@ -17,47 +17,27 @@
<div class="text">科技领域</div>
</div>
<div class="checkbox-group">
<el-checkbox
v-for="(item, index) in techFields"
:key="index"
v-model="item.checked"
:label="item.label"
@change="handleFilterChange(item, techFields, 'tech')"
/>
<el-checkbox v-for="(item, index) in techFields" :key="index" v-model="item.checked" :label="item.label"
@change="handleFilterChange(item, techFields, 'tech')" />
</div>
<div class="title">
<div class="box"></div>
<div class="text">实体类型</div>
</div>
<div class="checkbox-group">
<el-checkbox
v-for="(item, index) in entityTypes"
:key="index"
v-model="item.checked"
:label="item.label"
@change="handleFilterChange(item, entityTypes, 'type')"
/>
<el-checkbox v-for="(item, index) in entityTypes" :key="index" v-model="item.checked" :label="item.label"
@change="handleFilterChange(item, entityTypes, 'type')" />
</div>
<div class="title">
<div class="box"></div>
<div class="text">制裁时间</div>
</div>
<div class="checkbox-group">
<el-checkbox
v-for="(item, index) in sanctionTimes"
:key="index"
v-model="item.checked"
:label="item.label"
@change="handleFilterChange(item, sanctionTimes, 'time')"
/>
<el-checkbox v-for="(item, index) in sanctionTimes" :key="index" v-model="item.checked" :label="item.label"
@change="handleFilterChange(item, sanctionTimes, 'time')" />
<div v-if="sanctionTimes.find(i => i.value === 'custom' && i.checked)" class="custom-date-picker">
<el-date-picker
v-model="customDateRange"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
/>
<el-date-picker v-model="customDateRange" type="daterange" range-separator="-" start-placeholder="开始日期"
end-placeholder="结束日期" />
</div>
</div>
</div>
......@@ -96,8 +76,8 @@
<CommonPrompt :content="row.entityNameZh || row.entityName" style="flex: 1; overflow: hidden" />
</div>
</template>
</el-table-column>
<el-table-column label="涉及领域" min-width="150">
</el-table-column>
<el-table-column label="涉及领域" min-width="150">
<template #default="{ row }">
<div class="domain-cell">
<el-tag v-for="tag in row.techDomains" :key="tag" class="domain-tag" effect="plain"
......@@ -106,9 +86,9 @@
</el-tag>
</div>
</template>
</el-table-column>
<el-table-column prop="startTime" label="制裁时间" width="140" show-overflow-tooltip align="center" />
<el-table-column label="50%规则子企业" min-width="280" show-overflow-tooltip align="right">
</el-table-column>
<el-table-column prop="startTime" label="制裁时间" width="140" show-overflow-tooltip align="center" />
<el-table-column label="50%规则子企业" min-width="280" show-overflow-tooltip align="right">
<template #default="{ row }">
<div class="rule-cell" v-if="row.ruleOrgCount > 0">
<div class="rule-text" :title="row.ruleOrgList?.[0]?.orgName || ''">
......@@ -118,34 +98,29 @@
row.ruleOrgCount }}家 ></el-link>
</div>
</template>
</el-table-column>
</el-table>
</div>
<div class="tight-footer">
</el-table-column>
</el-table>
</div>
<div class="tight-footer">
<div class="total-text">共 {{ total }} 项</div>
<el-pagination :current-page="currentPage" v-model:page-size="pageSize" :total="total" layout="prev, pager, next"
prev-text="<" next-text=">" @current-change="handleCurrentChange" />
</div> -->
</div> -->
<AnalysisBox title="实体清单" :showAllBtn="false">
<template #header-btn>
<div class="stats">
<div class="dot"></div>
<div class="count-text">
<span class="highlight">{{ ruleCount.totalCount }}</span>
<span class="highlight" @click="handlToDataLibrary">{{ ruleCount.totalCount }}</span>
</div>
<div class="rule-text">
(50%规则涉及<span class="highlight">{{ ruleCount.ruleCount }}</span
>家)
(50%规则涉及<span class="highlight" @click="handlToDataLibrary1">{{ ruleCount.ruleCount }}</span>家)
</div>
</div>
</template>
<div class="right-table">
<el-table
:data="entityRows"
table-layout="fixed"
:row-class-name="tableRowClassName"
:header-cell-style="{ background: '#fff' }"
>
<el-table :data="entityRows" table-layout="fixed" :row-class-name="tableRowClassName"
:header-cell-style="{ background: '#fff' }">
<el-table-column label="实体名称" min-width="200">
<template #default="{ row }">
<div class="entity-name-cell" @click="handleCompClick(row)">
......@@ -153,56 +128,30 @@
<div v-else class="avatar-undefined">
{{ (row.entityNameZh || row.entityName)?.match(/[\u4e00-\u9fa5a-zA-Z0-9]/)?.[0] }}
</div>
<CommonPrompt
:content="row.entityNameZh || row.entityName"
style="flex: 1; overflow: hidden"
/>
<CommonPrompt :content="row.entityNameZh || row.entityName" style="flex: 1; overflow: hidden" />
</div>
</template>
</el-table-column>
<el-table-column label="涉及领域" min-width="150">
<template #default="{ row }">
<div class="domain-cell">
<el-tag
v-for="tag in row.techDomains"
:key="tag"
class="domain-tag"
effect="plain"
:disable-transitions="true"
:style="getTagStyle(tag)"
>
<el-tag v-for="tag in row.techDomains" :key="tag" class="domain-tag" effect="plain"
:disable-transitions="true" :style="getTagStyle(tag)">
{{ tag }}
</el-tag>
</div>
</template>
</el-table-column>
<el-table-column
prop="listingLocation"
label="上市地点"
width="140"
show-overflow-tooltip
align="center"
/>
<el-table-column
prop="startTime"
label="制裁时间"
width="140"
show-overflow-tooltip
align="center"
/>
<el-table-column prop="listingLocation" label="上市地点" width="140" show-overflow-tooltip align="center" />
<el-table-column prop="startTime" label="制裁时间" width="140" show-overflow-tooltip align="center" />
<el-table-column label="50%规则子企业" min-width="280" show-overflow-tooltip align="right">
<template #default="{ row }">
<div class="rule-cell" v-if="row.ruleOrgCount > 0">
<div class="rule-text" :title="row.ruleOrgList?.[0]?.orgName || ''">
{{ row.ruleOrgList?.[0]?.orgName || "" }}...等
</div>
<el-link
class="rule-link"
type="primary"
:underline="false"
@click="handleRuleClick(row)"
>{{ row.ruleOrgCount }}家 ></el-link
>
<el-link class="rule-link" type="primary" :underline="false" @click="handleRuleClick(row)">{{
row.ruleOrgCount }}家 ></el-link>
</div>
</template>
</el-table-column>
......@@ -210,26 +159,15 @@
</div>
<div class="tight-footer">
<div class="total-text">共 {{ total }} 项</div>
<el-pagination
:current-page="currentPage"
v-model:page-size="pageSize"
:total="total"
layout="prev, pager, next"
prev-text="<"
next-text=">"
@current-change="handleCurrentChange"
/>
<el-pagination :current-page="currentPage" v-model:page-size="pageSize" :total="total"
layout="prev, pager, next" prev-text="<" next-text=">" @current-change="handleCurrentChange" />
</div>
</AnalysisBox>
</div>
</div>
</div>
<RuleSubsidiaryDialog
v-model="ruleDialogVisible"
:company-name="currentRuleCompany"
:total-count="currentRuleCount"
:data-list="currentRuleList"
/>
<RuleSubsidiaryDialog v-model="ruleDialogVisible" :company-name="currentRuleCompany" :total-count="currentRuleCount"
:data-list="currentRuleList" />
</div>
</template>
......@@ -414,7 +352,7 @@ const getExportControlListApi = async () => {
if (abortController) {
try {
abortController.abort();
} catch {}
} catch { }
}
abortController = new AbortController();
isFetching.value = true;
......@@ -526,6 +464,30 @@ watch(customDateRange, () => {
getExportControlListApi();
}
});
// 跳转到数据资源库
const handlToDataLibrary = () => {
const params = {
isCnEntityOnly: true,
};
const route = router.resolve({
path: "/dataLibrary/dataEntityList",
query: params
});
window.open(route.href, "_blank");
}
const handlToDataLibrary1 = () => {
const params = {
isCnEntityOnly: true,
isHalfRule: true,
};
const route = router.resolve({
path: "/dataLibrary/dataEntityList",
query: params
});
window.open(route.href, "_blank");
}
</script>
<style scoped lang="scss">
......@@ -577,6 +539,7 @@ watch(customDateRange, () => {
width: 160px;
height: 32px;
}
:deep(.el-checkbox__label) {
font-size: 14px;
color: rgb(95, 101, 108);
......@@ -729,6 +692,7 @@ watch(customDateRange, () => {
.highlight {
color: #cd4246;
margin: 0 4px;
}
}
......@@ -1001,6 +965,11 @@ watch(customDateRange, () => {
.highlight {
color: #cd4246;
margin: 0 4px;
cursor: pointer;
&:hover {
text-decoration: underline;
}
}
}
......@@ -1011,6 +980,11 @@ watch(customDateRange, () => {
.highlight {
color: #cd4246;
cursor: pointer;
&:hover {
text-decoration: underline;
}
}
}
}
......
<template>
<div class="data-statistics">
<div class="nav">
<div class="nav-item">
<div class="nav-item" @click="handleToDataLibrary">
<div class="item-position"></div>
<div class="content">
<div class="info">
......@@ -13,7 +13,7 @@
</div>
</div>
</div>
<div class="nav-item">
<div class="nav-item" @click="handleToDataLibrary1">
<div class="item-position"></div>
<div class="content">
<div class="info">
......@@ -26,7 +26,7 @@
</div>
</div>
</div>
<div class="nav-item">
<div class="nav-item" @click="handleToDataLibrary2">
<div class="item-position"></div>
<div class="content">
<div class="info">
......@@ -351,6 +351,8 @@ const getTotalCount = async () => {
if (!sanRecordId.value) return;
try {
const res = await getSingleSanctionTotalCount(route.query.sanTypeId, sanRecordId.value);
console.log('统计', res);
if (res.code === 200) {
totalCount.value = res.data || {};
}
......@@ -882,7 +884,6 @@ const handlePieChartClick1 = (val) => {
// 制裁实体国家地区分布情况
const handleClickRankChart = (item) => {
// console.log('item', item);
const params = {
selectedCountryId: item.id,
selectedDate: JSON.stringify([route.query.date, route.query.date])
......@@ -908,6 +909,43 @@ const handleRankChartClick = (item) => {
window.open(curRoute.href, "_blank");
}
// 跳转到数据资源库
const handleToDataLibrary = () => {
const dateStr = route.query.date ? route.query.date : ''
const curRoute = router.resolve({
path: "/dataLibrary/dataEntityList",
query: {
isCnEntityOnly: true,
selectedDate: JSON.stringify([dateStr, dateStr])
}
});
window.open(curRoute.href, "_blank");
}
const handleToDataLibrary1 = () => {
const dateStr = route.query.date ? route.query.date : ''
const curRoute = router.resolve({
path: "/dataLibrary/dataEntityList",
query: {
isCnEntityOnly: true,
isHalfRule: true,
selectedDate: JSON.stringify([dateStr, dateStr])
}
});
window.open(curRoute.href, "_blank");
}
const handleToDataLibrary2 = () => {
const dateStr = route.query.date ? route.query.date : ''
const curRoute = router.resolve({
path: "/dataLibrary/dataEntityList",
query: {
selectedDate: JSON.stringify([dateStr, dateStr])
}
});
window.open(curRoute.href, "_blank");
}
onMounted(() => {
// 获取路由参数id
......@@ -957,6 +995,11 @@ onMounted(() => {
background-color: #fff;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
position: relative;
cursor: pointer;
&:hover {
background: var(--color-primary-2);
}
.item-position {
position: absolute;
......
......@@ -45,17 +45,15 @@
<div class="left-top-content">
<div class="content-title">制裁实体分布:</div>
<div class="distribution-list">
<div class="list-item" v-for="(item, index) in entityDistribution" :key="index">
<div class="list-item" v-for="(item, index) in entityDistribution" :key="index"
@click="handleToDataLibrary(item)">
<img :src="item.imageUrl || flag" alt="" class="flag" />
<div class="country-name">{{ item.name }}</div>
<div class="progress-bar-container">
<div
class="progress-bar"
:style="{
<div class="progress-bar" :style="{
width: item.width,
background: item.gradient
}"
></div>
}"></div>
</div>
<div class="count" :class="{ highlight: index === 0 }">{{ item.count }}</div>
</div>
......@@ -98,25 +96,13 @@
</div>
<div class="filter-right">
<el-checkbox v-model="onlyChina" label="只看中国实体" />
<el-select
v-model="filterField"
placeholder="选择领域"
style="width: 150px; margin: 0 12px 0 16px"
>
<el-select v-model="filterField" placeholder="选择领域" style="width: 150px; margin: 0 12px 0 16px">
<!-- <el-option label="全部领域" value="" /> -->
<el-option
v-for="item in domainOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
<el-option v-for="item in domainOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<el-input
v-model="searchKeyword"
placeholder="搜索实体"
<el-input v-model="searchKeyword" placeholder="搜索实体"
style="width: 150px; border: 1px solid rgba(170, 173, 177, 0.4); border-radius: 5px"
:suffix-icon="Search"
/>
:suffix-icon="Search" />
</div>
</div>
<div class="stats-row">
......@@ -131,21 +117,14 @@
<div class="stats-info">
<div class="stat-item">
<span class="dot red"></span>
<span class="text"
>新增 <span class="num red">{{ addCount }}</span> 家 (50%规则涉及<span class="num red">{{
<span class="text">新增 <span class="num red">{{ addCount }}</span> 家 (50%规则涉及<span class="num red">{{
addRuleCount
}}</span
>家)</span
>
}}</span>家)</span>
</div>
<div class="stat-item">
<span class="dot green"></span>
<span class="text"
>移除 <span class="num green">{{ removeCount }}</span> 家 (50%规则涉及<span
class="num green"
>{{ removeRuleCount }}</span
>家)</span
>
<span class="text">移除 <span class="num green">{{ removeCount }}</span> 家 (50%规则涉及<span
class="num green">{{ removeRuleCount }}</span>家)</span>
</div>
</div>
</div>
......@@ -177,11 +156,7 @@
>{{ item }}</span
> -->
<div class="domain-box">
<AreaTag
v-for="(domain, index) in scope.row.fields"
:key="index"
:tagName="domain"
/>
<AreaTag v-for="(domain, index) in scope.row.fields" :key="index" :tagName="domain" />
</div>
</template>
</el-table-column>
......@@ -190,11 +165,8 @@
<el-table-column prop="revenue" label="营收(亿元)" width="110" align="center" />
<el-table-column label="50%规则子企业" width="180" align="center">
<template #default="scope">
<span
v-if="scope.row.subsidiaryCount"
class="subsidiary-link"
@click="handleSubsidiaryClick(scope.row)"
>
<span v-if="scope.row.subsidiaryCount" class="subsidiary-link"
@click="handleSubsidiaryClick(scope.row)">
{{ scope.row.subsidiaryText }}
<span class="blue-text">{{ scope.row.subsidiaryCount }}家 ></span>
</span>
......@@ -212,12 +184,8 @@
</div>
</div>
<!-- 50%规则子企业弹框 -->
<RuleSubsidiaryDialog
v-model="subsidiaryDialogVisible"
:company-name="currentSubsidiaryCompanyName"
:total-count="currentSubsidiaryCount"
:data-list="currentSubsidiaryList"
/>
<RuleSubsidiaryDialog v-model="subsidiaryDialogVisible" :company-name="currentSubsidiaryCompanyName"
:total-count="currentSubsidiaryCount" :data-list="currentSubsidiaryList" />
</div>
</template>
......@@ -555,6 +523,26 @@ const entityDistribution = ref([
}
]);
const sanTypeId = ref("");
// 跳转到数据资源库
const handleToDataLibrary = (item) => {
console.log('item', item);
const dateStr = formattedData.value.postDate.replace(/(\d{4})(\d{1,2})(\d{1,2})日/, (_, y, m, d) =>
`${y}-${m.padStart(2, '0')}-${d.padStart(2, '0')}`
);
const route = router.resolve({
path: "/dataLibrary/dataEntityList",
query:{
selectedDate: JSON.stringify([dateStr,dateStr]),
selectedCountryId: item.id
}
});
window.open(route.href, "_blank");
}
onMounted(() => {
// 获取路由参数中的sanTypeId
console.log("route.query.sanTypeId --:", route.query.sanTypeId);
......@@ -696,6 +684,11 @@ onMounted(() => {
display: flex;
align-items: center;
height: 24px;
cursor: pointer;
&:hover {
background: var(--color-primary-2);
}
.flag {
width: 24px;
......
......@@ -247,12 +247,15 @@ const handlePageChange = async newPage => {
// ========== 选择某项 ==========
const selectSanction = async item => {
// console.log('item', item);
selectedSanctionId.value = item.id;
router.replace({
path: window.location.pathname,
query: {
id: item.id,
sanTypeId: item.sanTypeId
sanTypeId: item.sanTypeId,
date: item.postDate
}
});
sanctionModalVisible.value = false;
......@@ -260,7 +263,7 @@ const selectSanction = async item => {
// 根据最新URL参数刷新当前页面
window.sessionStorage.setItem("curTabName", item.postDate + " 《实体清单新增条目》");
window.open(`${window.location.pathname}?id=${item.id}&sanTypeId=${item.sanTypeId}`, "_self");
window.open(`${window.location.pathname}?id=${item.id}&sanTypeId=${item.sanTypeId}&date=${item.postDate}`, "_self");
};
// ========== 关闭弹窗时重置 ==========
......
......@@ -7,7 +7,7 @@
<div class="sub-title">{{ subtitle }}</div>
</div>
<div class="description">{{ description }}</div>
<div v-if="quantity > 0" class="quantity" :style="{ color: color }">
<div v-if="quantity > 0" class="quantity" :style="{ color: color }" @click.stop="handleClickNum(title)">
{{ quantity }}{{ unit || "个" }}
<div class="quantity-title-des" v-if="desMap[title]">
<img class="info-icon" :src="infoIcon" alt="" />
......@@ -20,6 +20,25 @@
<script setup>
import infoIcon from "../assets/icons/info-icon.png";
import { useRouter } from "vue-router";
const router = useRouter()
const handleClickNum = (item) => {
if (item === '特别指定国民清单') {
const route = router.resolve({
path: "/dataLibrary/sDNList",
// query: {
// isCnEntityOnly: true
// }
});
window.open(route.href, "_blank");
} else if (item === '涉军企业清单') {
const route = router.resolve({
path: "/dataLibrary/mREList",
});
window.open(route.href, "_blank");
}
}
defineProps({
title: {
type: String,
......
......@@ -116,7 +116,7 @@
</div>
</div>
</div>
<div class="box1-absolute">
<div class="box1-absolute" @click="handleToDataLibrary(item)">
<div class="box1-absolute-des">
<el-icon>
<Warning color="rgba(206, 79, 81, 1)" />
......@@ -195,7 +195,12 @@
<div class="box3">
<div class="box3-content">
<div class="box3-content-title">特别指定国民清单(SDN)发布频度</div>
<el-table :data="entityListReleaseFreq" stripe style="width: 100%">
<el-table
:data="entityListReleaseFreq"
stripe
style="width: 100%"
@row-click="handleEntityRowClick"
>
<el-table-column prop="year" label="年份" width="200" />
<el-table-column label="发布次数" width="300">
<template #default="scope">
......@@ -241,6 +246,7 @@
:data="commerceControlListReleaseFreq"
stripe
style="width: 100%; margin-bottom: auto"
@row-click="handleCommercialRowClick"
>
<el-table-column prop="year" label="年份" width="200" />
<el-table-column label="发布次数" width="300">
......@@ -320,7 +326,12 @@
<el-checkbox v-model="domainChecked" label="50%规则" size="large" />
</template>
<template #default>
<EChart :option="radarOption" autoresize :style="{ height: '420px' }" />
<EChart
:option="radarOption"
autoresize
:style="{ height: '420px' }"
@chart-click="handleRadarChartClick"
/>
<div class="data-origin-box">
<div class="data-origin-icon">
<img :src="tipsIcon" alt="" />
......@@ -347,7 +358,12 @@
</div>
</template>
<template #default>
<EChart :option="trendOption" autoresize :style="{ height: '420px' }" />
<EChart
:option="trendOption"
autoresize
:style="{ height: '420px' }"
@chart-click="handleMultiBarChartClick"
/>
<div class="data-origin-box">
<div class="data-origin-icon">
<img :src="tipsIcon" alt="" />
......@@ -1708,6 +1724,80 @@ const handleSearch = () => {
window.open(curRoute.href, "_blank");
};
// 点击特别指定国民清单(SDN)发布频度
const handleEntityRowClick = row => {
// console.log("row", row);
const params = {
// domains: row.tags[0],
selectedDate: JSON.stringify([row.year + "-01-01", row.year + "-12-31"])
};
const route = router.resolve({
path: "/dataLibrary/sDNListEvent",
query: params
});
window.open(route.href, "_blank");
};
// 点击中国军事工业复合体企业清单(CMIC)更新频度
const handleCommercialRowClick = row => {
console.log("row", row);
const params = {
selectedDate: JSON.stringify([row.year + "-01-01", row.year + "-12-31"])
};
const route = router.resolve({
path: "/dataLibrary/mREListEvent",
query: params
});
window.open(route.href, "_blank");
};
// 点击制裁领域分布
const handleRadarChartClick = value => {
const params = {
isHalfRule: domainChecked.value
};
let route;
if (domainChecked.value) {
route = router.resolve({
path: "/dataLibrary/sDNList",
query: params
});
} else {
route = router.resolve({
path: "/dataLibrary/sDNList"
});
}
window.open(route.href, "_blank");
};
// 点击制裁清单数量增长趋势
const handleMultiBarChartClick = val => {
const params = {
isHalfRule: trendChecked.value,
domains: val.seriesName,
isCnEntityOnly: true,
selectedDate: JSON.stringify([val.name + "-01-01", val.name + "-12-31"])
};
const route = router.resolve({
path: selectedEntityId.value === 2 ? "/dataLibrary/sDNList" : "/dataLibrary/mREList",
query: params
});
window.open(route.href, "_blank");
};
// 跳转到数据资源库
const handleToDataLibrary = item => {
const route = router.resolve({
path: "/dataLibrary/sDNList",
query: {
isCnEntityOnly: true,
selectedDate: JSON.stringify([item.postDate, item.postDate])
}
});
window.open(route.href, "_blank");
};
onMounted(async () => {
console.log("finance 页面 mounted");
try {
......
......@@ -973,7 +973,7 @@ export const getMultipleBarChart_m = object => {
const option = {
tooltip: {
trigger: "axis",
trigger: "item",
axisPointer: {
type: "shadow"
}
......
<template>
<div class="data-list">
<div class="data-item" v-for="(item, index) in props.list" :key="index">
<div class="item-head">
<div class="item-name">{{ `(${onNumToChinese(Number(index)+1)}). ${item.title}` }}</div>
<div class="button-box" @click="onNavigateTo()">
<div class="button-icon">
<img src="../assets/icons/open.png" alt="" />
</div>
<div class="button-text">跳转原文</div>
</div>
</div>
<Level2List :list="item.data"></Level2List>
</div>
</div>
</template>
<script setup lang="ts" name="Level2List">
import router from "@/router";
import { useRoute } from "vue-router";
import { onNumToChinese } from "@/views/marketAccessRestrictions/utils/index"
import Level2List from "@/views/marketAccessRestrictions/com/Level2List.vue";
const route = useRoute();
const props = defineProps({
list: {
type: Array as any,
default: () => ([])
},
})
const onNavigateTo = () => {
const page = router.resolve({
name: "MarketSingleReportOriginal",
query: { ...route.query }
});
window.open(page.href, "_blank");
}
</script>
<style scoped lang="scss">
.data-list {
margin-bottom: 16px;
border-top: 1px solid rgba(234, 236, 238, 1);
.data-item {
.item-head {
padding: 0 20px;
height: 48px;
border-bottom: 1px solid rgba(234, 236, 238, 1);
background: rgba(247, 248, 249, 1);
display: flex;
align-items: center;
.item-name {
width: 20px;
flex: auto;
font-family: Source Han Sans CN;
font-size: 18px;
font-weight: bold;
line-height: 30px;
color: var(--text-primary-80-color);
}
.button-box {
display: flex;
align-items: center;
margin-left: 50px;
cursor: pointer;
.button-icon {
width: 16px;
height: 16px;
font-size: 0;
margin-right: 4px;
img {
width: 100%;
height: 100%;
}
}
.button-text {
color: var(--color-primary-100);
font-family: Microsoft YaHei;
font-size: 12px;
font-weight: 400;
line-height: 12px;
}
}
}
}
}
</style>
\ No newline at end of file
<template>
<div class="view-box">
<div class="item-info" v-for="(text, num) in props.list" :key="num">
<div class="item-num">{{ Number(num) + 1 }}.</div>
<div class="text-align-justify">{{ text }}</div>
</div>
</div>
</template>
<script setup lang="ts" name="Level2List">
const props = defineProps({
list: {
type: Array as any,
default: () => ([])
}
})
</script>
<style scoped lang="scss">
.view-box {
.item-info {
padding: 12px 20px 12px 50px;
color: rgba(59, 65, 75, 1);
font-family: Source Han Sans CN;
font-size: 16px;
font-weight: 400;
line-height: 30px;
letter-spacing: 0px;
border-bottom: 1px solid rgba(234, 236, 238, 1);
position: relative;
.item-num {
position: absolute;
left: 26px;
top: 12px;
}
}
}
</style>
\ No newline at end of file
......@@ -2,29 +2,15 @@
<AnalysisBox :title="title" :showAllBtn="false" height="auto">
<el-empty v-if="!props.listData?.length" description="暂无数据" :image-size="200" />
<div v-else class="box-main">
<div class="data-list">
<div class="data-item" v-for="(item, index) in props.listData" :key="index">
<div class="item-head">
<div class="item-name">{{ item.title }}</div>
<div class="button-box">
<div class="button-icon">
<img src="../assets/icons/open.png" alt="" />
</div>
<div class="button-text">跳转原文</div>
</div>
</div>
<div class="item-down">
<div class="item-text" v-for="(text, num) in item.data" :key="num">{{ text }}</div>
</div>
</div>
</div>
<AiTips :tips="tips"></AiTips>
<Level1List :list="props.listData"></Level1List>
<!-- <AiTips :tips="tips"></AiTips> -->
</div>
</AnalysisBox>
</template>
<script setup lang="ts" name="SurveyConclusion">
import AiTips from "@/views/marketAccessRestrictions/com/AiTips.vue";
import Level1List from "@/views/marketAccessRestrictions/com/Level1List.vue";
const props = defineProps({
listData: {
......@@ -46,62 +32,5 @@ const props = defineProps({
<style scoped lang="scss">
.box-main {
padding: 0 22px 20px;
.data-list {
margin-bottom: 16px;
border-top: 1px solid rgba(234, 236, 238, 1);
.data-item {
.item-head {
padding: 0 20px;
height: 48px;
border-bottom: 1px solid rgba(234, 236, 238, 1);
background: rgba(247, 248, 249, 1);
display: flex;
align-items: center;
.item-name {
width: 20px;
flex: auto;
font-family: Source Han Sans CN;
font-size: 18px;
font-weight: bold;
line-height: 30px;
color: var(--text-primary-80-color);
}
.button-box {
display: flex;
align-items: center;
margin-left: 50px;
.button-icon {
width: 16px;
height: 16px;
font-size: 0;
margin-right: 4px;
img {
width: 100%;
height: 100%;
}
}
.button-text {
color: var(--color-primary-100);
font-family: Microsoft YaHei;
font-size: 12px;
font-weight: 400;
line-height: 12px;
}
}
}
.item-text {
letter-spacing: 1px;
padding: 12px 20px 12px 40px;
color: rgba(59, 65, 75, 1);
font-family: Source Han Sans CN;
font-size: 16px;
font-weight: 400;
line-height: 30px;
letter-spacing: 0px;
text-align: justify;
border-bottom: 1px solid rgba(234, 236, 238, 1);
}
}
}
}
</style>
\ No newline at end of file
......@@ -2,19 +2,19 @@
<div class="box-text-box">
<div class="box-text-item">
<div class="box-text-left">{{ "启动时间:" }}</div>
<div class="box-text-right one-line-ellipsis">{{ props.baseInfo.searchnum }}</div>
<div class="box-text-right one-line-ellipsis">{{ props.baseInfo.progressdate }}</div>
</div>
<div class="box-text-item">
<div class="box-text-left">{{ "调查概括:" }}</div>
<div class="box-text-right two-line-ellipsis">{{ props.baseInfo.product }}</div>
<div class="box-text-right two-line-ellipsis">{{ props.baseInfo.investSummary }}</div>
</div>
<div class="box-text-item">
<div class="box-text-left">{{ "调查阶段:" }}</div>
<div class="box-text-right one-line-ellipsis">{{ props.baseInfo.plaintiff }}</div>
<div class="box-text-right one-line-ellipsis">{{ props.baseInfo.investStage }}</div>
</div>
<div class="box-text-item">
<div class="box-text-left">{{ "调查范围:" }}</div>
<div class="box-text-right five-line-ellipsis">{{ props.baseInfo.defendant }}</div>
<div class="box-text-right five-line-ellipsis">{{ props.baseInfo.investScope }}</div>
</div>
</div>
</template>
......
......@@ -2,26 +2,25 @@
<div class="box-blue-box">
<div class="box-blue-name">
<div class="box-blue-time">{{ props.baseInfo.progressdate }}</div>
<div class="box-blue-time">{{ props.baseInfo.progressresult }}</div>
</div>
<div class="box-blue-text one-line-ellipsis">{{ props.baseInfo.progressdetails }}</div>
</div>
<div class="box-text-box">
<div class="box-text-item">
<div class="box-text-left">{{ "启动时间:" }}</div>
<div class="box-text-right one-line-ellipsis">{{ props.baseInfo.searchnum }}</div>
<div class="box-text-right one-line-ellipsis">{{ props.baseInfo.investDate }}</div>
</div>
<div class="box-text-item">
<div class="box-text-left">{{ "调查对象:" }}</div>
<div class="box-text-right one-line-ellipsis">{{ props.baseInfo.product }}</div>
<div class="box-text-right one-line-ellipsis">{{ props.baseInfo.investSubject }}</div>
</div>
<div class="box-text-item">
<div class="box-text-left">{{ "调查状态:" }}</div>
<div class="box-text-right one-line-ellipsis">{{ props.baseInfo.plaintiff }}</div>
<div class="box-text-right one-line-ellipsis">{{ props.baseInfo.investStatus }}</div>
</div>
<div class="box-text-item">
<div class="box-text-left">{{ "请愿方:" }}</div>
<div class="box-text-right three-line-ellipsis">{{ props.baseInfo.product }}</div>
<div class="box-text-right three-line-ellipsis">{{ props.baseInfo.petitioner }}</div>
</div>
</div>
</template>
......
import { symbolCircle } from "d3";
import * as echarts from "echarts";
const getBarChart = (nameList, valueList) => {
......@@ -15,27 +14,45 @@ const getBarChart = (nameList, valueList) => {
},
yAxis: {
type: 'value',
splitLine: {
show: false
name: "项",
nameLocation: 'end',
nameGap: 12,
nameTextStyle: {
color: '#666',
fontSize: 14,
fontWeight: 400,
padding: [0, 0, 6, -26]
},
show: false
axisLabel: {
formatter: '{value}',
color: '#666',
fontSize: 14,
fontWeight: 400
},
xAxis: {
type: 'category',
data: nameList.map(item => {
return item.name
}),
splitLine: {
show: false
show: true,
lineStyle: {
color: '#e7f3ff',
type: 'dashed',
}
},
axisTick: {
show: false
},
xAxis: {
type: 'category',
data: nameList.map(item => item.name),
axisLine: {
show: false
show: true,
lineStyle: {
color: '#e7f3ff',
},
},
axisLabel: {
show: true
show: true,
textStyle: {
color: 'rgba(95, 101, 108, 1)',
fontFamily: 'Microsoft YaHei',
fontsize: 14,
}
}
},
series: [{
......@@ -57,8 +74,7 @@ const getBarChart = (nameList, valueList) => {
barWidth: 20,
markPoint: {
symbol: 'circle',
symbolSize: 20,
symbolSize: 0,
data: (function () {
const data = [];
nameList.forEach((item, index) => {
......@@ -67,9 +83,7 @@ const getBarChart = (nameList, valueList) => {
xAxis: index,
yAxis: valueList[index],
symbol: `image://${item.img}`,
// symbolSize: [20, 20],
symbolSize: 20,
// symbolOffset: [0, 20],
symbolCircle: 20,
itemStyle: {
borderRadius: '50%',
......
......@@ -11,22 +11,24 @@
<el-option label="调查中" value="1" />
<el-option label="调查结束" value="0" />
</el-select>
<el-select v-model="filterParty" placeholder="全部原告/被告" class="filter-select" clearable>
<!-- <el-select v-model="filterParty" placeholder="全部原告/被告" class="filter-select" clearable>
<el-option label="全部原告/被告" value="" />
</el-select>
<el-select v-model="filterReason" placeholder="全部原因" class="filter-select" clearable>
<el-option label="全部原因" value="" />
</el-select>
</el-select> -->
</div>
</div>
<div class="select-box">
<div class="paixu-btn" @click="handleSwithSort">
<div class="text">{{ "发布时间" }}</div>
<div class="icon2">
<img v-if="isSort" src="@/assets/icons/shengxu2.png" alt="" />
<img v-else src="@/assets/icons/jiangxu2.png" alt="" />
</div>
<el-select v-model="isSort" placeholder="发布时间" style="width: 166px">
<template #prefix>
<div style="display: flex; align-items: center; height: 100%">
<img src="@/assets/icons/jiangxu1.png" style="width: 14px; height: 14px" />
</div>
</template>
<el-option label="按发布时间降序" value="desc" />
<el-option label="按发布时间升序" value="asc" />
</el-select>
</div>
</div>
<div class="wrapper-main">
......@@ -95,11 +97,7 @@ const searchText = ref("");
const filterStage = ref("");
const filterParty = ref("");
const filterReason = ref("");
const isSort = ref(false); // false 降序
const handleSwithSort = () => {
isSort.value = !isSort.value;
};
const isSort = ref('desc'); // 降序
// 科技领域过滤
const surveyAreaList = ref([]);
......@@ -166,20 +164,17 @@ const handleFetchSurveyList = async () => {
publishYear: checkedYearList.value.join(',') || null,
Area: checkedAreaList.value.join(',') || null,
caseStatus: filterStage.value,
keywords: searchText.value,
keywords: searchText.value || null,
sortField: "date",
sortOrder: isSort.value ? "asc" : "desc"
sortOrder: isSort.value
};
const res = await getSurveyList(params);
if (res.code === 200 && res.data) {
surveyInfoList.value = res.data.content;
totalDiscussNum.value = res.data.totalElements || 0;
}
} catch (error) {
console.error("获取调查列表失败", error);
} finally {
} catch (error) {}
listLoading.value = false;
}
};
const handleCurrentChange = val => {
......@@ -241,30 +236,6 @@ onMounted(async () => {
}
}
}
.select-box {
.paixu-btn {
display: flex;
align-items: center;
gap: 8px;
height: 32px;
border: 1px solid #e6e7e8;
border-radius: 4px;
background: #fff;
cursor: pointer;
padding: 0 12px;
.text {
font-size: 14px;
color: #5f656c;
}
.icon2 {
width: 10px;
img {
width: 100%;
}
}
}
}
}
.wrapper-main {
......@@ -335,18 +306,26 @@ onMounted(async () => {
height: 48px;
display: flex;
align-items: center;
padding: 0 20px;
.icon {
width: 22px;
height: 18px;
margin-left: 19px;
img {
width: 100%;
height: 100%;
}
}
.title {
height: 26px;
margin-left: 12px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-style: Bold;
font-size: 20px;
font-weight: 700;
color: var(--color-main-active);
line-height: 26px;
letter-spacing: 0px;
text-align: left;
}
}
......
<template>
<div class="case-wrapper">
<div class="wrapper-header">
<div class="header-filters">
<div class="search-box">
<el-input v-model="searchText" style="width: 360px; height: 32px" placeholder="搜索调查案件" @keyup.enter="handleSearch" :suffix-icon="Search"></el-input>
</div>
<div class="select-box">
<div class="paixu-btn" @click="handleSwithSort">
<div class="icon1">
<img v-if="isSort" src="@/assets/icons/shengxu1.png" alt="" />
<img v-else src="@/assets/icons/jiangxu1.png" alt="" />
</div>
<div class="text">{{ "发布时间" }}</div>
<div class="icon2">
<img v-if="isSort" src="@/assets/icons/shengxu2.png" alt="" />
<img v-else src="@/assets/icons/jiangxu2.png" alt="" />
</div>
<div class="select-box">
<el-select v-model="isSort" placeholder="发布时间" style="width: 166px">
<template #prefix>
<div style="display: flex; align-items: center; height: 100%">
<img src="@/assets/icons/jiangxu1.png" style="width: 14px; height: 14px" />
</div>
</template>
<el-option label="按发布时间降序" value="desc" />
<el-option label="按发布时间升序" value="asc" />
</el-select>
</div>
</div>
<div class="wrapper-main">
......@@ -54,7 +54,7 @@
</div>
<SurveyHistory v-loading="listLoading" :surveyList="surveyInfoList"></SurveyHistory>
<div class="right-footer">
<div class="footer-left">{{ `共 ${totalDiscussNum}` }}</div>
<div class="footer-left">{{ `共${totalDiscussNum}项调查` }}</div>
<div class="footer-right">
<el-pagination @current-change="handleCurrentChange" :pageSize="pageSize" :current-page="currentPage" background layout="prev, pager, next" :total="totalDiscussNum" />
</div>
......@@ -70,10 +70,8 @@ import { Search } from "@element-plus/icons-vue";
import { getSearchAllArea, getSearchAllYear, getSurveyList } from "@/api/marketAccessRestrictions";
import SurveyHistory from "@/views/marketAccessRestrictions/com/SurveyHistory.vue"
const isSort = ref(true); // true 升序 false 倒序
const handleSwithSort = () => {
isSort.value = !isSort.value;
};
const searchText = ref(''); // 搜索文本
const isSort = ref('desc'); // 降序
// 科技领域过滤
const surveyAreaList = ref([]);
......@@ -139,20 +137,17 @@ const handleFetchSurveyList = async () => {
sortCode: "301",
publishYear: checkedYearList.value.join(',') || null,
Area: checkedAreaList.value.join(',') || null,
// keywords: searchText.value,
keywords: searchText.value || null,
sortField: "date",
sortOrder: isSort.value ? "asc" : "desc"
sortOrder: isSort.value
};
const res = await getSurveyList(params);
if (res.code === 200 && res.data) {
surveyInfoList.value = res.data.content;
totalDiscussNum.value = res.data.totalElements || 0;
}
} catch (error) {
console.error("获取调查列表失败", error);
} finally {
} catch (error) {}
listLoading.value = false;
}
};
const handleCurrentChange = (val) => {
......@@ -190,56 +185,24 @@ onMounted(async () => {
display: flex;
margin-bottom: 16px;
justify-content: space-between;
.header-filters {
display: flex;
gap: 16px;
align-items: center;
.search-box {
background-color: #fff;
border: 1px solid rgba(234, 236, 238, 1);
border-radius: 4px;
}
.select-box {
height: 32px;
box-sizing: border-box;
.paixu-btn {
.dropdown-filters {
display: flex;
width: 120px;
height: 32px;
box-sizing: border-box;
border: 1px solid rgba(230, 231, 232, 1);
border-radius: 4px;
background: rgba(255, 255, 255, 1);
&:hover {
background: var(--color-bg-hover);
}
cursor: pointer;
.icon1 {
width: 11px;
height: 14px;
margin-top: 10px;
margin-left: 9px;
img {
width: 100%;
height: 100%;
}
}
.text {
height: 19px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 18px;
letter-spacing: 0px;
text-align: left;
margin-top: 7px;
margin-left: 9px;
}
.icon2 {
width: 10px;
height: 5px;
margin-top: 5px;
margin-left: 13px;
img {
width: 100%;
height: 100%;
gap: 12px;
.filter-select {
width: 140px;
:deep(.el-input__wrapper) {
background-color: #fff;
}
}
}
......@@ -324,7 +287,7 @@ onMounted(async () => {
}
.title {
height: 26px;
margin-left: 19px;
margin-left: 12px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-style: Bold;
......
......@@ -11,12 +11,12 @@
<el-option label="调查中" value="1" />
<el-option label="调查结束" value="0" />
</el-select>
<el-select v-model="filterParty" placeholder="全部原告/被告" class="filter-select" clearable>
<!-- <el-select v-model="filterParty" placeholder="全部原告/被告" class="filter-select" clearable>
<el-option label="全部原告/被告" value="" />
</el-select>
<el-select v-model="filterReason" placeholder="全部原因" class="filter-select" clearable>
<el-option label="全部原因" value="" />
</el-select>
</el-select> -->
</div>
</div>
<div class="select-box">
......@@ -26,7 +26,8 @@
<img src="@/assets/icons/jiangxu1.png" style="width: 14px; height: 14px" />
</div>
</template>
<el-option v-for="item in releaseTimeList" :key="item.value" :label="item.label" :value="item.value" />
<el-option label="按发布时间降序" value="desc" />
<el-option label="按发布时间升序" value="asc" />
</el-select>
</div>
</div>
......@@ -99,19 +100,7 @@ const searchText = ref("");
const filterStage = ref("");
const filterParty = ref("");
const filterReason = ref("");
const isSort = ref(false); // false 降序
const releaseTimeList = ref([
{
label: "按发布时间倒序",
value: false
},
{
label: "按发布时间升序",
value: true
}
]);
const isSort = ref('desc'); // 降序
// 科技领域过滤
const surveyAreaList = ref([]);
......@@ -203,18 +192,15 @@ const handleFetchSurveyList = async () => {
caseStatus: filterStage.value || null,
keywords: searchText.value || null,
sortField: "date",
sortOrder: isSort.value ? "asc" : "desc"
sortOrder: isSort.value
};
const res = await getSurveyList(params);
if (res.code === 200) {
surveyInfoList.value = res.data?.content || [];
totalDiscussNum.value = res.data?.totalElements || 0;
}
} catch (error) {
console.error("获取调查列表失败", error);
} finally {
} catch (error) {}
listLoading.value = false;
}
};
const handleCurrentChange = val => {
......@@ -278,33 +264,6 @@ onMounted(async () => {
}
}
}
.select-box {
.paixu-btn {
display: flex;
align-items: center;
gap: 8px;
height: 32px;
border: 1px solid #e6e7e8;
border-radius: 4px;
background: #fff;
cursor: pointer;
padding: 0 12px;
.text {
font-size: 14px;
color: #5f656c;
}
.icon2 {
width: 10px;
img {
width: 100%;
}
}
}
}
}
.wrapper-main {
......
......@@ -19,8 +19,7 @@
<div class="page-tabs">
<div :class="['tab-item', {'tab-active': activeName==item.name}]" v-for="(item, index) in tabList" :key="index" @click="handleClickBtn(item)">
<div class="icon">
<img :src="item.activeIcon" alt="" v-if="activeName==item.name" />
<img :src="item.icon" alt="" v-else />
<img :src="activeName==item.name ? item.activeIcon : item.icon" alt="" />
</div>
<div class="text" :class="{ textActive: activeName==item.name }">
{{ item.name }}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论