提交 f987ba5c authored 作者: 张烨's avatar 张烨

Merge branch 'master' into zy-dev

...@@ -10,6 +10,7 @@ lerna-debug.log* ...@@ -10,6 +10,7 @@ lerna-debug.log*
*.rar *.rar
*.zip *.zip
*.7z *.7z
*.rest
# Dependencies # Dependencies
node_modules node_modules
......
...@@ -7,32 +7,41 @@ import request from "@/api/request.js"; ...@@ -7,32 +7,41 @@ import request from "@/api/request.js";
* @param {String} params.date - 日期 * @param {String} params.date - 日期
*/ */
export function getAllUnionList(params) { export function getAllUnionList(params) {
return request({ return request({
method: 'GET', method: "GET",
url: `/api/union/union/unionList/${params.date}` url: `/api/union/union/unionList/${params.date}`,
}) params: {
domainId: params.domainId ? params.domainId : null
}
});
} }
// 全联盟-获取排华数量 // 全联盟-获取排华数量
/** /**
* @header token * @header token
*/ */
export function getUnionCount() { export function getUnionCount(params) {
return request({ return request({
method: 'GET', method: "GET",
url: `/api/union/union/unionCount` url: `/api/union/union/unionCount`,
}) params: {
currentPage: params.page ? params.page : 1,
pageSize: params.pageSize ? params.pageSize : 10,
domainId: params.domainId ? params.domainId : null
}
});
} }
// 全联盟-获取排华联盟动态 // 全联盟-获取排华联盟动态
/** /**
* @header token * @header token
*/ */
export function getDynamic() { export function getDynamic(params) {
return request({ return request({
method: 'GET', method: "GET",
url: `/api/union/union/dynamic` url: `/api/union/union/dynamic`,
}) params
});
} }
// 全联盟-获取排华联盟预警 // 全联盟-获取排华联盟预警
...@@ -42,10 +51,10 @@ export function getDynamic() { ...@@ -42,10 +51,10 @@ export function getDynamic() {
* @header token * @header token
*/ */
export function getPrediction() { export function getPrediction() {
return request({ return request({
method: 'GET', method: "GET",
url: `/api/union/union/prediction` url: `/api/union/union/prediction`
}) });
} }
// 全联盟-获取排华联盟领域分布 // 全联盟-获取排华联盟领域分布
...@@ -55,10 +64,10 @@ export function getPrediction() { ...@@ -55,10 +64,10 @@ export function getPrediction() {
* @header token * @header token
*/ */
export function getIndustry() { export function getIndustry() {
return request({ return request({
method: 'GET', method: "GET",
url: `/api/union/union/industry` url: `/api/union/union/industry`
}) });
} }
// 全联盟-获取排华联盟国家紧密度 // 全联盟-获取排华联盟国家紧密度
...@@ -68,8 +77,8 @@ export function getIndustry() { ...@@ -68,8 +77,8 @@ export function getIndustry() {
* @header token * @header token
*/ */
export function getCountryRelation() { export function getCountryRelation() {
return request({ return request({
method: 'GET', method: "GET",
url: `/api/union/union/countryRelation` url: `/api/union/union/countryRelation`
}) });
} }
\ No newline at end of file
...@@ -117,7 +117,7 @@ export function getBillContentId(params) { ...@@ -117,7 +117,7 @@ export function getBillContentId(params) {
// 主要条款-根据原文ID获取条款内容 // 主要条款-根据原文ID获取条款内容
/** /**
* @param {billid,id,cRelated,currentPage,pageSize} * @param {billId,id,cRelated,currentPage,pageSize,domainNameList,measuresNameList,content}
* @header token * @header token
*/ */
export function getBillContentTk(params) { export function getBillContentTk(params) {
......
...@@ -135,6 +135,26 @@ export function getBillsPerson(params, signal) { ...@@ -135,6 +135,26 @@ export function getBillsPerson(params, signal) {
}) })
} }
// 获取议员合作关系
export function getBillsPersonRel(params, signal) {
return request({
method: 'GET',
url: `/api/BillOverview/billsPersonRel`,
params,
signal
})
}
// 获取涉华委员会及其法案
export function getBillsIsCnCommittee(params, signal) {
return request({
method: 'GET',
url: `/api/BillOverview/billsIsCnCommittee`,
params,
signal
})
}
// 获取提出部门列表 // 获取提出部门列表
export function getPostOrgList() { export function getPostOrgList() {
return request({ return request({
...@@ -149,4 +169,100 @@ export function getPostMemberList() { ...@@ -149,4 +169,100 @@ export function getPostMemberList() {
method: 'GET', method: 'GET',
url: `/api/BillDict/member`, url: `/api/BillDict/member`,
}) })
} }
\ No newline at end of file
/**
* 获取筛选项配置 - 行业列表
* GET /api/billImpactAnalysis/industry/hylyList
*/
export async function getIndustryKeyList() {
return request('/api/billImpactAnalysis/industry/hylyList', {
method: 'GET',
})
}
/**
* 获取进度阶段配置
* GET /api/commonDict/bill/stage
*/
export async function getBillStageConfig() {
return request('/api/commonDict/bill/stage', {
method: 'GET',
})
}
/**
* 获取法案列表
* GET /api/personHomepage/historyBill/{personId}
* @param {string} personId - 人物ID
* @param {Object} params - 查询参数(不包含分页参数)
*/
export async function getHistoryBillList(personId, params = {}) {
const queryString = Object.entries(params)
.filter(([, value]) => value !== undefined && value !== null && value !== '')
.map(([key, value]) => {
if (Array.isArray(value)) {
return value.map(v => `${encodeURIComponent(key)}=${encodeURIComponent(v)}`).join('&')
}
return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`
})
.join('&')
const url = queryString
? `/api/personHomepage/historyBill/${personId}?${queryString}`
: `/api/personHomepage/historyBill/${personId}`
return request(url, {
method: 'GET',
})
}
/**
* 获取法案列表(含阶段字典)
* @param {string} personId - 人物ID
* @param {Object} params - 查询参数
*/
export async function getHistoryBillListWithStage(personId, params = {}) {
const stageRes = await getBillStageConfig()
const billRes = await getHistoryBillList(personId, params)
return {
stageConfig: stageRes,
billList: billRes,
}
}
export function getSortOptions() {
return Promise.resolve({
code: 200,
data: [
{ value: 'latestMotionTimeDesc', label: '最新修议时间倒序' },
{ value: 'latestMotionTimeAsc', label: '最新修议时间正序' },
],
})
}
export async function getPotentialNewsList(personId, params = {}) {
const queryString = Object.entries(params)
.filter(([, value]) => value !== undefined && value !== null && value !== '')
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
.join('&')
const url = queryString
? `/api/personHomepage/historyBill/clause/${personId}?${queryString}`
: `/api/personHomepage/historyBill/clause/${personId}`
return request(url, {
method: 'GET',
})
}
export async function getPotentialNewsKeywords(personId) {
return request(`/api/personHomepage/historyBill/clauseKeyword/${personId}`, {
method: 'GET',
})
}
\ No newline at end of file
...@@ -98,8 +98,8 @@ export function getCharacterResume(params) { ...@@ -98,8 +98,8 @@ export function getCharacterResume(params) {
*/ */
export function getCharacterView(params) { export function getCharacterView(params) {
return request({ return request({
method: 'GET', method: 'GET',
url: `/api/personHomepage/option/${params.personId}/${params.year}`, url: `/api/personHomepage/option/`,
params, params,
}) })
} }
...@@ -112,7 +112,7 @@ export function getCharacterView(params) { ...@@ -112,7 +112,7 @@ export function getCharacterView(params) {
export function getCharacterFundSource(params) { export function getCharacterFundSource(params) {
return request({ return request({
method: 'GET', method: 'GET',
url: `/api/personHomepage/personFunds/${params.personId}/${params.year}`, url: `/api/personHomepage/personFunds/`,
params, params,
}) })
} }
...@@ -141,4 +141,62 @@ export function getCharacterRelatedEntity(params) { ...@@ -141,4 +141,62 @@ export function getCharacterRelatedEntity(params) {
url: `/api/personHomepage/personRelation/${params.personId}/${params.startTime}`, url: `/api/personHomepage/personRelation/${params.personId}/${params.startTime}`,
params, params,
}) })
}
// 获取人物教育履历
/**
* @param {personId}
* @header token
*/
export function getCharacterReducationResume(params) {
return request({
method: 'GET',
url: `/api/personHomepage/educationResume/${params.personId}`,
params,
})
}
export async function getFindingsReport(personId, params = {}) {
const queryParts = []
Object.entries(params).forEach(([key, value]) => {
if (value === undefined || value === null || value === '') return
if (Array.isArray(value)) {
value.forEach(v => {
queryParts.push(`${encodeURIComponent(key)}=${encodeURIComponent(v)}`)
})
} else {
queryParts.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
}
})
const queryString = queryParts.join('&')
const url = queryString
? `/api/personHomepage/findingsReport/${personId}?${queryString}`
: `/api/personHomepage/findingsReport/${personId}`
return request(url, { method: 'GET' })
}
/**
* 获取创新主体列表(大学/实验室/企业)
* @param {Object} params - 请求参数
* @param {string} params.arealist - 科技领域ID
* @param {number} params.currentPage - 当前页码(从0开始)
* @param {string} params.keywords - 搜索关键词
* @param {number} params.pageSize - 每页条数
* @param {string} params.subjectTypeId - 主体类型ID
* @returns {Promise} 返回列表数据
*/
export async function getSubjectList(params) {
return request('/api/innovateSubject/findListBySubjectTypeId', {
method: 'GET',
params
})
}
export function getareaType(params) {
return request({
method: 'GET',
url: `/api/commonDict/areaType`,
params
})
} }
\ No newline at end of file
...@@ -130,3 +130,14 @@ export function getBillPersonPoliContribution(params) { ...@@ -130,3 +130,14 @@ export function getBillPersonPoliContribution(params) {
url: `/api/billDeepDive/processAnalyze/xj/${params.id}/${params.personId}` url: `/api/billDeepDive/processAnalyze/xj/${params.id}/${params.personId}`
}) })
} }
// 根据法案ID和人物ID获取政治献金领域分布
/**
* @param {id, personId}
*/
export function getBillPersonPoliDomain(params) {
return request({
method: 'GET',
url: `/api/billDeepDive/processAnalyze/xjDomain/${params.id}/${params.personId}`
})
}
import request from "@/api/request.js";
const INTELLECTUAL_API = "/intelligent-api";
export class IntelligentResultWrapper<T> {
result: T;
status: string;
}
export class TextEntity {
text_span: string;
type: string;
}
// 智能化:提取文本实体
export function extractTextEntity(text: string): Promise<IntelligentResultWrapper<TextEntity[]>> {
return request({
url: `${INTELLECTUAL_API}/extract-entity`,
method: "POST",
data: {
text
}
});
}
...@@ -35,7 +35,7 @@ export function getHotNews() { ...@@ -35,7 +35,7 @@ export function getHotNews() {
export function getHotNewsByArea(params) { export function getHotNewsByArea(params) {
return request({ return request({
method: 'GET', method: 'GET',
url: `/api/news/hotNews`, url: `/api/news/hotAreaNews/${params.moduleId}`,
params params
}) })
} }
......
...@@ -72,6 +72,15 @@ service.interceptors.response.use( ...@@ -72,6 +72,15 @@ service.interceptors.response.use(
}, },
error => { error => {
console.log('err' + error) console.log('err' + error)
const isCanceledError =
error?.code === 'ERR_CANCELED' ||
error?.name === 'CanceledError' ||
error?.name === 'AbortError' ||
(typeof error?.message === 'string' && /canceled/i.test(error.message))
// 重复请求触发的取消不提示错误
if (isCanceledError) return Promise.reject(error)
// 处理token过期或无效的情况 // 处理token过期或无效的情况
if (error.response && (error.response.status === 401 || error.response.status === 403)) { if (error.response && (error.response.status === 401 || error.response.status === 403)) {
......
...@@ -2,74 +2,99 @@ import request from "@/api/request.js"; ...@@ -2,74 +2,99 @@ import request from "@/api/request.js";
// 全要素统计 // 全要素统计
export function getElementCount(params) { export function getElementCount(params) {
return request({ return request({
method: 'GET', method: "GET",
url: `/api/element/elementCount/${params.date}`, url: `/api/element/elementCount/${params.date}`
}) });
}
// 美对华科技要素打压遏制数量趋势
export function getElementSuppressTrend(params) {
return request({
method: "GET",
url: `/api/element/DomainContainmentTrend/${params.date}`,
params: {
domainId: params.domainId ? params.domainId : null
}
});
} }
// 最新动态 // 最新动态
export function getNewDynamics() { export function getNewDynamics() {
return request({ return request({
method: 'GET', method: "GET",
url: `/api/element/newDynamics`, url: `/api/element/newDynamics`
}) });
} }
// 美对我要素打压情况 // 美对我要素打压情况
/** /**
* @param {currentPage, pageSize} * @param {currentPage, pageSize}
*/ */
export function getElementSuppress(params) { export function getElementSuppress(params) {
return request({ return request({
method: 'GET', method: "GET",
url: `/api/element/elementSuppress/${params.date}`, url: `/api/element/elementSuppress/${params.date}`,
params params: {
}) elementId: params.elementId ? params.elementId : null,
page: params.currentPage,
pageSize: params.pageSize
}
});
} }
// 关键词云-上 // 关键词云-上
/** /**
* @param {date} * @param {date}
*/ */
export function getKeyWordUp(params) { export function getKeyWordUp(params) {
return request({ return request({
method: 'GET', method: "GET",
url: `/api/element/getKeyWordUp/${params.date}`, url: `/api/element/getKeyWordUp/${params.date}`,
}) params: {
elementId: params.elementId ? params.elementId : null
}
});
} }
// 美自身要素发展情况 // 美自身要素发展情况
/** /**
* @param {currentPage, pageSize} * @param {currentPage, pageSize}
*/ */
export function getElementDevelop(params) { export function getElementDevelop(params) {
return request({ return request({
method: 'GET', method: "GET",
url: `/api/element/elementDevelop/${params.date}`, url: `/api/element/elementDevelop/${params.date}`,
params params: {
}) elementId: params.elementId ? params.elementId : null,
page: params.currentPage,
pageSize: params.pageSize
}
});
} }
// 关键词云-下 // 关键词云-下
/** /**
* @param {currentPage, pageSize} * @param {currentPage, pageSize}
*/ */
export function getKeyWordDown(params) { export function getKeyWordDown(params) {
return request({ return request({
method: 'GET', method: "GET",
url: `/api/element/getKeyWordDown/${params.date}`, url: `/api/element/getKeyWordDown/${params.date}`,
}) params: {
elementId: params.elementId ? params.elementId : null
}
});
} }
// 通过id获取政令详细信息 // 通过id获取政令详细信息
/** /**
* @param {id} * @param {id}
*/ */
export function getOrderInfo(params) { export function getOrderInfo(params) {
return request({ return request({
method: 'GET', method: "GET",
url: `/api/element/getOrderInfo/${params.id}`, url: `/api/element/getOrderInfo/${params.id}`,
params params
}) });
} }
\ No newline at end of file
差异被折叠。
...@@ -103,6 +103,7 @@ const headerTitleClasses = computed(() => [ ...@@ -103,6 +103,7 @@ const headerTitleClasses = computed(() => [
border-bottom: 1px solid #ebeef5; border-bottom: 1px solid #ebeef5;
/* background-color: #f8fafc; */ /* background-color: #f8fafc; */
padding-left: 0; padding-left: 0;
// background: linear-gradient(180deg, rgb(231, 243, 255) 0%, rgba(231, 243, 255, 0) 100%);
} }
.header-left { .header-left {
...@@ -132,10 +133,10 @@ const headerTitleClasses = computed(() => [ ...@@ -132,10 +133,10 @@ const headerTitleClasses = computed(() => [
} }
.header-icon { .header-icon {
width: 20px; width: 22px;
height: 20px; height: 18px;
margin-left: 5px; margin-left: 5px;
margin-right: 19px; margin-right: 14px;
} }
.blue-title-block { .blue-title-block {
...@@ -148,14 +149,13 @@ const headerTitleClasses = computed(() => [ ...@@ -148,14 +149,13 @@ const headerTitleClasses = computed(() => [
.header-title { .header-title {
font-family: $base-font-family; font-family: $base-font-family;
font-size: $base-font-size; font-size: 20px;
font-weight: 700; font-weight: 700;
/* color: var(--color-main-active); */ /* color: var(--color-main-active); */
/* color: var(--base-color); */ /* color: var(--base-color); */
color: $base-color; color: $base-color;
line-height: 48px; line-height: 48px;
padding: 0 12px; // padding: 0 12px;
font-size: 20px;
} }
.header-title-primary { .header-title-primary {
......
...@@ -2,14 +2,14 @@ ...@@ -2,14 +2,14 @@
<div class="sider-tabs-wrapper"> <div class="sider-tabs-wrapper">
<div class="sider-item" <div class="sider-item"
:class="{'sider-item-active': sider.active}" :class="{'sider-item-active': sider.active}"
v-for="sider, index in siderList" :key="index" v-for="(sider, index) in siderList" :key="sider.name || index"
@click="handleClickSiderItem(sider)" @click="handleClickSiderItem(sider)"
> >
<div <div
class="sider-item-text text-primary-65-clor text-tip-1" class="sider-item-text text-primary-65-clor text-tip-1"
:class="{'sider-item-text-active': sider.active}">{{ sider.name }}</div> :class="{'sider-item-text-active': sider.active}">{{ sider.name }}</div>
<div class="sider-item-icon" v-show="sider.active"> <div class="sider-item-icon" v-show="sider.active">
<img src="./active-icon.svg" alt=""> <img src="./active-icon.svg" alt="" />
</div> </div>
</div> </div>
</div> </div>
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
const props = defineProps({ const props = defineProps({
siderList: { siderList: {
type: Array, type: Array,
default: [ default: () => [
{ {
name: '分析内容1', name: '分析内容1',
active: true active: true
......
...@@ -50,21 +50,38 @@ const props = defineProps({ ...@@ -50,21 +50,38 @@ const props = defineProps({
showAllBtn: { showAllBtn: {
type: Boolean, type: Boolean,
default: true default: true
},
// 当业务功能尚未实现时,点击右上角图标仅弹出统一提示
devTip: {
type: Boolean,
default: false
} }
}) })
const handleSave = () => { const handleSave = () => {
if (props.devTip) {
ElMessage.warning('当前功能正在开发中,敬请期待!')
return
}
ElMessage.success('保存当前内容') ElMessage.success('保存当前内容')
// emit('save') // emit('save')
} }
const handleDownload = () => { const handleDownload = () => {
if (props.devTip) {
ElMessage.warning('当前功能正在开发中,敬请期待!')
return
}
ElMessage.success('下载当前内容') ElMessage.success('下载当前内容')
// emit('download') // emit('download')
} }
const handleCollect = () => { const handleCollect = () => {
if (props.devTip) {
ElMessage.warning('当前功能正在开发中,敬请期待!')
return
}
ElMessage.success('收藏当前内容') ElMessage.success('收藏当前内容')
// emit('collect') // emit('collect')
......
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { size } from 'lodash';
import { ref, computed, watch, onMounted } from 'vue'; import { ref, computed, watch, onMounted } from 'vue';
// 组件属性 // 组件属性
...@@ -83,7 +82,7 @@ const processedSvgContent = computed(() => { ...@@ -83,7 +82,7 @@ const processedSvgContent = computed(() => {
}); });
} }
console.log(processed) // console.log(processed)
return processed; return processed;
}); });
......
...@@ -10,11 +10,10 @@ ...@@ -10,11 +10,10 @@
</div> </div>
<!-- <div class="more" @click="handleToMoreNews">{{ "更多 +" }}</div> --> <!-- <div class="more" @click="handleToMoreNews">{{ "更多 +" }}</div> -->
</div> </div>
<div class="msg-bubble-main"> <div class="msg-bubble-main" ref="scrollContainer">
<div class="message-bubble" v-for="(item, index) in messageList" :key="index" @click="handleClickPerson(item)"> <div class="message-bubble" v-for="(item, index) in displayList" :key="index" @click="handleClickPerson(item)">
<div class="avatar-container"> <div class="avatar-container">
<img :src="item[props.imageUrl] || avatarUser" :alt="item[props.name]" class="avatar" /> <img :src="item[props.imageUrl] || avatarUser" :alt="item[props.name]" class="avatar" />
<div class="avatar-containerOne" v-if="isRepublicanParty"> <div class="avatar-containerOne" v-if="isRepublicanParty">
<img src="./image2.png" alt="" class="avatar-imageOne" /> <img src="./image2.png" alt="" class="avatar-imageOne" />
</div> </div>
...@@ -35,27 +34,12 @@ ...@@ -35,27 +34,12 @@
</div> </div>
</div> </div>
</div> </div>
<!-- <MessageBubble v-for="(item, index) in messageList" @click="handleClickPsserson(item)"
@info-click="handleMediaClick(item)" :key="index" :avatar="item.img ? item.img : DefaultIcon1" :name="item.name"
:time="item.time" :source="item.source" :content="item.content" /> -->
<!-- <div class="msg-bubble-main-item" v-for="(item, index) in messageList" :key="index">
<div class="left" @click="handleClickPerson(item)">
<img :src="item.img ? item.img : DefaultIcon1" alt="" />
</div>
<div class="right">
<div class="right-top">
<div class="name">{{ item.name }}</div>
<div class="time">{{ item.time }}</div>
</div>
<div class="content">{{ item.content }}</div>
</div>
</div> -->
</div> </div>
</div> </div>
</template> </template>
<script setup> <script setup>
import { computed } from "vue"; import { ref, computed, onMounted, onBeforeUnmount } from "vue";
import avatarUser from "@/assets/images/avatar_user.png"; import avatarUser from "@/assets/images/avatar_user.png";
const emit = defineEmits(["click", "info-click"]); const emit = defineEmits(["click", "info-click"]);
...@@ -118,6 +102,66 @@ const handleInfoClick = item => { ...@@ -118,6 +102,66 @@ const handleInfoClick = item => {
const handleToMoreNews = item => { const handleToMoreNews = item => {
emit("more-click", item); emit("more-click", item);
}; };
const scrollContainer = ref(null)
let timer = null
const currentIndex = ref(0)
// const itemHeight = ref(80) // 每条消息的高度,需要根据实际调整
// 计算当前显示的消息列表(只显示固定数量的消息)
const displayList = computed(() => {
if(props.messageList.length < 4) {
return props.messageList
}
// 确保 messageList 存在且有数据
if (!props.messageList || !Array.isArray(props.messageList) || props.messageList.length === 0) {
return []
}
const list = []
const totalLength = props.messageList.length
for (let i = 0; i < 3; i++) {
// 计算当前索引,确保不会超出数组长度
const index = (currentIndex.value + i) % totalLength
const item = props.messageList[index]
// 确保 item 存在再添加到列表
if (item) {
list.push(item)
}
}
return list
})
// 开始滚动
const startScroll = () => {
if (timer) clearInterval(timer)
timer = setInterval(() => {
currentIndex.value = (currentIndex.value + 1) % props.messageList.length
}, 2000) // 每秒滚动一条
}
// 停止滚动
const stopScroll = () => {
if (timer) {
clearInterval(timer)
timer = null
}
}
onMounted(() => {
if (props.messageList.length > 3) {
startScroll()
}
})
onBeforeUnmount(() => {
stopScroll()
})
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
...@@ -180,7 +224,7 @@ const handleToMoreNews = item => { ...@@ -180,7 +224,7 @@ const handleToMoreNews = item => {
.msg-bubble-main { .msg-bubble-main {
height: 402px; height: 402px;
overflow-y: auto; overflow: hidden;
box-sizing: border-box; box-sizing: border-box;
padding-bottom: 8px; padding-bottom: 8px;
padding-left: 21px; padding-left: 21px;
...@@ -190,6 +234,8 @@ const handleToMoreNews = item => { ...@@ -190,6 +234,8 @@ const handleToMoreNews = item => {
display: flex; display: flex;
max-width: 740px; max-width: 740px;
margin-bottom: 15px; margin-bottom: 15px;
transition: transform 2s ease;
/* 可选:添加平滑动画 */
.avatar-container { .avatar-container {
flex-shrink: 0; flex-shrink: 0;
...@@ -317,6 +363,18 @@ const handleToMoreNews = item => { ...@@ -317,6 +363,18 @@ const handleToMoreNews = item => {
} }
} }
// .msg-bubble-main {
// height: 400px; /* 设置固定高度 */
// overflow: hidden;
// position: relative;
// }
// .message-bubble {
// transition: transform 0.3s ease; /* 可选:添加平滑动画 */
// height: 80px; /* 固定每条消息高度 */
// margin-bottom: 10px; /* 消息之间的间距 */
// }
/* 响应式设计 */ /* 响应式设计 */
@media (max-width: 768px) { @media (max-width: 768px) {
.message-bubble { .message-bubble {
......
...@@ -9,14 +9,9 @@ ...@@ -9,14 +9,9 @@
<SearchBar v-show="isShowSearchBar" /> <SearchBar v-show="isShowSearchBar" />
<div class="title-box" v-show="!isShowSearchBar"> <div class="title-box" v-show="!isShowSearchBar">
<!-- <div class="title-box" v-if="false"> --> <!-- <div class="title-box" v-if="false"> -->
<div <div class="title" v-for="(item, index) in homeTitleList" :key="index"
class="title" @mouseenter="handleShowMenu(index, true)" @mouseleave="handleShowMenu(index, false)"
v-for="(item, index) in homeTitleList" @click="handleClickTitle(item)">
:key="index"
@mouseenter="handleShowMenu(index, true)"
@mouseleave="handleShowMenu(index, false)"
@click="handleClickTitle(item)"
>
<div class="text" :class="{ textActive: homeActiveTitleIndex === index }"> <div class="text" :class="{ textActive: homeActiveTitleIndex === index }">
{{ item.name }} {{ item.name }}
</div> </div>
...@@ -36,7 +31,8 @@ ...@@ -36,7 +31,8 @@
<div class="name">{{ "管理员" }}</div> <div class="name">{{ "管理员" }}</div>
</div> </div>
</div> </div>
<div class="menu-box" v-show="isShowMenu" @mouseenter="handleHoverMenu(true)" @mouseleave="handleHoverMenu(false)"> <div class="menu-box" v-show="isShowMenu" @mouseenter="handleHoverMenu(true)"
@mouseleave="handleHoverMenu(false)">
<div class="menu-content"> <div class="menu-content">
<div class="menu-item" v-for="(item, index) in menuList" :key="index" @click="handleToModule(item)"> <div class="menu-item" v-for="(item, index) in menuList" :key="index" @click="handleToModule(item)">
<div class="icon"> <div class="icon">
...@@ -90,7 +86,7 @@ const handleGetPersonType = async () => { ...@@ -90,7 +86,7 @@ const handleGetPersonType = async () => {
personTypeList.value = []; personTypeList.value = [];
} }
window.sessionStorage.setItem("personTypeList", JSON.stringify(personTypeList.value)); window.sessionStorage.setItem("personTypeList", JSON.stringify(personTypeList.value));
} catch (error) {} } catch (error) { }
}; };
// 概览页标题列表 // 概览页标题列表
...@@ -230,6 +226,7 @@ onMounted(() => { ...@@ -230,6 +226,7 @@ onMounted(() => {
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1); box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: linear-gradient(180deg, rgba(246, 250, 255, 0.8) 0%, rgba(255, 255, 255, 0.8) 100%); background: linear-gradient(180deg, rgba(246, 250, 255, 0.8) 0%, rgba(255, 255, 255, 0.8) 100%);
padding: 12px 0; padding: 12px 0;
.nav-content { .nav-content {
width: 1600px; width: 1600px;
margin: 0 auto; margin: 0 auto;
...@@ -237,11 +234,14 @@ onMounted(() => { ...@@ -237,11 +234,14 @@ onMounted(() => {
justify-content: space-between; justify-content: space-between;
position: relative; position: relative;
align-items: flex-start; align-items: flex-start;
.nav-left { .nav-left {
display: flex; display: flex;
align-items: center; align-items: center;
&.flex-start { &.flex-start {
align-items: flex-start; align-items: flex-start;
.icon { .icon {
flex-shrink: 0; flex-shrink: 0;
width: 48px; width: 48px;
...@@ -251,16 +251,19 @@ onMounted(() => { ...@@ -251,16 +251,19 @@ onMounted(() => {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
img { img {
width: 29px; width: 29px;
height: 30px; height: 30px;
} }
} }
} }
.icon { .icon {
width: 29px; width: 29px;
height: 30px; height: 30px;
margin-right: 17px; margin-right: 17px;
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
...@@ -274,6 +277,7 @@ onMounted(() => { ...@@ -274,6 +277,7 @@ onMounted(() => {
.title { .title {
cursor: pointer; cursor: pointer;
position: relative; position: relative;
&:hover { &:hover {
.text { .text {
color: var(--color-main-active); color: var(--color-main-active);
...@@ -299,6 +303,7 @@ onMounted(() => { ...@@ -299,6 +303,7 @@ onMounted(() => {
width: 90%; width: 90%;
height: 20px; height: 20px;
margin-top: 9px; margin-top: 9px;
&::after { &::after {
display: block; display: block;
content: ""; content: "";
...@@ -365,23 +370,35 @@ onMounted(() => { ...@@ -365,23 +370,35 @@ onMounted(() => {
} }
.menu-box { .menu-box {
// position: absolute;
// z-index: 999999999;
// width: 713px;
// height: 413px;
// top: 52px;
// left: 0;
// box-sizing: border-box;
// border-radius: 10px;
// backdrop-filter: blur(10px);
// -webkit-backdrop-filter: blur(10px);
// box-shadow: 0px 8px 32px 0px rgba(31, 38, 135, 0.15);
// background: rgba(255, 255, 255, 0.25);
// backdrop-filter: blur(10px);
// -webkit-backdrop-filter: blur(10px);
// border: 1px solid rgba(255, 255, 255, 0.3);
// background: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.2) 100%);
// box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.2);
position: absolute; position: absolute;
z-index: 999999999; z-index: 999999;
width: 713px; width: 713px;
height: 413px; height: 413px;
top: 52px; top: 52px;
left: 0; left: -2px;
box-sizing: border-box; box-sizing: border-box;
border: 1px solid rgba(255, 255, 255, 1);
border-radius: 10px; border-radius: 10px;
backdrop-filter: blur(10px); backdrop-filter: blur(30px);
-webkit-backdrop-filter: blur(10px); box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
box-shadow: 0px 8px 32px 0px rgba(31, 38, 135, 0.15); background: rgba(255, 255, 255, 0.8);
background: rgba(255, 255, 255, 0.25);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.3);
background: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.2) 100%);
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.2);
.menu-content { .menu-content {
width: 562px; width: 562px;
......
<template> <template>
<div class="box3-item" @click="handleToNewsAnalysis(news)"> <el-space alignment="flex-start" :size="10">
<div class="left"> <img :width="64" :height="52" :src="news ?? DefaultIconNews" alt="" />
<img :src="news[props.img] ? news[props.img] : DefaultIconNews" alt="" /> <el-space direction="vertical" alignment="flex-start" :size="0">
</div> <common-text :line-limit="1" class="text-regular text-hover" color="var(--text-primary-80-color)">
<div class="right"> {{ title }}
<div class="right-top"> </common-text>
<div class="title"><span class="text-inner">{{ news[props.title] }}</span></div> <common-text :line-limit="1" class="text-tip-1" color="var(--text-primary-65-color)">
<div class="time">{{ news[props.from] }}</div> {{ from }}
</div> </common-text>
<div class="right-footer">{{ news[props.content] }}</div> </el-space>
</div> </el-space>
</div>
</template> </template>
<script setup> <script setup>
import DefaultIconNews from "@/assets/icons/default-icon-news.png"; import DefaultIconNews from "@/assets/icons/default-icon-news.png";
const props = defineProps({ import { ElSpace } from "element-plus";
import CommonText from "../texts/CommonText.vue";
// 新闻列表数据
news: {
type: Object,
default: () => { }
},
const props = defineProps({
img: { img: {
type: String, type: String,
default: 'img' default: ''
}, },
title: { title: {
type: String, type: String,
default: "title" default: ""
}, },
from: { from: {
type: String, type: String,
default: "from" default: ""
}, },
content: { content: {
type: String, type: String,
default: "content" default: ""
}, },
}); });
...@@ -49,72 +44,4 @@ const handleToNewsAnalysis = (item, index) => { ...@@ -49,72 +44,4 @@ const handleToNewsAnalysis = (item, index) => {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@use '@/styles/common.scss'; @use '@/styles/common.scss';
.box3-item {
display: flex;
align-items: center;
height: 78px;
margin: 0px 21px;
cursor: pointer;
&:hover {
.right-top .title {
color: rgb(5, 95, 194) !important;
font-weight: 700;
}
.right-top .text-inner {
border-bottom-color: rgb(5, 95, 194) !important;
}
}
}
.left {
width: 97px;
// flex-shrink: 0;
height: 72px;
img {
width: 100%;
height: 100%;
border-radius: 4px;
}
}
.right {
flex: 1;
min-width: 0;
margin-left: 20px;
.right-top {
display: flex;
justify-content: space-between;
.title {
// width: 500px;
@extend .text-title-3-bold;
color: var(--text-primary-80-color);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
.text-inner {
border-bottom: 1px solid transparent;
}
}
.time {
text-align: right;
@extend .text-tip-2;
color: var(--text-primary-65-color);
}
}
.right-footer {
@extend .text-compact;
color: var(--text-primary-65-color);
@include common.text-ellipsis(2);
}
}
</style> </style>
\ No newline at end of file
<template> <template>
<div class="common-text"> <div class="common-text-box-hudf">
<slot></slot> <slot></slot>
</div> </div>
</template> </template>
...@@ -18,8 +18,8 @@ const props = defineProps({ ...@@ -18,8 +18,8 @@ const props = defineProps({
<style lang="scss" scoped> <style lang="scss" scoped>
@use '@/styles/common.scss'; @use '@/styles/common.scss';
.common-text { .common-text-box-hudf {
color: v-bind(color); color: v-bind(color) !important;
@if('v-bind(lineLimit) !==null') { @if('v-bind(lineLimit) !==null') {
@include common.text-ellipsis(v-bind(lineLimit)); @include common.text-ellipsis(v-bind(lineLimit));
......
<template>
<p class="p-regular-rereg">
<span class="text-regular" v-for="(segment, index) in processedText" :key="index">
<a v-if="segment.isEntity" :href="`https://cn.bing.com/search?q=${segment.entity?.text_span}`"
class="entity-link" target="_blank" rel="noopener noreferrer">
{{ segment.entity?.text_span }}
<img :src="SearchIcon" :width="10" :height="10" alt="search" />
</a>
<span v-else>
{{ segment.text }}
</span>
</span>
</p>
</template>
<script lang="ts" setup>
import { TextEntity } from '@/api/intelligent';
import { ref, watch, onMounted } from 'vue';
import SearchIcon from './images/search.png'
export interface ProcessedTextSegment {
text: string
isEntity: boolean
entity?: TextEntity
}
const props = defineProps({
text: {
type: String,
default: ''
}
, entities: {
type: Array<TextEntity>,
default: () => []
}
})
// 处理后的文本段
const processedText = ref<ProcessedTextSegment[]>([])
// 处理文本,识别并替换实体
const processText = () => {
if (!props.text || !props.entities) {
console.log('props.text', props.entities.length)
processedText.value = [{ text: '', isEntity: false }]
return
}
const result = []
let currentPosition = 0
// 按实体文本长度排序,优先匹配长文本
const sortedEntities = [...props.entities].sort((a, b) =>
b.text_span.length - a.text_span.length
)
while (currentPosition < props.text.length) {
let matched = false
for (const entity of sortedEntities) {
const entityText = entity.text_span
const endPosition = currentPosition + entityText.length
if (props.text.substring(currentPosition, endPosition) === entityText) {
// 如果当前位置是实体,添加到结果
result.push({
isEntity: true,
entity: { ...entity }
})
currentPosition = endPosition
matched = true
break
}
}
if (!matched) {
// 如果不是实体,收集普通文本
let nextEntityStart = props.text.length
for (const entity of sortedEntities) {
const pos = props.text.indexOf(entity.text_span, currentPosition)
if (pos !== -1 && pos < nextEntityStart) {
nextEntityStart = pos
}
}
if (nextEntityStart > currentPosition) {
const plainText = props.text.substring(currentPosition, nextEntityStart)
result.push({
text: plainText,
isEntity: false
})
currentPosition = nextEntityStart
} else {
// 没有更多实体,添加剩余文本
const remainingText = props.text.substring(currentPosition)
if (remainingText) {
result.push({
text: remainingText,
isEntity: false
})
}
currentPosition = props.text.length
}
}
}
processedText.value = result
}
// 监听文本和实体变化
watch(() => props.text, processText)
watch(() => props.entities, processText, { deep: true })
// 初始化处理
onMounted(processText)
</script>
<style lang="scss" scoped>
@use '@/styles/common.scss';
.entity-link {
color: var(--color-primary-100);
}
.p-regular-rereg {
text-indent: 2em;
}
</style>
\ No newline at end of file
...@@ -13,6 +13,7 @@ const BillInfluenceLayout = () => import('@/views/bill/influence/index.vue') ...@@ -13,6 +13,7 @@ const BillInfluenceLayout = () => import('@/views/bill/influence/index.vue')
const BillInfluenceIndustry = () => import('@/views/bill/influence/industry/index.vue') const BillInfluenceIndustry = () => import('@/views/bill/influence/industry/index.vue')
const BillInfluenceScientificResearch = () => import('@/views/bill/influence/scientificResearch/index.vue') const BillInfluenceScientificResearch = () => import('@/views/bill/influence/scientificResearch/index.vue')
const BillRelevantCircumstance = () => import('@/views/bill/relevantCircumstance/index.vue') const BillRelevantCircumstance = () => import('@/views/bill/relevantCircumstance/index.vue')
const BillOriginalText = () => import('@/views/bill/billOriginalText/index.vue')
const billRoutes = [ const billRoutes = [
...@@ -35,6 +36,14 @@ const billRoutes = [ ...@@ -35,6 +36,14 @@ const billRoutes = [
dynamicTitle: true // 标记需要动态设置标题 dynamicTitle: true // 标记需要动态设置标题
}, },
children: [ children: [
{
path: "originalText",
name: "BillOriginalText",
component: BillOriginalText,
meta: {
title: "法案原文"
}
},
// 法案分析路由 // 法案分析路由
{ {
path: "bill", path: "bill",
......
...@@ -71,6 +71,13 @@ ...@@ -71,6 +71,13 @@
color: var(--text-primary-80); color: var(--text-primary-80);
} }
.text-hover {
&:hover {
color: rgb(5, 95, 194) !important;
font-weight: 700;
}
}
//0级标题 //0级标题
.text-title-0 { .text-title-0 {
@extend .text-base; @extend .text-base;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
<div class="text-title-1-show">文字样式</div> <div class="text-title-1-show">文字样式</div>
<TextStyle /> <TextStyle />
<div class="text-title-1-show">通用样式/组件</div> <div class="text-title-1-show">通用样式/组件</div>
<div style="position: relative; min-height: 300px;"> <div style="position: relative; min-height: 700px;">
<el-tabs tabPosition="left" class="tabs-nav-no-wrap left-float-nav-tabs"> <el-tabs tabPosition="left" class="tabs-nav-no-wrap left-float-nav-tabs">
<el-tab-pane label="通用" lazy> <el-tab-pane label="通用" lazy>
<common-page /> <common-page />
......
// 绘制echarts图表 // 绘制echarts图表
import * as echarts from 'echarts' import * as echarts from 'echarts'
import 'echarts-wordcloud';
const setChart = (option, chartId) => { const setChart = (option, chartId) => {
let chartDom = document.getElementById(chartId); let chartDom = document.getElementById(chartId);
if (!chartDom) { if (!chartDom) {
......
...@@ -141,12 +141,30 @@ ...@@ -141,12 +141,30 @@
@page-change="handleNewsPageChange" @page-change="handleNewsPageChange"
/> />
</div> </div>
<!-- <custom-container title="美对华领域打压遏制排行" :titleIcon="icon3" height="700px">
<template #header-right>
<div class="title-right-select">
<el-select
v-model="selectedField"
@change="handleFieldChange"
placeholder="全部领域"
class="field-select"
:style="{ width: '160px' }"
>
<el-option v-for="item in fieldOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</div>
</template>
</custom-container> -->
<div class="empty-section"> <div class="empty-section">
<div class="bottom-item"> <div class="bottom-item">
<div class="bottom-item-title"> <div class="bottom-item-title">
<img :src="icon3" alt="" /> <img :src="icon3" alt="" />
<span>美对华领域打压遏制排行</span> <span>美对华领域打压遏制排行</span>
</div> </div>
<el-select v-model="selectedField" placeholder="全部领域" class="field-select">
<el-option v-for="item in fieldOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</div> </div>
<div class="select-box"> <div class="select-box">
<div class="rank-btns"> <div class="rank-btns">
...@@ -160,13 +178,18 @@ ...@@ -160,13 +178,18 @@
受打压院校 受打压院校
</div> </div>
</div> </div>
<el-select v-model="selectedField" placeholder="全部领域" class="field-select">
<el-option v-for="item in fieldOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</div> </div>
<div class="main-box" v-loading="rankLoading" element-loading-background="rgba(255, 255, 255, 0.5)"> <div class="main-box" v-loading="rankLoading" element-loading-background="rgba(255, 255, 255, 0.5)">
<!-- 机构排行的原有样式 -->
<template v-if="rankType === 'institution'"> <template v-if="rankType === 'institution'">
<div class="table-header">
<div class="col-rank col-rank-75"></div>
<div class="col-name" style="color: rgb(59, 65, 75); font-weight: 700">部门名称</div>
<div class="col-domain" style="color: rgb(59, 65, 75); font-weight: 700"></div>
<div class="col-date" style="color: rgb(59, 65, 75); font-weight: 700"></div>
<div class="col-member" v-if="rankType !== 'school'" style="color: rgb(59, 65, 75); font-weight: 700">
打压次数
</div>
</div>
<div v-for="(item, index) in rankList" :key="index" class="rank-item"> <div v-for="(item, index) in rankList" :key="index" class="rank-item">
<div class="rank-num" :class="'rank-' + (index + 1)">{{ index + 1 }}</div> <div class="rank-num" :class="'rank-' + (index + 1)">{{ index + 1 }}</div>
<img :src="item.orgPicture ? item.orgPicture : defaultImg" alt="" class="rank-icon" /> <img :src="item.orgPicture ? item.orgPicture : defaultImg" alt="" class="rank-icon" />
...@@ -177,7 +200,6 @@ ...@@ -177,7 +200,6 @@
<div class="rank-count">{{ item.count }}</div> <div class="rank-count">{{ item.count }}</div>
</div> </div>
</template> </template>
<!-- 企业/院校排行的表格样式 -->
<template v-else> <template v-else>
<div class="table-header"> <div class="table-header">
<div class="col-rank"></div> <div class="col-rank"></div>
...@@ -210,7 +232,6 @@ ...@@ -210,7 +232,6 @@
</div> </div>
</div> </div>
<div class="col-date">{{ item.date }}</div> <div class="col-date">{{ item.date }}</div>
<!-- <div class="col-member" v-if="rankType !== 'school'">{{ item.member }}</div> -->
<div class="col-member" v-if="rankType !== 'school'">{{ item.province }}</div> <div class="col-member" v-if="rankType !== 'school'">{{ item.province }}</div>
</div> </div>
</div> </div>
...@@ -315,10 +336,13 @@ import getMultiLineChart from "./multiLineChart"; ...@@ -315,10 +336,13 @@ import getMultiLineChart from "./multiLineChart";
import CommonPrompt from "../../../../commonPrompt/index.vue"; import CommonPrompt from "../../../../commonPrompt/index.vue";
import leftBtn from "../../assets/left-btn.png"; import leftBtn from "../../assets/left-btn.png";
import rightBtn from "../../assets/right-btn.png"; import rightBtn from "../../assets/right-btn.png";
import icon1 from "./icon/icon-1.png";
import icon3 from "./icon/icon-3.png"; import icon3 from "./icon/icon-3.png";
import icon4 from "./icon/icon-4.png"; import icon4 from "./icon/icon-4.png";
import defaultImg from "../../../../assets/images/default-icon2.png"; import defaultImg from "../../../../assets/images/default-icon2.png";
import { fieldOptions } from "@/views/ZMOverView/public.js";
import { import {
getAllDomainCount, getAllDomainCount,
getDomainContainmentTrend, getDomainContainmentTrend,
...@@ -330,6 +354,7 @@ import { getUSGovernmentLatestDynamic, getDepartmentList, getSanTypeList } from ...@@ -330,6 +354,7 @@ import { getUSGovernmentLatestDynamic, getDepartmentList, getSanTypeList } from
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import { ArrowLeft, ArrowRight } from "@element-plus/icons-vue"; import { ArrowLeft, ArrowRight } from "@element-plus/icons-vue";
import SimplePagination from "@/components/SimplePagination.vue"; import SimplePagination from "@/components/SimplePagination.vue";
import CustomContainer from "@/components/Container/index.vue";
const router = useRouter(); const router = useRouter();
...@@ -752,23 +777,23 @@ const svgHeight = computed(() => { ...@@ -752,23 +777,23 @@ const svgHeight = computed(() => {
return startY + rows * rowHeight + 50; return startY + rows * rowHeight + 50;
}); });
const fieldOptions = [ // const fieldOptions = [
{ value: "", label: "全部领域" }, // { value: "", label: "全部领域" },
{ value: "1", label: "人工智能" }, // { value: "1", label: "人工智能" },
{ value: "2", label: "生物科技" }, // { value: "2", label: "生物科技" },
{ value: "3", label: "新一代信息技术" }, // { value: "3", label: "新一代信息技术" },
{ value: "4", label: "量子科技" }, // { value: "4", label: "量子科技" },
{ value: "5", label: "新能源" }, // { value: "5", label: "新能源" },
{ value: "6", label: "集成电路" }, // { value: "6", label: "集成电路" },
{ value: "7", label: "海洋" }, // { value: "7", label: "海洋" },
{ value: "8", label: "先进制造" }, // { value: "8", label: "先进制造" },
{ value: "9", label: "新材料" }, // { value: "9", label: "新材料" },
{ value: "10", label: "航空航天" }, // { value: "10", label: "航空航天" },
{ value: "11", label: "深海" }, // { value: "11", label: "深海" },
{ value: "12", label: "极地" }, // { value: "12", label: "极地" },
{ value: "13", label: "太空" }, // { value: "13", label: "太空" },
{ value: "14", label: "核" } // { value: "14", label: "核" }
]; // ];
// 全领域统计 // 全领域统计
const buttonsData = ref([]); const buttonsData = ref([]);
...@@ -1614,8 +1639,8 @@ watch(activeDate, () => { ...@@ -1614,8 +1639,8 @@ watch(activeDate, () => {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
padding-left: 17px; padding-left: 16px;
padding-right: 35px; padding-right: 16px;
box-sizing: border-box; box-sizing: border-box;
background: linear-gradient(180deg, rgba(231, 243, 255, 1) 0%, rgba(231, 243, 255, 0) 100%); background: linear-gradient(180deg, rgba(231, 243, 255, 1) 0%, rgba(231, 243, 255, 0) 100%);
.bottom-item-title { .bottom-item-title {
...@@ -1634,14 +1659,19 @@ watch(activeDate, () => { ...@@ -1634,14 +1659,19 @@ watch(activeDate, () => {
color: rgb(5, 95, 194); color: rgb(5, 95, 194);
} }
} }
.field-select {
width: 160px;
}
} }
.select-box { .select-box {
width: 691px; width: 691px;
height: 32px; height: 50px;
margin: 10px auto 5px auto; margin: 10px auto 5px auto;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
border-bottom: 1px solid #eee;
padding-bottom: 15px;
.rank-btns { .rank-btns {
display: flex; display: flex;
...@@ -1698,7 +1728,7 @@ watch(activeDate, () => { ...@@ -1698,7 +1728,7 @@ watch(activeDate, () => {
box-sizing: border-box; box-sizing: border-box;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 28px; gap: 21px;
overflow-y: auto; overflow-y: auto;
.rank-item { .rank-item {
display: flex; display: flex;
...@@ -1910,6 +1940,9 @@ watch(activeDate, () => { ...@@ -1910,6 +1940,9 @@ watch(activeDate, () => {
text-align: center; text-align: center;
flex-shrink: 0; flex-shrink: 0;
} }
.col-rank-75 {
width: 75px;
}
.col-name { .col-name {
flex: 1.5; flex: 1.5;
min-width: 0; min-width: 0;
......
{
"code": 200,
"message": "操作成功",
"success": true,
"data": [
{
"elementName": "科研机构",
"elementNum": 0,
"elementDate": "2025-01"
},
{
"elementName": "科研人才",
"elementNum": 1,
"elementDate": "2025-01"
},
{
"elementName": "科研仪器",
"elementNum": 0,
"elementDate": "2025-01"
},
{
"elementName": "科研机构",
"elementNum": 0,
"elementDate": "2025-02"
},
{
"elementName": "科研人才",
"elementNum": 0,
"elementDate": "2025-02"
},
{
"elementName": "科研仪器",
"elementNum": 1,
"elementDate": "2025-02"
},
{
"elementName": "科研机构",
"elementNum": 0,
"elementDate": "2025-03"
},
{
"elementName": "科研人才",
"elementNum": 0,
"elementDate": "2025-03"
},
{
"elementName": "科研仪器",
"elementNum": 0,
"elementDate": "2025-03"
},
{
"elementName": "科研机构",
"elementNum": 1,
"elementDate": "2025-04"
},
{
"elementName": "科研人才",
"elementNum": 0,
"elementDate": "2025-04"
},
{
"elementName": "科研仪器",
"elementNum": 0,
"elementDate": "2025-04"
},
{
"elementName": "科研机构",
"elementNum": 0,
"elementDate": "2025-05"
},
{
"elementName": "科研人才",
"elementNum": 1,
"elementDate": "2025-05"
},
{
"elementName": "科研仪器",
"elementNum": 0,
"elementDate": "2025-05"
},
{
"elementName": "科研机构",
"elementNum": 0,
"elementDate": "2025-06"
},
{
"elementName": "科研人才",
"elementNum": 0,
"elementDate": "2025-06"
},
{
"elementName": "科研仪器",
"elementNum": 0,
"elementDate": "2025-06"
},
{
"elementName": "科研机构",
"elementNum": 0,
"elementDate": "2025-07"
},
{
"elementName": "科研人才",
"elementNum": 0,
"elementDate": "2025-07"
},
{
"elementName": "科研仪器",
"elementNum": 3,
"elementDate": "2025-07"
},
{
"elementName": "科研机构",
"elementNum": 0,
"elementDate": "2025-08"
},
{
"elementName": "科研人才",
"elementNum": 0,
"elementDate": "2025-08"
},
{
"elementName": "科研仪器",
"elementNum": 0,
"elementDate": "2025-08"
},
{
"elementName": "科研机构",
"elementNum": 0,
"elementDate": "2025-09"
},
{
"elementName": "科研人才",
"elementNum": 0,
"elementDate": "2025-09"
},
{
"elementName": "科研仪器",
"elementNum": 0,
"elementDate": "2025-09"
},
{
"elementName": "科研机构",
"elementNum": 0,
"elementDate": "2025-10"
},
{
"elementName": "科研人才",
"elementNum": 0,
"elementDate": "2025-10"
},
{
"elementName": "科研仪器",
"elementNum": 0,
"elementDate": "2025-10"
},
{
"elementName": "科研机构",
"elementNum": 0,
"elementDate": "2025-11"
},
{
"elementName": "科研人才",
"elementNum": 0,
"elementDate": "2025-11"
},
{
"elementName": "科研仪器",
"elementNum": 0,
"elementDate": "2025-11"
},
{
"elementName": "科研机构",
"elementNum": 0,
"elementDate": "2025-12"
},
{
"elementName": "科研人才",
"elementNum": 0,
"elementDate": "2025-12"
},
{
"elementName": "科研仪器",
"elementNum": 0,
"elementDate": "2025-12"
},
{
"elementName": "科研机构",
"elementNum": 0,
"elementDate": "2026-01"
},
{
"elementName": "科研人才",
"elementNum": 0,
"elementDate": "2026-01"
},
{
"elementName": "科研仪器",
"elementNum": 0,
"elementDate": "2026-01"
},
{
"elementName": "科研机构",
"elementNum": 0,
"elementDate": "2026-02"
},
{
"elementName": "科研人才",
"elementNum": 0,
"elementDate": "2026-02"
},
{
"elementName": "科研仪器",
"elementNum": 0,
"elementDate": "2026-02"
},
{
"elementName": "科研机构",
"elementNum": 0,
"elementDate": "2026-03"
},
{
"elementName": "科研人才",
"elementNum": 0,
"elementDate": "2026-03"
},
{
"elementName": "科研仪器",
"elementNum": 0,
"elementDate": "2026-03"
}
]
}
\ No newline at end of file
No preview for this file type
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论