提交 32381f85 authored 作者: 张烨's avatar 张烨

Merge remote-tracking branch 'origin/pre' into zy-dev

流水线 #395 已通过 于阶段
in 1 分 43 秒
const baseUrl = `http://8.140.26.4:9085` const baseUrl = `http://8.140.26.4:9085`
const outImgbaseUrl = `http://8.140.26.4:10017/out/img` // 写报图片URL
\ No newline at end of file
...@@ -16,7 +16,7 @@ export function getBillIndustry(params) { ...@@ -16,7 +16,7 @@ export function getBillIndustry(params) {
return request({ return request({
method: 'GET', method: 'GET',
url: `/api/BillOverview/billIndustry/${params.year}`, url: `/api/BillOverview/billIndustry/${params.year}`,
params: { status: params.status } params: { stageName: params.stageName }
}) })
} }
......
...@@ -12,6 +12,7 @@ export function search(data) { ...@@ -12,6 +12,7 @@ export function search(data) {
}) })
} }
// 智库列表
export function getThinkTankList() { export function getThinkTankList() {
return request({ return request({
method: 'GET', method: 'GET',
...@@ -19,9 +20,50 @@ export function getThinkTankList() { ...@@ -19,9 +20,50 @@ export function getThinkTankList() {
}) })
} }
// 立法阶段
export function getStatusList() { export function getStatusList() {
return request({ return request({
method: 'GET', method: 'GET',
url: `/temporarySearch/search-info/dBillStage`, url: `/temporarySearch/search-info/dBillStage`,
}) })
} }
// 省名字列表
export function getProvinceList() {
return request({
method: 'GET',
url: `/temporarySearch/search-info/all-provinceName`,
})
}
// 国家列表
export function getCountryList() {
return request({
method: 'GET',
url: `/temporarySearch/search-info/all-countryName`,
})
}
// 实体类型
export function getEntityTypes() {
return request({
method: 'GET',
url: `/temporarySearch/search-info/entityTypes`,
})
}
// 物项类别
export function getMaterialCategory() {
return request({
method: 'GET',
url: `/temporarySearch/search-info/all-materialCategory`,
})
}
// 商业管制清单-管控原因
export function getControlReason() {
return request({
method: 'GET',
url: `/temporarySearch/search-info/all-controlReason`,
})
}
\ No newline at end of file
...@@ -123,7 +123,7 @@ export function getSanctionsInfoCount() { ...@@ -123,7 +123,7 @@ export function getSanctionsInfoCount() {
* sanReason: string * sanReason: string
* }[]>} * }[]>}
*/ */
export function getSanctionProcess(sanTypeIds = "1", pageNum = 1, pageSize = 10, isCn = false) { export function getSanctionProcess(sanTypeIds = ["1"], pageNum = 1, pageSize = 10, isCn = false) {
return request200( return request200(
request({ request({
method: "POST", method: "POST",
......
<template> <template>
<p class="p-regular-rereg"> <p class="p-regular-rereg">
<span class="text-regular" v-for="(segment, index) in processedText" :key="index"> <span class="text-regular" v-for="(segment, index) in processedText" :key="index">
<span v-if="segment.isEntity" @click="$emit('onEntityClick', segment.entity)" class="entity-link"> <span
v-if="segment.isEntity"
@click="$emit('onEntityClick', segment.entity)"
:class="['entity-link', { 'keyword-highlight': segment.isKeywordHit }]"
>
{{ segment.entity?.text_span }} {{ segment.entity?.text_span }}
<img :src="SearchIcon" :width="10" :height="10" alt="search" /> <img :src="SearchIcon" :width="10" :height="10" alt="search" />
</span> </span>
<span v-else> <span v-else>
{{ segment.text }} <span :class="{ 'keyword-highlight': segment.isKeywordHit }">{{ segment.text }}</span>
</span> </span>
</span> </span>
</p> </p>
...@@ -20,6 +24,7 @@ export interface ProcessedTextSegment { ...@@ -20,6 +24,7 @@ export interface ProcessedTextSegment {
text: string; text: string;
isEntity: boolean; isEntity: boolean;
entity?: TextEntity; entity?: TextEntity;
isKeywordHit?: boolean;
} }
const props = defineProps({ const props = defineProps({
text: { text: {
...@@ -29,15 +34,42 @@ const props = defineProps({ ...@@ -29,15 +34,42 @@ const props = defineProps({
entities: { entities: {
type: Array<TextEntity>, type: Array<TextEntity>,
default: () => [] default: () => []
},
highlight: {
type: String,
default: ""
} }
}); });
const emit = defineEmits(["onEntityClick"]); const emit = defineEmits(["onEntityClick"]);
// 处理后的文本段 // 处理后的文本段
const processedText = ref<ProcessedTextSegment[]>([]); const processedText = ref<ProcessedTextSegment[]>([]);
const normalizeKeyword = (value: unknown) => String(value ?? "").trim();
const getKeywordMatches = (text: string, keyword: string) => {
if (!keyword) return [{ text, isKeywordHit: false }];
const lowerText = text.toLowerCase();
const lowerKeyword = keyword.toLowerCase();
if (!lowerKeyword) return [{ text, isKeywordHit: false }];
const parts: Array<{ text: string; isKeywordHit: boolean }> = [];
let start = 0;
while (start < text.length) {
const index = lowerText.indexOf(lowerKeyword, start);
if (index === -1) {
parts.push({ text: text.slice(start), isKeywordHit: false });
break;
}
if (index > start) {
parts.push({ text: text.slice(start, index), isKeywordHit: false });
}
parts.push({ text: text.slice(index, index + keyword.length), isKeywordHit: true });
start = index + keyword.length;
}
return parts.filter(part => part.text);
};
// 处理文本,识别并替换实体 // 处理文本,识别并替换实体
const processText = () => { const processText = () => {
console.log("props.entities.length", props.entities.length);
if (!props.text || !props.entities) { if (!props.text || !props.entities) {
// console.log('props.text', props.entities.length) // console.log('props.text', props.entities.length)
processedText.value = [{ text: "", isEntity: false }]; processedText.value = [{ text: "", isEntity: false }];
...@@ -46,6 +78,7 @@ const processText = () => { ...@@ -46,6 +78,7 @@ const processText = () => {
const result = []; const result = [];
let currentPosition = 0; let currentPosition = 0;
const keyword = normalizeKeyword(props.highlight);
// 按实体文本长度排序,优先匹配长文本 // 按实体文本长度排序,优先匹配长文本
const sortedEntities = [...props.entities].sort((a, b) => b.text_span.length - a.text_span.length); const sortedEntities = [...props.entities].sort((a, b) => b.text_span.length - a.text_span.length);
...@@ -61,7 +94,8 @@ const processText = () => { ...@@ -61,7 +94,8 @@ const processText = () => {
// 如果当前位置是实体,添加到结果 // 如果当前位置是实体,添加到结果
result.push({ result.push({
isEntity: true, isEntity: true,
entity: { ...entity } entity: { ...entity },
isKeywordHit: keyword ? entityText.toLowerCase().includes(keyword.toLowerCase()) : false
}); });
currentPosition = endPosition; currentPosition = endPosition;
matched = true; matched = true;
...@@ -82,18 +116,26 @@ const processText = () => { ...@@ -82,18 +116,26 @@ const processText = () => {
if (nextEntityStart > currentPosition) { if (nextEntityStart > currentPosition) {
const plainText = props.text.substring(currentPosition, nextEntityStart); const plainText = props.text.substring(currentPosition, nextEntityStart);
const parts = getKeywordMatches(plainText, keyword);
parts.forEach(part => {
result.push({ result.push({
text: plainText, text: part.text,
isEntity: false isEntity: false,
isKeywordHit: part.isKeywordHit
});
}); });
currentPosition = nextEntityStart; currentPosition = nextEntityStart;
} else { } else {
// 没有更多实体,添加剩余文本 // 没有更多实体,添加剩余文本
const remainingText = props.text.substring(currentPosition); const remainingText = props.text.substring(currentPosition);
if (remainingText) { if (remainingText) {
const parts = getKeywordMatches(remainingText, keyword);
parts.forEach(part => {
result.push({ result.push({
text: remainingText, text: part.text,
isEntity: false isEntity: false,
isKeywordHit: part.isKeywordHit
});
}); });
} }
currentPosition = props.text.length; currentPosition = props.text.length;
...@@ -106,6 +148,7 @@ const processText = () => { ...@@ -106,6 +148,7 @@ const processText = () => {
// 监听文本和实体变化 // 监听文本和实体变化
watch(() => props.text, processText); watch(() => props.text, processText);
watch(() => props.entities, processText, { deep: true }); watch(() => props.entities, processText, { deep: true });
watch(() => props.highlight, processText);
// 初始化处理 // 初始化处理
onMounted(processText); onMounted(processText);
...@@ -113,6 +156,11 @@ onMounted(processText); ...@@ -113,6 +156,11 @@ onMounted(processText);
<style lang="scss" scoped> <style lang="scss" scoped>
@use "@/styles/common.scss"; @use "@/styles/common.scss";
.keyword-highlight {
background: rgba(255, 199, 0, 0.35);
border-radius: 2px;
}
.entity-link { .entity-link {
color: var(--color-primary-100); color: var(--color-primary-100);
&:hover { &:hover {
......
...@@ -33,7 +33,7 @@ const financeRoutes = [ ...@@ -33,7 +33,7 @@ const financeRoutes = [
}, },
// V2.0单条制裁详情-实体清单原文 // V2.0单条制裁详情-实体清单原文
{ {
path: "/exportControl/origin", path: "/finance/origin",
name: "financeEntityListOrigin", name: "financeEntityListOrigin",
component: () => import("@/views/finance/singleSanction/originPage/index.vue") component: () => import("@/views/finance/singleSanction/originPage/index.vue")
// meta: { // meta: {
......
...@@ -12,6 +12,7 @@ const useTagsViewStore = defineStore('tags-view', { ...@@ -12,6 +12,7 @@ const useTagsViewStore = defineStore('tags-view', {
this.addCachedView(view) this.addCachedView(view)
}, },
addVisitedView(view) { addVisitedView(view) {
this.visitedViews = localStorage.getItem('visitedViews') && JSON.parse(localStorage.getItem('visitedViews')) || []
this.visitedViews.forEach(item => { this.visitedViews.forEach(item => {
item.active = false item.active = false
}) })
...@@ -23,8 +24,8 @@ const useTagsViewStore = defineStore('tags-view', { ...@@ -23,8 +24,8 @@ const useTagsViewStore = defineStore('tags-view', {
...view, ...view,
title: view.meta?.title || '未命名' title: view.meta?.title || '未命名'
}) })
localStorage.setItem('visitedViews', JSON.stringify(this.visitedViews))
} else { } else {
this.visitedViews.forEach(v => { this.visitedViews.forEach(v => {
if (v.path === view.path) { if (v.path === view.path) {
v.active = true v.active = true
...@@ -49,7 +50,7 @@ const useTagsViewStore = defineStore('tags-view', { ...@@ -49,7 +50,7 @@ const useTagsViewStore = defineStore('tags-view', {
if (index !== -1) { if (index !== -1) {
this.visitedViews.splice(index, 1) this.visitedViews.splice(index, 1)
} }
localStorage.setItem('visitedViews', JSON.stringify(this.visitedViews))
resolve([...this.visitedViews]) resolve([...this.visitedViews])
}) })
}, },
...@@ -64,6 +65,13 @@ const useTagsViewStore = defineStore('tags-view', { ...@@ -64,6 +65,13 @@ const useTagsViewStore = defineStore('tags-view', {
} }
}, },
loadVisitedViewFromLocalStorage() {
const saved = localStorage.getItem('visitedViews')
if (saved) {
this.items = JSON.parse(saved)
}
},
// 关闭其他/右侧/全部 // 关闭其他/右侧/全部
delOthersViews(view) { delOthersViews(view) {
......
...@@ -485,7 +485,6 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', { ...@@ -485,7 +485,6 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
// ========== AI 生成报文 SSE(更新报文内容 + 执行步骤) ========== // ========== AI 生成报文 SSE(更新报文内容 + 执行步骤) ==========
async fetchReportData(params) { async fetchReportData(params) {
console.log(">")
if (this.abortController) this.abortController.abort(); if (this.abortController) this.abortController.abort();
this.abortController = new AbortController(); this.abortController = new AbortController();
// this.processLog = ''; // this.processLog = '';
...@@ -511,7 +510,8 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', { ...@@ -511,7 +510,8 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
lastFlushedIndex = 0; lastFlushedIndex = 0;
if (this.reportContent.includes('./out/img')) { if (this.reportContent.includes('./out/img')) {
this.reportContent = this.reportContent.replaceAll('./out/img', 'http://172.19.21.9:8003/out/img'); this.reportContent = this.reportContent.replaceAll('./out/img', outImgbaseUrl);
// console.log(reportContent)
} }
}; };
...@@ -571,7 +571,6 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', { ...@@ -571,7 +571,6 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
streamBuffer += str; streamBuffer += str;
updateFlushIndexByBoundary(); updateFlushIndexByBoundary();
flushToReport(false); flushToReport(false);
console.log(streamBuffer,456)
console.log(msgData,'data') console.log(msgData,'data')
} else { } else {
// 结束时把剩余内容强制 flush // 结束时把剩余内容强制 flush
...@@ -663,7 +662,6 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', { ...@@ -663,7 +662,6 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
}; };
await this.fetchReportData(params); await this.fetchReportData(params);
} else { } else {
console.log(10101010101010)
// 政令模板需要先解析PDF // 政令模板需要先解析PDF
if (this.curTempTitle === '政令') { if (this.curTempTitle === '政令') {
if (this.uploadFileList.length === 0) { if (this.uploadFileList.length === 0) {
......
...@@ -93,7 +93,7 @@ ...@@ -93,7 +93,7 @@
<div class="item"> <div class="item">
<div class="item-left">法案进展:</div> <div class="item-left">法案进展:</div>
<div class="item-right2"> <div class="item-right2">
<div class="tag" v-for="(val, idx) in getReversedProgress(item.progress)" :key="`${item.billId}-${val}-${idx}`" :style="{ zIndex: item.progress.length - idx }">{{ val }}</div> <div class="tag" v-for="(val, idx) in item.progress" :key="`${item.billId}-${val}-${idx}`" :style="{ zIndex: item.progress.length - idx }">{{ val }}</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -458,8 +458,6 @@ const handleClickAvatar = async member => { ...@@ -458,8 +458,6 @@ const handleClickAvatar = async member => {
} catch (error) {} } catch (error) {}
}; };
const getReversedProgress = progress => (Array.isArray(progress) ? [...progress].reverse() : []);
const handleClickCommitteeBill = bill => { const handleClickCommitteeBill = bill => {
if (!bill?.billId) return; if (!bill?.billId) return;
props.onClickToDetail({ props.onClickToDetail({
......
...@@ -373,7 +373,8 @@ const committeeTimeRange = ref("近一月"); ...@@ -373,7 +373,8 @@ const committeeTimeRange = ref("近一月");
const committeeTimeOptions = [ const committeeTimeOptions = [
{ label: "近一周", value: "近一周" }, { label: "近一周", value: "近一周" },
{ label: "近一月", value: "近一月" }, { label: "近一月", value: "近一月" },
{ label: "近一年", value: "近一年" } { label: "近一年", value: "近一年" },
{label:"全部时间", value: "全部时间"}
]; ];
const committeeCardList = ref([]); const committeeCardList = ref([]);
...@@ -1029,14 +1030,15 @@ const handleBox6 = async () => { ...@@ -1029,14 +1030,15 @@ const handleBox6 = async () => {
// 涉华领域分布 // 涉华领域分布
const box9ChartData = ref([]); const box9ChartData = ref([]);
const box9selectetedTime = ref("2025"); const box9selectetedTime = ref("2025");
// 立法状态下拉:提出法案、众议院通过、参议院通过、解决分歧、完成立法 // 立法状态下拉:提出法案、众议院通过、参议院通过、解决分歧、呈交总统、完成立法
// v-model 存储的是接口需要的 status 值 // v-model 存储的是接口需要的 status 值(直接作为接口参数)
const box9LegislativeStatus = ref("提案"); const box9LegislativeStatus = ref("提出法案");
const box9LegislativeStatusList = ref([ const box9LegislativeStatusList = ref([
{ label: "提出法案", value: "提案" }, { label: "提出法案", value: "提出法案" },
{ label: "众议院通过", value: "众议院通过" }, { label: "众议院通过", value: "众议院通过" },
{ label: "参议院通过", value: "参议院通过" }, { label: "参议院通过", value: "参议院通过" },
{ label: "解决分歧", value: "分歧已解决" }, { label: "解决分歧", value: "解决分歧" },
{ label: "呈交总统", value: "呈交总统" },
{ label: "完成立法", value: "完成立法" } { label: "完成立法", value: "完成立法" }
]); ]);
const box9YearList = ref([ const box9YearList = ref([
...@@ -1063,18 +1065,39 @@ const box9YearList = ref([ ...@@ -1063,18 +1065,39 @@ const box9YearList = ref([
]); ]);
const box9HasData = ref(true); const box9HasData = ref(true);
let box9ChartInstance = null; let box9ChartInstance = null;
const BOX9_MAX_DOMAIN_COUNT = 7;
const BOX9_OTHER_DOMAIN_NAME = "其他";
const formatBox9DomainData = (list = []) => {
if (!Array.isArray(list) || list.length <= BOX9_MAX_DOMAIN_COUNT) {
return list;
}
const topDomainList = list.slice(0, BOX9_MAX_DOMAIN_COUNT);
const otherDomainCount = list.slice(BOX9_MAX_DOMAIN_COUNT).reduce((sum, item) => {
return sum + Number(item?.countBill || 0);
}, 0);
if (!otherDomainCount) {
return topDomainList;
}
return [
...topDomainList,
{
industryName: BOX9_OTHER_DOMAIN_NAME,
countBill: otherDomainCount
}
];
};
const getBox9Data = async () => { const getBox9Data = async () => {
chartLoading.value = { ...chartLoading.value, box6: true }; chartLoading.value = { ...chartLoading.value, box6: true };
const params = { const params = {
year: box9selectetedTime.value, year: box9selectetedTime.value,
status: box9LegislativeStatus.value stageName: box9LegislativeStatus.value
}; };
try { try {
const res = await getBillIndustry(params); const res = await getBillIndustry(params);
console.log("box9-涉华法案领域分布", res.data); console.log("box9-涉华法案领域分布", res.data);
if (res.code === 200 && res.data && res.data.length > 0) { if (res.code === 200 && res.data && res.data.length > 0) {
box9HasData.value = true; box9HasData.value = true;
box9ChartData.value = res.data; box9ChartData.value = formatBox9DomainData(res.data);
} else { } else {
box9HasData.value = false; box9HasData.value = false;
box9ChartData.value = []; box9ChartData.value = [];
...@@ -1104,16 +1127,9 @@ const handleBox9Data = async () => { ...@@ -1104,16 +1127,9 @@ const handleBox9Data = async () => {
const selectedIndex = box9LegislativeStatusList.value.findIndex( const selectedIndex = box9LegislativeStatusList.value.findIndex(
item => item.value === box9LegislativeStatus.value item => item.value === box9LegislativeStatus.value
); );
const arr = [ // 当前选中的立法状态中文名(直接等于接口传参值)
{ label: "提出法案", value: "提案" }, const statusItem = box9LegislativeStatusList.value[selectedIndex];
{ label: "众议院通过", value: "众议院通过" }, const status = statusItem ? statusItem.label : "";
{ label: "参议院通过", value: "参议院通过" },
{ label: "解决分歧", value: "分歧已解决" },
{ label: "完成立法", value: "完成立法" }
]
const status = arr.filter(item => {
return item.value === box9LegislativeStatus.value
})[0].label
const selectParam = { const selectParam = {
moduleType: '国会法案', moduleType: '国会法案',
key: 2, key: 2,
...@@ -1272,13 +1288,14 @@ const getBox8ChartOption = stageList => { ...@@ -1272,13 +1288,14 @@ const getBox8ChartOption = stageList => {
const handleBox8Data = async () => { const handleBox8Data = async () => {
chartLoading.value = { ...chartLoading.value, box8: true }; chartLoading.value = { ...chartLoading.value, box8: true };
// 进展分布显示顺序:提出法案(对应进度“提案”)、众议院通过、参议院通过、分歧已解决(解决分歧)、完成立法 // 进展分布显示顺序:提出法案(对应进度“提案”)、众议院通过、参议院通过、解决分歧(对应进度“分歧已解决”)、呈交总统、完成立法
const stageOrder = ["提案", "众议院通过", "参议院通过", "分歧已解决", "完成立法"]; const stageOrder = ["提案", "众议院通过", "参议院通过", "分歧已解决", "呈交总统", "完成立法"];
const stageNameMap = { const stageNameMap = {
提案: "提出法案", 提案: "提出法案",
众议院通过: "众议院通过", 众议院通过: "众议院通过",
参议院通过: "参议院通过", 参议院通过: "参议院通过",
分歧已解决: "解决分歧", 分歧已解决: "解决分歧",
呈交总统: "呈交总统",
完成立法: "完成立法" 完成立法: "完成立法"
}; };
......
...@@ -1169,6 +1169,10 @@ onMounted(async () => { ...@@ -1169,6 +1169,10 @@ onMounted(async () => {
<style lang="scss" scoped> <style lang="scss" scoped>
.wrap { .wrap {
display: flex; display: flex;
flex-direction: row;
flex-wrap: nowrap;
direction: ltr;
justify-content: flex-start;
margin-bottom: 30px; margin-bottom: 30px;
...@@ -1254,6 +1258,8 @@ onMounted(async () => { ...@@ -1254,6 +1258,8 @@ onMounted(async () => {
.left { .left {
margin-top: 16px; margin-top: 16px;
width: 792px;
flex: 0 0 792px;
.box1 { .box1 {
width: 792px; width: 792px;
...@@ -1651,6 +1657,7 @@ onMounted(async () => { ...@@ -1651,6 +1657,7 @@ onMounted(async () => {
margin-left: 16px; margin-left: 16px;
margin-top: 16px; margin-top: 16px;
width: 792px; width: 792px;
flex: 0 0 792px;
height: 847px; height: 847px;
.box3 { .box3 {
......
...@@ -131,6 +131,7 @@ ...@@ -131,6 +131,7 @@
<IntelligentEntityText <IntelligentEntityText
:text="term?.fynr || ''" :text="term?.fynr || ''"
:entities="termsHighlight ? getTermEntities(term, 'cn') : []" :entities="termsHighlight ? getTermEntities(term, 'cn') : []"
:highlight="searchKeyword"
@on-entity-click="e => gotoSearchResults(e.text_span, '')" @on-entity-click="e => gotoSearchResults(e.text_span, '')"
/> />
</div> </div>
...@@ -141,6 +142,7 @@ ...@@ -141,6 +142,7 @@
<IntelligentEntityText <IntelligentEntityText
:text="term?.ywnr || ''" :text="term?.ywnr || ''"
:entities="termsHighlight ? getTermEntities(term, 'en') : []" :entities="termsHighlight ? getTermEntities(term, 'en') : []"
:highlight="searchKeyword"
@on-entity-click="e => gotoSearchResults(e.text_span, '')" @on-entity-click="e => gotoSearchResults(e.text_span, '')"
/> />
</div> </div>
...@@ -343,6 +345,27 @@ const chart1ColorList = ref([...MUTICHARTCOLORS]); ...@@ -343,6 +345,27 @@ const chart1ColorList = ref([...MUTICHARTCOLORS]);
const chart2ColorList = ref([...MUTICHARTCOLORS]); const chart2ColorList = ref([...MUTICHARTCOLORS]);
const chart2Data = ref([]); const chart2Data = ref([]);
const DOMAIN_MAX_DISPLAY_COUNT = 7;
const DOMAIN_OTHER_NAME = "其他";
const formatDomainChartData = (list = []) => {
if (!Array.isArray(list) || list.length <= DOMAIN_MAX_DISPLAY_COUNT) {
return list;
}
const topDomainList = list.slice(0, DOMAIN_MAX_DISPLAY_COUNT);
const otherCount = list.slice(DOMAIN_MAX_DISPLAY_COUNT).reduce((sum, item) => {
return sum + Number(item?.value || 0);
}, 0);
if (!otherCount) {
return topDomainList;
}
return [
...topDomainList,
{
name: DOMAIN_OTHER_NAME,
value: otherCount
}
];
};
const aiPaneVisible = ref({ const aiPaneVisible = ref({
domain: false, domain: false,
...@@ -737,12 +760,13 @@ const handleGetBillHyly = async () => { ...@@ -737,12 +760,13 @@ const handleGetBillHyly = async () => {
.map(name => { .map(name => {
return { label: name, value: name }; return { label: name, value: name };
}); });
chart2Data.value = res.data.map(item => { const domainChartData = res.data.map(item => {
return { return {
name: item.hylymc, name: item.hylymc,
value: item.countTk value: item.countTk
}; };
}); });
chart2Data.value = formatDomainChartData(domainChartData);
aiPaneFetched.value = { ...aiPaneFetched.value, domain: false }; aiPaneFetched.value = { ...aiPaneFetched.value, domain: false };
let chart2 = getPieChart(chart2Data.value, chart2ColorList.value); let chart2 = getPieChart(chart2Data.value, chart2ColorList.value);
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<div class="header-top"> <div class="header-top">
<SelectBox :placeholder-name="areaPlaceHolder" select-title="科技领域" :select-list="areaList" <SelectBox :placeholder-name="areaPlaceHolder" select-title="科技领域" :select-list="areaList"
:select-name="selectedArea" @update:select-text="handleSelectArea" /> :select-name="selectedArea" @update:select-text="handleSelectArea" />
<SelectBox :placeholder-name="DatePlaceHolder" select-title="提时间" :select-list="dateList" <SelectBox :placeholder-name="DatePlaceHolder" select-title="提时间" :select-list="dateList"
:select-name="selectedDate" :custom-time="customTime" @update:select-text="handleSelectDate" :select-name="selectedDate" :custom-time="customTime" @update:select-text="handleSelectDate"
@update:custom-time="handleCustomDate" /> @update:custom-time="handleCustomDate" />
<SelectBox v-if="isFolderAll" :placeholder-name="partyPlaceHolder" select-title="所属党派" :select-list="partyList" <SelectBox v-if="isFolderAll" :placeholder-name="partyPlaceHolder" select-title="所属党派" :select-list="partyList"
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
<ChartHeader :list="staticsDemensionList" @clickItem="handleClickDemensionItem"> <ChartHeader :list="staticsDemensionList" @clickItem="handleClickDemensionItem">
<template #chart-header-right> <template #chart-header-right>
<el-select v-model="selectedTime" placeholder="选择时间" style="width: 150px" <el-select v-model="selectedTime" placeholder="选择时间" style="width: 150px"
v-show="curDemension === '提案时间'"> v-show="curDemension === '提案时间'" @change="handleChangeTime">
<el-option v-for="item in timeList" :key="item.value" :label="item.label" :value="item.value" /> <el-option v-for="item in timeList" :key="item.value" :label="item.label" :value="item.value" />
</el-select> </el-select>
...@@ -123,7 +123,8 @@ ...@@ -123,7 +123,8 @@
<el-table-column type="selection" width="40" /> <el-table-column type="selection" width="40" />
<el-table-column label="法案名称" width="455"> <el-table-column label="法案名称" width="455">
<template #default="scope"> <template #default="scope">
<span class="title-item text-compact-bold" @click="handleClickToDetail(scope.row)">{{ scope.row.originalTitle <span class="title-item text-compact-bold" @click="handleClickToDetail(scope.row)">{{
scope.row.originalTitle
}}</span> }}</span>
</template> </template>
</el-table-column> </el-table-column>
...@@ -184,10 +185,20 @@ const handleSwitchChartData = () => { ...@@ -184,10 +185,20 @@ const handleSwitchChartData = () => {
const curDemensionItem = staticsDemensionList.value.filter(item => { const curDemensionItem = staticsDemensionList.value.filter(item => {
return item.name === curDemension.value return item.name === curDemension.value
})[0] })[0]
timer1.value = setTimeout(() => { // timer1.value = setTimeout(() => {
activeChart.value = curDemensionItem.chartTypeList[0] activeChart.value = curDemensionItem.chartTypeList[0]
if (curDemension.value === '提案时间') {
if (selectedTime.value === '按月度统计') {
curChartData.value = curDemensionItem.data curChartData.value = curDemensionItem.data
}) } else if (selectedTime.value === '按季度统计') {
curChartData.value = curDemensionItem.quatarData
} else {
curChartData.value = curDemensionItem.yearData
}
} else {
curChartData.value = curDemensionItem.data
}
// })
} }
} }
...@@ -206,10 +217,12 @@ const staticsDemensionList = ref([ ...@@ -206,10 +217,12 @@ const staticsDemensionList = ref([
dataY: [] dataY: []
}, },
quatarData: { quatarData: {
dataX: [],
dataY: []
}, },
yearData: { yearData: {
dataX: [],
dataY: []
} }
}, },
{ {
...@@ -273,11 +286,17 @@ const handleClickDemensionItem = (val) => { ...@@ -273,11 +286,17 @@ const handleClickDemensionItem = (val) => {
curDemension.value = val.name curDemension.value = val.name
timer2.value = setTimeout(() => { timer2.value = setTimeout(() => {
activeChart.value = val.chartTypeList[0] activeChart.value = val.chartTypeList[0]
if (curDemension.value === '发布时间' && selectedTime.value === '按年度统计') {
curChartData.value = val.yearData
} else if (curDemension.value === '发布时间' && selectedTime.value === '按季度统计') {
curChartData.value = val.quatarData
} else {
curChartData.value = val.data curChartData.value = val.data
}
}) })
} }
const selectedTime = ref('按统计') const selectedTime = ref('按年度统计')
const timeList = ref([ const timeList = ref([
{ {
label: '按年度统计', label: '按年度统计',
...@@ -293,6 +312,27 @@ const timeList = ref([ ...@@ -293,6 +312,27 @@ const timeList = ref([
}, },
]) ])
const handleChangeTime = value => {
let curChart = activeChart.value
activeChart.value = ''
if (value === '按月度统计') {
setTimeout(() => {
activeChart.value = curChart
curChartData.value = staticsDemensionList.value[0].data
})
} else if (value === '按季度统计') {
setTimeout(() => {
activeChart.value = curChart
curChartData.value = staticsDemensionList.value[0].quatarData
})
} else {
setTimeout(() => {
activeChart.value = curChart
curChartData.value = staticsDemensionList.value[0].yearData
})
}
}
// 激活的标签列表 // 激活的标签列表
const activeTagList = computed(() => { const activeTagList = computed(() => {
const arr = [] const arr = []
...@@ -307,7 +347,7 @@ const activeTagList = computed(() => { ...@@ -307,7 +347,7 @@ const activeTagList = computed(() => {
if (selectedDate.value === '自定义') { if (selectedDate.value === '自定义') {
arr.push( arr.push(
{ {
tag: '提时间', tag: '提时间',
name: customTime.value.join('至') name: customTime.value.join('至')
} }
) )
...@@ -372,7 +412,7 @@ const handleCloseCurTag = (tag, index) => { ...@@ -372,7 +412,7 @@ const handleCloseCurTag = (tag, index) => {
case '科技领域': case '科技领域':
selectedArea.value = '全部领域' selectedArea.value = '全部领域'
break break
case '提时间': case '提时间':
selectedDate.value = '' selectedDate.value = ''
break break
case '所属党派': case '所属党派':
...@@ -541,7 +581,7 @@ const handleSelectArea = (value) => { ...@@ -541,7 +581,7 @@ const handleSelectArea = (value) => {
selectedArea.value = value selectedArea.value = value
} }
// 提时间 // 提时间
const DatePlaceHolder = ref('请选择时间') const DatePlaceHolder = ref('请选择时间')
const selectedDate = ref('') const selectedDate = ref('')
const dateList = ref([ const dateList = ref([
...@@ -843,6 +883,14 @@ const fetchTableData = async () => { ...@@ -843,6 +883,14 @@ const fetchTableData = async () => {
dataX: Object.keys(res.data.aggregationsDate), dataX: Object.keys(res.data.aggregationsDate),
dataY: Object.values(res.data.aggregationsDate).map(value => Number(value)) dataY: Object.values(res.data.aggregationsDate).map(value => Number(value))
} }
staticsDemensionList.value[0].quatarData = {
dataX: Object.keys(res.data.aggregationsQuarter),
dataY: Object.values(res.data.aggregationsQuarter).map(value => Number(value))
}
staticsDemensionList.value[0].yearData = {
dataX: Object.keys(res.data.aggregationsYear),
dataY: Object.values(res.data.aggregationsYear).map(value => Number(value))
}
staticsDemensionList.value[1].data = Object.entries(res.data.aggregationsDomain).map(([key, value]) => ({ staticsDemensionList.value[1].data = Object.entries(res.data.aggregationsDomain).map(([key, value]) => ({
name: key, name: key,
value: Number(value) value: Number(value)
...@@ -860,7 +908,7 @@ const fetchTableData = async () => { ...@@ -860,7 +908,7 @@ const fetchTableData = async () => {
value: Number(value) value: Number(value)
})) }))
staticsDemensionList.value[5].data = Object.entries(res.data.aggregationsStatus).map(([key, value]) => ({ staticsDemensionList.value[5].data = Object.entries(res.data.aggregationsStatus).map(([key, value]) => ({
name: key === '1' ? '通过' : '提出', name: key,
value: Number(value) value: Number(value)
})) }))
} }
...@@ -1083,10 +1131,10 @@ const initParam = () => { ...@@ -1083,10 +1131,10 @@ const initParam = () => {
const query = route.query; const query = route.query;
if (Object.keys(query).length > 0) { if (Object.keys(query).length > 0) {
sessionStorage.setItem('routeQuery', JSON.stringify(query)); sessionStorage.setItem('countryRouteQuery', JSON.stringify(query));
} }
} else { } else {
const savedQuery = JSON.parse(sessionStorage.getItem('routeQuery') || '{}'); const savedQuery = JSON.parse(sessionStorage.getItem('countryRouteQuery') || '{}');
selectedArea.value = savedQuery.domains ? savedQuery.domains : '全部领域' selectedArea.value = savedQuery.domains ? savedQuery.domains : '全部领域'
if (savedQuery.selectedDate && Array.isArray(JSON.parse(savedQuery.selectedDate)) && JSON.parse(savedQuery.selectedDate).length) { if (savedQuery.selectedDate && Array.isArray(JSON.parse(savedQuery.selectedDate)) && JSON.parse(savedQuery.selectedDate).length) {
selectedDate.value = '自定义' selectedDate.value = '自定义'
......
...@@ -62,7 +62,9 @@ const getBarChart = (data) => { ...@@ -62,7 +62,9 @@ const getBarChart = (data) => {
type: 'bar', type: 'bar',
data: data.dataY, data: data.dataY,
label: { label: {
show: true, show: true,
position: 'top', position: 'top',
color: 'rgb(59, 65, 75)', color: 'rgb(59, 65, 75)',
fontWeight: 'regular', // 文字加粗 fontWeight: 'regular', // 文字加粗
...@@ -72,7 +74,7 @@ const getBarChart = (data) => { ...@@ -72,7 +74,7 @@ const getBarChart = (data) => {
return params.value return params.value
}, },
}, },
barWidth: 20, barWidth: data.dataX.length < 60 ? 20 : 3,
itemStyle: { itemStyle: {
color: function (params) { color: function (params) {
return new echarts.graphic.LinearGradient(0, 1, 0, 0, return new echarts.graphic.LinearGradient(0, 1, 0, 0,
......
<template> <template>
<div class="wrapper"> <div class="wrapper">
<div class="show" @click="handleSwitchShowAll"> <div v-if="isShowAllBtn" class="show" @click="handleSwitchShowAll">
<div class="text text-compact">{{ isShowAll ? '收起' : '展开全部' }}</div> <div class="text text-compact">{{ isShowAll ? '收起' : '展开全部' }}</div>
<div class="icon"> <div class="icon">
<img v-if="isShowAll" src="./arrow-up.svg" alt=""> <img v-if="isShowAll" src="./arrow-up.svg" alt="">
...@@ -23,6 +23,10 @@ const props = defineProps({ ...@@ -23,6 +23,10 @@ const props = defineProps({
isShowAll: { isShowAll: {
type: Boolean, type: Boolean,
default: false default: false
},
isShowAllBtn: {
type: Boolean,
default: true
} }
}) })
......
...@@ -53,6 +53,9 @@ const getLineChart = (dataX, dataY) => { ...@@ -53,6 +53,9 @@ const getLineChart = (dataX, dataY) => {
lineStyle: { lineStyle: {
color: 'rgba(5, 95, 194, 1)' color: 'rgba(5, 95, 194, 1)'
}, },
label: {
show: true
},
areaStyle: { areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0, offset: 0,
......
import { MUTICHARTCOLORS } from "@/common/constant"; import { MUTICHARTCOLORS } from "@/common/constant";
const getPieChart = (data) => { const getPieChart = (data) => {
const colorList = MUTICHARTCOLORS const colorList = MUTICHARTCOLORS
let showData = data
if(data.length > 14) {
showData = data.slice(0,13)
let num = 0
data.slice(13,).forEach(item => {
num = num + item.value
})
showData = [...showData, {name: '其他', value: num}]
}
let option = { let option = {
color: colorList, color: colorList,
legend: {
show: false
},
series: [ series: [
{ {
type: 'pie', type: 'pie',
...@@ -50,7 +62,7 @@ const getPieChart = (data) => { ...@@ -50,7 +62,7 @@ const getPieChart = (data) => {
labelLinePoints: points labelLinePoints: points
}; };
}, },
data: data data: showData
}] }]
} }
return option return option
......
...@@ -89,4 +89,5 @@ const customTimeValue = computed({ ...@@ -89,4 +89,5 @@ const customTimeValue = computed({
.select-wrapper-custom { .select-wrapper-custom {
width: 738px; width: 738px;
} }
</style> </style>
\ No newline at end of file
...@@ -197,7 +197,7 @@ const handleSwitchChartData = () => { ...@@ -197,7 +197,7 @@ const handleSwitchChartData = () => {
const curDemensionItem = staticsDemensionList.value.filter(item => { const curDemensionItem = staticsDemensionList.value.filter(item => {
return item.name === curDemension.value return item.name === curDemension.value
})[0] })[0]
setTimeout(() => { // setTimeout(() => {
activeChart.value = curDemensionItem.chartTypeList[0] activeChart.value = curDemensionItem.chartTypeList[0]
if (curDemension.value === '发布时间') { if (curDemension.value === '发布时间') {
if (selectedTime.value === '按月度统计') { if (selectedTime.value === '按月度统计') {
...@@ -210,7 +210,7 @@ const handleSwitchChartData = () => { ...@@ -210,7 +210,7 @@ const handleSwitchChartData = () => {
} else { } else {
curChartData.value = curDemensionItem.data curChartData.value = curDemensionItem.data
} }
}) // })
} }
} }
...@@ -289,7 +289,7 @@ const handleClickDemensionItem = (val) => { ...@@ -289,7 +289,7 @@ const handleClickDemensionItem = (val) => {
} }
// 时间图表 当前选择时间 // 时间图表 当前选择时间
const selectedTime = ref('按统计') const selectedTime = ref('按年度统计')
// 时间图表-时间列表 // 时间图表-时间列表
const timeList = ref([ const timeList = ref([
{ {
......
...@@ -92,6 +92,7 @@ import { ElMessage } from "element-plus"; ...@@ -92,6 +92,7 @@ import { ElMessage } from "element-plus";
const router = useRouter(); const router = useRouter();
const route = useRoute(); const route = useRoute();
const tagsViewStore = useTagsViewStore(); const tagsViewStore = useTagsViewStore();
tagsViewStore.loadVisitedViewFromLocalStorage()
// 在路由全局守卫中处理 // 在路由全局守卫中处理
router.beforeEach((to, from, next) => { router.beforeEach((to, from, next) => {
...@@ -348,8 +349,7 @@ const handleSiderSecondItem = item => { ...@@ -348,8 +349,7 @@ const handleSiderSecondItem = item => {
}; };
const openedTabList = computed(() => { const openedTabList = computed(() => {
const arr = tagsViewStore.visitedViews; return tagsViewStore.visitedViews;
return arr;
}); });
const handleClickTab = tab => { const handleClickTab = tab => {
...@@ -393,7 +393,7 @@ const timer = ref(null); ...@@ -393,7 +393,7 @@ const timer = ref(null);
// 关闭当前标签页 // 关闭当前标签页
const handleCloseCurTab = (tab, index) => { const handleCloseCurTab = (tab, index) => {
if(tagsViewStore.visitedViews.length === 1) { if (tagsViewStore.visitedViews.length === 1) {
ElMessage.warning('至少保留一个标签页') ElMessage.warning('至少保留一个标签页')
return return
} }
...@@ -494,16 +494,17 @@ onMounted(() => { ...@@ -494,16 +494,17 @@ onMounted(() => {
siderList.value[3].isExpanded = true; siderList.value[3].isExpanded = true;
siderList.value[3].children[0].active = true; siderList.value[3].children[0].active = true;
break; break;
case "/dataLibrary/dataCommerceControlList": case "/dataLibrary/dataEntityListEvent":
siderList.value[3].active = true; siderList.value[3].active = true;
siderList.value[3].isExpanded = true; siderList.value[3].isExpanded = true;
siderList.value[3].children[1].active = true; siderList.value[3].children[1].active = true;
break; break;
case "/dataLibrary/dataEntityListEvent": case "/dataLibrary/dataCommerceControlList":
siderList.value[3].active = true; siderList.value[3].active = true;
siderList.value[3].isExpanded = true; siderList.value[3].isExpanded = true;
siderList.value[3].children[2].active = true; siderList.value[3].children[2].active = true;
break; break;
case "/dataLibrary/dataCommerceControlListEvent": case "/dataLibrary/dataCommerceControlListEvent":
siderList.value[3].active = true; siderList.value[3].active = true;
siderList.value[3].isExpanded = true; siderList.value[3].isExpanded = true;
...@@ -586,6 +587,7 @@ onBeforeUnmount(() => { ...@@ -586,6 +587,7 @@ onBeforeUnmount(() => {
if (timer.value) { if (timer.value) {
clearTimeout(timer.value); clearTimeout(timer.value);
} }
localStorage.setItem('visitedViews', [])
}); });
</script> </script>
......
...@@ -189,7 +189,7 @@ const handleSwitchChartData = () => { ...@@ -189,7 +189,7 @@ const handleSwitchChartData = () => {
const curDemensionItem = staticsDemensionList.value.filter(item => { const curDemensionItem = staticsDemensionList.value.filter(item => {
return item.name === curDemension.value; return item.name === curDemension.value;
})[0]; })[0];
setTimeout(() => { // setTimeout(() => {
activeChart.value = curDemensionItem.chartTypeList[0]; activeChart.value = curDemensionItem.chartTypeList[0];
if (curDemension.value === "发布时间") { if (curDemension.value === "发布时间") {
if (selectedTime.value === "按月度统计") { if (selectedTime.value === "按月度统计") {
...@@ -202,7 +202,7 @@ const handleSwitchChartData = () => { ...@@ -202,7 +202,7 @@ const handleSwitchChartData = () => {
} else { } else {
curChartData.value = curDemensionItem.data; curChartData.value = curDemensionItem.data;
} }
}); // });
} }
}; };
...@@ -281,7 +281,7 @@ const handleClickDemensionItem = val => { ...@@ -281,7 +281,7 @@ const handleClickDemensionItem = val => {
}; };
// 时间图表 当前选择时间 // 时间图表 当前选择时间
const selectedTime = ref("按统计"); const selectedTime = ref("按年度统计");
// 时间图表-时间列表 // 时间图表-时间列表
const timeList = ref([ const timeList = ref([
{ {
......
差异被折叠。
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论