Merge branch 'master' of https://gitcode.com/hk_openRepo/OpenRepo_Portal into junjie_dev
# Conflicts: # src/views/Jyh/Home/index.vue
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
<div class="home-container">
|
||||
<div class="home-content">
|
||||
<div class="home-title">
|
||||
<img src="@/assets/imgs/home/home-title-logo-2x.webp" alt="logo" />
|
||||
<img src="@/assets/imgs/logo.png" alt="logo" />
|
||||
<h1>可信开源代码库</h1>
|
||||
</div>
|
||||
<div class="home-search" ref="homeSearch" :class="{ 'glow-border': inputGlow }">
|
||||
@@ -54,14 +54,14 @@
|
||||
</d-dropdown-menu>
|
||||
<d-button color="primary" variant="solid" @click="search">搜索</d-button>
|
||||
</div>
|
||||
<d-button v-if="userStore.isLogin" @click="check" ref="origin" icon="share" class="batch-btn">批量校验</d-button>
|
||||
<d-button @click="check" ref="origin" icon="share" class="batch-btn">批量校验</d-button>
|
||||
<div class="home-information">
|
||||
<div class="info-title">
|
||||
<div class="sub-title">
|
||||
<img src="@/assets/imgs/home/informIcon@2x.png">
|
||||
<span>信息公示</span>
|
||||
<span>预警公告</span>
|
||||
</div>
|
||||
<a class="devui-link" @click="checkMore">更多 ></a>
|
||||
<a v-if="isLogin" class="devui-link" @click="checkMore">更多 ></a>
|
||||
</div>
|
||||
<div class="info-content">
|
||||
<d-timeline :direction="'vertical'" :time-position="'right'" :position="'right'">
|
||||
@@ -71,11 +71,11 @@
|
||||
<div class="flex items-center justify-between w-full">
|
||||
<div class="cursor-pointer notice-content flex gap-2 items-center" @click="openWarningDetail(item, index)">
|
||||
<span>{{ item.subject }}</span>
|
||||
<d-tag v-if="item.importance" :color="tagMap[item.importance]?.color" size="sm">{{ tagMap[item.importance]?.text }}</d-tag>
|
||||
<d-tag :color="tagMap[item.importance]" size="sm">{{ item.importance }}</d-tag>
|
||||
</div>
|
||||
<div class="time-container">
|
||||
<d-icon name="icon-time"></d-icon>
|
||||
<span>{{ item.publishTime }}</span>
|
||||
{{ item.pulishTime }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -89,7 +89,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<d-modal class="warning-modal" v-model="warningModalVisable" title="主题:" style="width: 600px;">
|
||||
<d-modal class="warning-modal" v-model="warningModalVisable" title="" style="width: 600px;">
|
||||
<EarlyWarningDetail :warningData="currentWarning" :type="'user'"></EarlyWarningDetail>
|
||||
</d-modal>
|
||||
</template>
|
||||
@@ -100,9 +100,10 @@ import { useRoute, useRouter } from 'vue-router';
|
||||
import AdvanceSearch from '@/components/AdvanceSearch/index.vue';
|
||||
import { getHomeNoticeList } from '@/api/jyh'
|
||||
import EarlyWarningDetail from '@/views/Jyh/PersonalCenter/Detail/EarlyWarningDetail.vue';
|
||||
import { useAccountStore } from '@/stores/user';
|
||||
import { useDiscussGetUserInfo } from '@/api/discussion/hook';
|
||||
|
||||
const userStore = useAccountStore();
|
||||
// 获取当前用户信息 & 是否登录
|
||||
const { isLogin = false, userInfo = {}} = useDiscussGetUserInfo();
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const inputGlow = ref(false);
|
||||
@@ -123,22 +124,9 @@ const homeSearch = ref(null);
|
||||
const dropdownWidth = ref(0);
|
||||
const selectedCate = ref('软件');
|
||||
const tagMap = {
|
||||
'Critical': {
|
||||
text: '致命',
|
||||
color: '#c7000b'
|
||||
},
|
||||
'High': {
|
||||
text: '高',
|
||||
color: '#f66f6a'
|
||||
},
|
||||
'Medium': {
|
||||
text: '中',
|
||||
color: '#fac20a'
|
||||
},
|
||||
'Low': {
|
||||
text: '低',
|
||||
color: '#5e7ce0'
|
||||
}
|
||||
'高': '#f66f6a',
|
||||
'中': '#fac20a',
|
||||
'低': '#5e7ce0'
|
||||
}
|
||||
|
||||
const searchInput = ref(null);
|
||||
@@ -202,7 +190,7 @@ const openWarningDetail = (event, index) => {
|
||||
item.dotColor = '';
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
warningModalVisable.value = true;
|
||||
currentWarning.value = event;
|
||||
}
|
||||
@@ -250,6 +238,7 @@ getNoticeList();
|
||||
|
||||
.home-content {
|
||||
font-size: 14px;
|
||||
height: 50%;
|
||||
width: 50%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -269,7 +258,7 @@ getNoticeList();
|
||||
|
||||
img {
|
||||
width: 50px;
|
||||
filter: brightness(0);
|
||||
//filter: brightness(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -409,7 +398,7 @@ getNoticeList();
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
margin-right: 8px;
|
||||
|
||||
|
||||
span {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
@@ -422,11 +411,8 @@ getNoticeList();
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
width: 150px;
|
||||
width: 120px;
|
||||
flex-shrink: 0;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
:deep(.devui-timeline-item-data-right) {
|
||||
@@ -440,4 +426,4 @@ getNoticeList();
|
||||
padding: 0px !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="warning-detail-container">
|
||||
<div class="warning-title">
|
||||
<div>{{ warningData.subject }}</div>
|
||||
<div style="padding-right: 20px;">{{ warningData.subject }}</div>
|
||||
<div class="sub-title mt-3">
|
||||
<div>
|
||||
<span>重要性</span>
|
||||
@@ -20,7 +20,7 @@
|
||||
:toolbar-config="toolbarConfig"
|
||||
></d-editor-md>
|
||||
</div>
|
||||
<div :style="{'border-radius': propsData.type === 'user' ? '6px' : 0}" class="warning-from">{{warningData.group}} {{ warningData.pulishTime }}</div>
|
||||
<div :style="{'border-radius': propsData.type === 'user' ? '6px' : 0}" class="warning-from">{{warningData.group}} {{ warningData.publishTime }}</div>
|
||||
<div v-if="propsData.type === 'system'" class="warning-operation">
|
||||
<d-button @click="confirm" variant="solid" class="mr-2">确定</d-button>
|
||||
<d-button @click="$emit('close')">取消</d-button>
|
||||
@@ -40,7 +40,8 @@ const toolbarConfig = [
|
||||
['ul', 'ol', 'checklist', 'code', 'link', 'image', 'table'],
|
||||
];
|
||||
const mode = ref('readonly');
|
||||
warningData.value = JSON.parse(propsData.warningData.alertMsg ?? JSON.stringify({
|
||||
console.log(propsData.warningData)
|
||||
warningData.value = propsData.warningData ?? {
|
||||
subject: '【漏洞排查预警】ApacheIgnite远程代码执行漏洞排查(CVE-2024-52577)',
|
||||
importance: '高',
|
||||
group: '可信开源代码库运营团队',
|
||||
@@ -49,7 +50,7 @@ warningData.value = JSON.parse(propsData.warningData.alertMsg ?? JSON.stringify(
|
||||
近日,安全中心发现Apache lgnite远程代码执行漏洞(CVE-2024-52577)。在 2.6.0<Apache Ignite< 2.17.0版本中,由于lgnite未能正确实施类序列化过滤器,攻击者能够利用恶意序列化对象绕过安全检查,从而在服务器端反序列化时触发任意代码的执行。经可信开源代码库运营团队评审漏洞技术定级2级/3级,若不满足利用条件可举证降为6级。请你按要求在XX时间内完成修复。
|
||||
## 二、修复方案
|
||||
升级Apache Ignite至安全版本:2.17.0`
|
||||
}));
|
||||
};
|
||||
const confirm = () => {
|
||||
emit('close');
|
||||
};
|
||||
|
||||
@@ -1,22 +1,34 @@
|
||||
<template>
|
||||
<Card simple class="jyh-card mt-3">
|
||||
<div class="card-title">组织预警通知列表</div>
|
||||
<div class="mb-3">
|
||||
<d-table class="jyh-table jyh-table-2" :header-bg="true" :data="licenseTableData">
|
||||
<d-column field="code" header="时间"></d-column>
|
||||
<d-table v-if="tableData.length>0" class="jyh-table jyh-table-2" :header-bg="true" :data="tableData">
|
||||
<d-column field="updateTime" header="时间">
|
||||
<template #default="scope">
|
||||
<span>{{ formatTime(scope.row.updateTime, 'YYYY-MM-DD') }}</span>
|
||||
</template>
|
||||
</d-column>
|
||||
<d-column field="name" header="标题">
|
||||
<template #default="scope">
|
||||
<a @click="openWarningDetail(scope.row)">{{ scope.row.name }}</a>
|
||||
</template>
|
||||
</d-column>
|
||||
<d-column field="detail" header="详情"></d-column>
|
||||
<d-column field="owner" header="订阅人"></d-column>
|
||||
<d-column field="alertMsg" header="详情">
|
||||
<template #default="scope">
|
||||
<span>{{ JSON.parse(scope.row.alertMsg)?.overview || ''}}</span>
|
||||
</template>
|
||||
</d-column>
|
||||
<d-column field="level" header="级别">
|
||||
<template #default="scope, text">
|
||||
<d-status v-if="scope.row.level === 4" type="error">危险</d-status>
|
||||
<d-status v-if="scope.row.level === 3" type="warning">严重</d-status>
|
||||
<d-status v-if="scope.row.level === 2" class="yellow-status">一般</d-status>
|
||||
<d-status v-if="scope.row.level === 1" type="running">提示</d-status>
|
||||
<template #default="scope">
|
||||
<d-status v-if="JSON.parse(scope.row.alertMsg)?.importance === '高'" type="error">
|
||||
{{ JSON.parse(scope.row.alertMsg)?.importance || ''}}
|
||||
</d-status>
|
||||
<d-status v-if="JSON.parse(scope.row.alertMsg)?.importance === '中'" type="warning">
|
||||
{{ JSON.parse(scope.row.alertMsg)?.importance || ''}}
|
||||
</d-status>
|
||||
<d-status v-if="JSON.parse(scope.row.alertMsg)?.importance === '低'" class="yellow-status">
|
||||
{{ JSON.parse(scope.row.alertMsg)?.importance || ''}}
|
||||
</d-status>
|
||||
<!-- <d-status v-if="scope.row.importance === 1" type="running">提示</d-status>-->
|
||||
</template>
|
||||
</d-column>
|
||||
<d-column field="status" header="状态">
|
||||
@@ -26,7 +38,17 @@
|
||||
</template>
|
||||
</d-column>
|
||||
</d-table>
|
||||
<NoData v-else :small="false"></NoData>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="mt-20 mb-20 flex justify-end">
|
||||
<d-pagination size="md" :page-size-options="[10, 20, 50]" :total="pager.total"
|
||||
v-model:pageSize="pager.pageSize" v-model:pageIndex="pager.pageIndex" :max-items="5"
|
||||
:can-change-page-size="true" :can-view-total="true" total-item-text="总计" @page-index-change="changeIndex()"
|
||||
@page-size-change="changeSize()" />
|
||||
</div>
|
||||
|
||||
</Card>
|
||||
|
||||
<d-modal class="warning-modal" v-model="warningModalVisable" title="">
|
||||
@@ -35,25 +57,45 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import EarlyWarningDetail from '@/views/Jyh/PersonalCenter/Detail/EarlyWarningDetail.vue';
|
||||
import NoData from "@/components/NoData/NoData.vue";
|
||||
import { getgroupNoticeList, getNoticeList } from '@/api/jyh';
|
||||
|
||||
const licenseTableData = ref([
|
||||
{ code: '05822156', name: 'MIT License', detail: 'integer', owner: 'admin', level: 4, status: 1 },
|
||||
{ code: '05822156', name: 'MIT License', detail: 'integer', owner: 'admin', level: 3, status: 2 },
|
||||
{ code: '05822156', name: 'MIT License', detail: 'integer', owner: 'admin', level: 2, status: 2 },
|
||||
{ code: '05822156', name: 'MIT License', detail: 'integer', owner: 'admin', level: 1, status: 2 }
|
||||
const tableData = ref([
|
||||
// { code: '05822156', name: 'MIT License', detail: 'integer', level: 4, status: 1 },
|
||||
// { code: '05822156', name: 'MIT License', detail: 'integer', level: 3, status: 2 },
|
||||
// { code: '05822156', name: 'MIT License', detail: 'integer', level: 2, status: 1 },
|
||||
// { code: '05822156', name: 'MIT License', detail: 'integer', level: 1, status: 2 }
|
||||
]);
|
||||
|
||||
const pager = ref({
|
||||
total: 0,
|
||||
pageIndex: 1,
|
||||
pageSize: 10
|
||||
});
|
||||
const warningModalVisable = ref(false);
|
||||
const currentWarning = ref();
|
||||
const openWarningDetail = (row) => {
|
||||
warningModalVisable.value = true;
|
||||
currentWarning.value = row;
|
||||
currentWarning.value = JSON.parse(row.alertMsg ?? '{}');
|
||||
};
|
||||
const colseWarningDetail = () => {
|
||||
warningModalVisable.value = false;
|
||||
};
|
||||
|
||||
const getList = async() => {
|
||||
const { data, error } = await getgroupNoticeList({ current: 1,size: pager.value.pageSize });
|
||||
if (!error && data) {
|
||||
tableData.value = data.data.data.records;
|
||||
pager.value.total = data.data.data.total;
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(async() => {
|
||||
getList();
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -1,31 +1,50 @@
|
||||
<template>
|
||||
<Card simple class="jyh-card mt-3">
|
||||
<div class="card-title">个人预警通知列表</div>
|
||||
<div class="mb-3">
|
||||
<d-table class="jyh-table jyh-table-2" :header-bg="true" :data="licenseTableData">
|
||||
<d-column field="code" header="时间"></d-column>
|
||||
<d-table v-if="tableData.length>0" class="jyh-table jyh-table-2" :header-bg="true" :data="tableData">
|
||||
<d-column field="updateTime" header="时间"></d-column>
|
||||
<d-column field="name" header="标题">
|
||||
<template #default="scope">
|
||||
<a @click="openWarningDetail(scope.row)">{{ scope.row.name }}</a>
|
||||
</template>
|
||||
</d-column>
|
||||
<d-column field="detail" header="详情"></d-column>
|
||||
<d-column field="alertMsg" header="详情">
|
||||
<template #default="scope">
|
||||
<span>{{ JSON.parse(scope.row.alertMsg)?.overview || ''}}</span>
|
||||
</template>
|
||||
</d-column>
|
||||
<d-column field="level" header="级别">
|
||||
<template #default="scope, text">
|
||||
<d-status v-if="scope.row.level === 4" type="error">危险</d-status>
|
||||
<d-status v-if="scope.row.level === 3" type="warning">严重</d-status>
|
||||
<d-status v-if="scope.row.level === 2" class="yellow-status">一般</d-status>
|
||||
<d-status v-if="scope.row.level === 1" type="running">提示</d-status>
|
||||
<template #default="scope">
|
||||
<d-status v-if="JSON.parse(scope.row.alertMsg)?.importance === '高'" type="error">
|
||||
{{ JSON.parse(scope.row.alertMsg)?.importance || ''}}
|
||||
</d-status>
|
||||
<d-status v-if="JSON.parse(scope.row.alertMsg)?.importance === '中'" type="warning">
|
||||
{{ JSON.parse(scope.row.alertMsg)?.importance || ''}}
|
||||
</d-status>
|
||||
<d-status v-if="JSON.parse(scope.row.alertMsg)?.importance === '低'" class="yellow-status">
|
||||
{{ JSON.parse(scope.row.alertMsg)?.importance || ''}}
|
||||
</d-status>
|
||||
<!-- <d-status v-if="scope.row.importance === 1" type="running">提示</d-status>-->
|
||||
</template>
|
||||
</d-column>
|
||||
<d-column field="status" header="状态">
|
||||
<template #default="scope, text">
|
||||
<d-tag v-if="scope.row.status === 1" type="danger" size="sm">未读</d-tag>
|
||||
<d-tag v-if="scope.row.status === 2" type="success" size="sm">已读</d-tag>
|
||||
<d-tag v-if="scope.row.status === 0" type="danger" size="sm">未读</d-tag>
|
||||
<d-tag v-if="scope.row.status === 1" type="success" size="sm">已读</d-tag>
|
||||
</template>
|
||||
</d-column>
|
||||
</d-table>
|
||||
<NoData v-else :small="false"></NoData>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="mt-20 mb-20 flex justify-end">
|
||||
<d-pagination size="md" :page-size-options="[10, 20, 50]" :total="pager.total"
|
||||
v-model:pageSize="pager.pageSize" v-model:pageIndex="pager.pageIndex" :max-items="5"
|
||||
:can-change-page-size="true" :can-view-total="true" total-item-text="总计" @page-index-change="changeIndex()"
|
||||
@page-size-change="changeSize()" />
|
||||
</div>
|
||||
|
||||
</Card>
|
||||
|
||||
<d-modal class="warning-modal" v-model="warningModalVisable" title="">
|
||||
@@ -34,25 +53,45 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import EarlyWarningDetail from '@/views/Jyh/PersonalCenter/Detail/EarlyWarningDetail.vue';
|
||||
import NoData from "@/components/NoData/NoData.vue";
|
||||
import { getNoticeList } from '@/api/jyh';
|
||||
|
||||
const licenseTableData = ref([
|
||||
{ code: '05822156', name: 'MIT License', detail: 'integer', level: 4, status: 1 },
|
||||
{ code: '05822156', name: 'MIT License', detail: 'integer', level: 3, status: 2 },
|
||||
{ code: '05822156', name: 'MIT License', detail: 'integer', level: 2, status: 1 },
|
||||
{ code: '05822156', name: 'MIT License', detail: 'integer', level: 1, status: 2 }
|
||||
const tableData = ref([
|
||||
// { code: '05822156', name: 'MIT License', detail: 'integer', level: 4, status: 1 },
|
||||
// { code: '05822156', name: 'MIT License', detail: 'integer', level: 3, status: 2 },
|
||||
// { code: '05822156', name: 'MIT License', detail: 'integer', level: 2, status: 1 },
|
||||
// { code: '05822156', name: 'MIT License', detail: 'integer', level: 1, status: 2 }
|
||||
]);
|
||||
|
||||
const pager = ref({
|
||||
total: 0,
|
||||
pageIndex: 1,
|
||||
pageSize: 10
|
||||
});
|
||||
const warningModalVisable = ref(false);
|
||||
const currentWarning = ref();
|
||||
const openWarningDetail = (row) => {
|
||||
warningModalVisable.value = true;
|
||||
currentWarning.value = row;
|
||||
currentWarning.value = JSON.parse(row.alertMsg ?? '{}');
|
||||
};
|
||||
const colseWarningDetail = () => {
|
||||
warningModalVisable.value = false;
|
||||
};
|
||||
|
||||
const getList = async() => {
|
||||
const { data, error } = await getNoticeList({ current: 1,size: pager.value.pageSize });
|
||||
if (!error && data) {
|
||||
tableData.value = data.data.data.records;
|
||||
pager.value.total = data.data.data.total;
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(async() => {
|
||||
getList();
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<template>
|
||||
<div class="invitation-notice-container">
|
||||
<Card simple class="jyh-card mt-3">
|
||||
<div class="card-title">邀请通知列表</div>
|
||||
<div class="mb-3">
|
||||
<div class="mt-3">
|
||||
<d-table
|
||||
class="jyh-table jyh-table-2"
|
||||
:header-bg="true"
|
||||
@@ -87,12 +86,13 @@ const handleAccept = async (row, type) => {
|
||||
});
|
||||
if (data?.data?.data?.data) {
|
||||
Message({
|
||||
type,
|
||||
type: 'success',
|
||||
message: '成功接受',
|
||||
});
|
||||
queryInviteListData();
|
||||
} else {
|
||||
Message({
|
||||
type,
|
||||
type: 'error',
|
||||
message: '接受失败',
|
||||
});
|
||||
}
|
||||
@@ -106,4 +106,4 @@ const handleAccept = async (row, type) => {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
<template>
|
||||
<Card simple class="jyh-card mt-3">
|
||||
<div class="card-title">组织订阅列表</div>
|
||||
<div class="mb-3">
|
||||
<d-table class="jyh-table jyh-table-2" :header-bg="true" :data="tableData">
|
||||
<d-column field="code" header="订阅时间"></d-column>
|
||||
<d-table v-if="tableData.length>0" class="jyh-table jyh-table-2" :header-bg="true" :data="tableData">
|
||||
<d-column field="updateTime" header="订阅时间"></d-column>
|
||||
<d-column field="name" header="软件名称"></d-column>
|
||||
<d-column field="detail" header="版本号"></d-column>
|
||||
<d-column field="owner" header="订阅人"></d-column>
|
||||
<d-column field="releaseId" header="版本号"></d-column>
|
||||
<d-column field="username" header="订阅人"></d-column>
|
||||
<d-column header="操作" width="100">
|
||||
<template #default="scope">
|
||||
<d-popover>
|
||||
@@ -24,17 +23,39 @@
|
||||
</template>
|
||||
</d-column>
|
||||
</d-table>
|
||||
<NoData v-else :small="false"></NoData>
|
||||
</div>
|
||||
</Card>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
const tableData = ref([{ code: '05822156', name: 'MIT License', detail: 'integer', owner: 'admin' }]);
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { getgroupNoticeList, getGroupSubscribeList, getSubscribeList } from '@/api/jyh';
|
||||
import NoData from "@/components/NoData/NoData.vue";
|
||||
const tableData = ref([]);
|
||||
const hidden = () => {
|
||||
// 模拟body点击操作
|
||||
document.querySelector('body')?.click();
|
||||
};
|
||||
|
||||
const pager = ref({
|
||||
total: 0,
|
||||
pageIndex: 1,
|
||||
pageSize: 10
|
||||
});
|
||||
|
||||
const getList = async() => {
|
||||
const { data, error } = await getGroupSubscribeList({ current: 1,size: pager.value.pageSize });
|
||||
if (!error && data) {
|
||||
tableData.value = data.data.data.records;
|
||||
pager.value.total = data.data.data.total;
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(async() => {
|
||||
getList();
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<template>
|
||||
<Card simple class="jyh-card mt-3">
|
||||
<div class="card-title">个人订阅列表</div>
|
||||
<div class="mb-3">
|
||||
<d-table class="jyh-table jyh-table-2" :header-bg="true" :data="tableData">
|
||||
<d-column field="code" header="订阅时间"></d-column>
|
||||
<d-table v-if="tableData.length>0" class="jyh-table jyh-table-2" :header-bg="true" :data="tableData">
|
||||
<d-column field="updateTime" header="订阅时间"></d-column>
|
||||
<d-column field="name" header="软件名称"></d-column>
|
||||
<d-column field="detail" header="版本号"></d-column>
|
||||
<d-column field="releaseId" header="版本号"></d-column>
|
||||
<d-column field="username" header="订阅人"></d-column>
|
||||
<d-column header="操作" width="100">
|
||||
<template #default="scope">
|
||||
<d-popover>
|
||||
@@ -23,17 +23,39 @@
|
||||
</template>
|
||||
</d-column>
|
||||
</d-table>
|
||||
<NoData v-else :small="false"></NoData>
|
||||
</div>
|
||||
</Card>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
const tableData = ref([{ code: '05822156', name: 'MIT License', detail: 'integer' }]);
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { getgroupNoticeList, getGroupSubscribeList, getSubscribeList } from '@/api/jyh';
|
||||
import NoData from "@/components/NoData/NoData.vue";
|
||||
const tableData = ref([]);
|
||||
const hidden = () => {
|
||||
// 模拟body点击操作
|
||||
document.querySelector('body')?.click();
|
||||
};
|
||||
|
||||
const pager = ref({
|
||||
total: 0,
|
||||
pageIndex: 1,
|
||||
pageSize: 10
|
||||
});
|
||||
|
||||
const getList = async() => {
|
||||
const { data, error } = await getSubscribeList({ current: 1,size: pager.value.pageSize });
|
||||
if (!error && data) {
|
||||
tableData.value = data.data.data.records;
|
||||
pager.value.total = data.data.data.total;
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(async() => {
|
||||
getList();
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
<div class="font-bold text-[14px] mb-[12px]">成员管理</div>
|
||||
<div class="flex mb-[12px]">
|
||||
<d-button icon="add" variant="solid" class="mr-[8px]" @click="openInviteMemberModal">邀请成员</d-button>
|
||||
<d-search icon-position="left" class="w-[296px]" placeholder="请输入搜索内容" />
|
||||
<d-search icon-position="left" class="w-[296px]" placeholder="请输入搜索内容" @search="getMemberList" />
|
||||
</div>
|
||||
<d-table
|
||||
:data="memberTableData"
|
||||
@@ -155,7 +155,7 @@ const userInfo = shallowRef<UserInfoType>({
|
||||
groupDesc: null,
|
||||
});
|
||||
const searchOrganizationLoading = ref(false);
|
||||
const hasOrganization = ref(false);
|
||||
const hasOrganization = ref(true);
|
||||
const organizationInfo = shallowRef<OrganizationInfoType>({
|
||||
groupId: 0,
|
||||
organizationName: '',
|
||||
@@ -218,13 +218,14 @@ async function queryUserInfo() {
|
||||
userInfo.value = res.data?.data.data;
|
||||
}
|
||||
if (userInfo.value.groupId) {
|
||||
hasOrganization.value = true;
|
||||
organizationInfo.value = {
|
||||
groupId: userInfo.value.groupId,
|
||||
organizationName: userInfo.value.groupName as string,
|
||||
organizationProfile: userInfo.value.groupDesc as string,
|
||||
};
|
||||
getMemberList();
|
||||
} else {
|
||||
hasOrganization.value = false;
|
||||
}
|
||||
} catch (e) {
|
||||
Message.error('查询用户信息失败');
|
||||
|
||||
@@ -4,21 +4,33 @@
|
||||
<div class="text-[14px] w-full flex items-center justify-between">
|
||||
<div class="font-bold mb-[16px]">基础信息</div>
|
||||
</div>
|
||||
<d-form layout="vertical" class="ml-3 mr-3" :data="forms">
|
||||
<d-form ref="formRef" layout="vertical" class="ml-3 mr-3" :data="forms">
|
||||
<d-row :gutter="16">
|
||||
<d-col span="8">
|
||||
<d-form-item field="name" label="名称" required>
|
||||
<d-input v-model="forms.name" />
|
||||
<d-form-item
|
||||
field="nickname"
|
||||
label="名称"
|
||||
:rules="[{ required: true, message: '请填写名称', trigger: 'blur' }]"
|
||||
>
|
||||
<d-input v-model="forms.nickname" />
|
||||
</d-form-item>
|
||||
</d-col>
|
||||
<d-col span="8">
|
||||
<d-form-item field="email" label="邮件" required>
|
||||
<d-form-item
|
||||
field="email"
|
||||
label="邮件"
|
||||
:rules="[{ required: true, message: '请填写邮件', trigger: 'blur' }]"
|
||||
>
|
||||
<d-input v-model="forms.email" />
|
||||
</d-form-item>
|
||||
</d-col>
|
||||
<d-col span="8">
|
||||
<d-form-item field="phone" label="电话" required>
|
||||
<d-input v-model="forms.phone" />
|
||||
<d-form-item
|
||||
field="mobile"
|
||||
label="电话"
|
||||
:rules="[{ required: true, message: '请填写电话', trigger: 'blur' }]"
|
||||
>
|
||||
<d-input v-model="forms.mobile" />
|
||||
</d-form-item>
|
||||
</d-col>
|
||||
</d-row>
|
||||
@@ -29,29 +41,71 @@
|
||||
<div class="font-bold mb-[16px]">预警通知设置</div>
|
||||
</div>
|
||||
<d-form layout="vertical">
|
||||
<d-form-item field="radio" label="是否开启邮件通知">
|
||||
<d-radio-group direction="row" v-model="radio">
|
||||
<d-radio value="0">开启</d-radio>
|
||||
<d-radio value="1">关闭</d-radio>
|
||||
<d-form-item field="radio" label="是否开启预警通知">
|
||||
<d-radio-group direction="row" v-model="forms.userExt.emailAlertSwitch">
|
||||
<d-radio :value="true">开启</d-radio>
|
||||
<d-radio :value="false">关闭</d-radio>
|
||||
</d-radio-group>
|
||||
</d-form-item>
|
||||
</d-form>
|
||||
</d-card>
|
||||
<div class="flex">
|
||||
<d-button variant="solid" class="mr-[8px]">提交</d-button>
|
||||
<d-button color="secondary" class="mr-[8px]">保存草稿</d-button>
|
||||
<d-button variant="solid" class="mr-[8px]" @click="save" :loading="loading">保存</d-button>
|
||||
<!-- <d-button color="secondary" class="mr-[8px]">保存草稿</d-button> -->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref, shallowRef } from 'vue';
|
||||
const radio = ref('1');
|
||||
import { userEdit } from '@/api/jyh';
|
||||
import { getUserInfo } from '@/api/user';
|
||||
import { onMounted, reactive, ref, shallowRef } from 'vue';
|
||||
import { Message } from 'vue-devui';
|
||||
import { useAccountStore } from '@/stores/user';
|
||||
|
||||
const loading = ref(false);
|
||||
|
||||
const forms = reactive({
|
||||
name: '',
|
||||
nickname: '',
|
||||
mobile: '',
|
||||
email: '',
|
||||
phone: ''
|
||||
userExt: {
|
||||
emailAlertSwitch: true
|
||||
}
|
||||
});
|
||||
|
||||
const getInfo = async () => {
|
||||
const userRes = await getUserInfo();
|
||||
const user = userRes.data.data.data || {};
|
||||
forms.nickname = user.nickname;
|
||||
forms.mobile = user.mobile;
|
||||
forms.email = user.email;
|
||||
forms.userExt.emailAlertSwitch = user.userExt?.emailAlertSwitch || false;
|
||||
|
||||
if (userRes.data?.data) {
|
||||
localStorage.setItem('userInfo', JSON.stringify(userRes.data?.data));
|
||||
useAccountStore().saveAccountInfo({
|
||||
...userRes.data?.data
|
||||
});
|
||||
// }
|
||||
}
|
||||
};
|
||||
|
||||
const formRef = ref();
|
||||
const save = () => {
|
||||
formRef.value.validate(async (isValid, invalidFields) => {
|
||||
if (isValid) {
|
||||
loading.value = true;
|
||||
await userEdit(forms);
|
||||
loading.value = false;
|
||||
Message.success('保存成功');
|
||||
getInfo();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getInfo();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -219,7 +219,7 @@ const currentReusltFilter = ref(null);
|
||||
// 定义 tableKey,用于强制刷新表格
|
||||
const tableKey = ref(0);
|
||||
const pager = ref({
|
||||
total: 10,
|
||||
total: 0,
|
||||
pageIndex: 1,
|
||||
pageSize: 10
|
||||
});
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
import AdvanceSearch from '@/components/AdvanceSearch/index.vue'
|
||||
import SettingTitle from '@/components/Setting/SettingTitle/index.vue';
|
||||
import SettingText from '@/components/Setting/SettingText/index.vue';
|
||||
import { ref,reactive, onMounted } from 'vue';
|
||||
import { ref,reactive, onMounted,watch } from 'vue';
|
||||
import { getGroupClaList, setGroupClaStatus, deleteGroupCla } from '@/api/cla';
|
||||
import { useRouter, useRoute } from 'vue-router';
|
||||
import { GModal } from '@/components/Setting/index';
|
||||
@@ -180,7 +180,7 @@ const columns = ref([
|
||||
{ key: 'contributorCountries', label: '贡献者国家/地区分布', visible: false, filterable: false, sortable: false },
|
||||
{ key: 'contributorOrganizations', label: '贡献者组织/公司分布', visible: false, filterable: false, sortable: false },
|
||||
{ key: 'communityHash', label: '社区hash值', visible: false, filterable: false, sortable: false },
|
||||
{ key: 'copyright', label: 'CopyRight', visible: false, filterable: false, sortable: false },
|
||||
{ key: 'copyright', label: 'Copyright', visible: false, filterable: false, sortable: false },
|
||||
{ key: 'externalVulnerabilitySource', label: '外部漏洞源的软件名称', visible: false, filterable: true, sortable: false },
|
||||
{ key: 'versionDescription', label: '版本描述', visible: false, filterable: false, sortable: false },
|
||||
{ key: 'compatibilityRisk', label: '兼容性风险描述', visible: false, filterable: false, sortable: false },
|
||||
@@ -322,6 +322,18 @@ onMounted(() => {
|
||||
...query
|
||||
};
|
||||
});
|
||||
|
||||
// 监听路由变化,更新 searchWord
|
||||
watch(
|
||||
() => route.query.searchWord, // 监听路由的 searchWord 参数
|
||||
(newSearchWord) => {
|
||||
if (newSearchWord) {
|
||||
newFormData.value.searchWord = newSearchWord; // 更新组件的 searchWord
|
||||
getReleaseList(); // 重新调用接口
|
||||
}
|
||||
},
|
||||
{ immediate: true } // 立即执行一次
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -5,25 +5,22 @@
|
||||
<d-row class="mb-3">
|
||||
<d-col :span="8">
|
||||
<span class="card-key width-90">社区名称</span>
|
||||
<span class="card-val">开发者社区</span>
|
||||
<span class="card-val">{{ infos.communityName }}</span>
|
||||
</d-col>
|
||||
<d-col :span="8">
|
||||
<span class="card-key width-90">官网地址</span>
|
||||
<span class="card-val">https://www.huaweicloud.com</span>
|
||||
<span class="card-val">{{ infos.communityWebsite }}</span>
|
||||
</d-col>
|
||||
<d-col :span="8">
|
||||
<span class="card-key width-90">联系方式</span>
|
||||
<span class="card-val">950808-1</span>
|
||||
<span class="card-val">{{ infos.communityContact }}</span>
|
||||
</d-col>
|
||||
</d-row>
|
||||
<d-row class="mb-3">
|
||||
<d-col :span="24">
|
||||
<div class="flex">
|
||||
<span class="card-key width-90 flex-shrink-0">社区描述</span>
|
||||
<span class="card-val flex-grow-1"
|
||||
>华为开发者社区致力于打造华为开发者专属的官方技术交流平台,帮助开发者探索开发实践、交流心得经验、获悉业界动态、解决开发问题。汇聚华为云社区“华为云”领域博
|
||||
客、问答、视频等精彩内容,形成开发者和技术爱好者交流与分享主阵地。</span
|
||||
>
|
||||
<span class="card-val flex-grow-1">{{ infos.communityDescription }}</span>
|
||||
</div>
|
||||
</d-col>
|
||||
</d-row>
|
||||
@@ -32,14 +29,28 @@
|
||||
<div class="card-title">贡献者分布</div>
|
||||
<p class="card-desc">有关Pull Request创建者的公司信息和地区分布(使用公共GitHub信息进行分析)</p>
|
||||
<div class="mt-3">
|
||||
<chart-line />
|
||||
<chart-line ref="chartLine" :companyGraph="infos.companyGraph" :countryGraph="infos.countryGraph" />
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import SBOMDetail from './SBOMDetail.vue';
|
||||
import { communityInfo } from '@/api/jyh';
|
||||
import { useRoute } from 'vue-router';
|
||||
import ChartLine from '@/components/ChartLine/index.vue';
|
||||
|
||||
const route = useRoute(); // 获取路由对象
|
||||
|
||||
const chartLine = ref();
|
||||
const infos = ref({});
|
||||
onMounted(async () => {
|
||||
const { data } = await communityInfo(Number(route.params.versionId));
|
||||
infos.value = data?.data?.data || {};
|
||||
chartLine.value.onInited();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -20,9 +20,13 @@
|
||||
</d-drawer>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue';
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import SBOMDetail from './SBOMDetail.vue';
|
||||
import { dependencyTree } from '@/api/jyh';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
const checked = ref(false);
|
||||
const route = useRoute(); // 获取路由对象
|
||||
const showDetail = ref(false);
|
||||
|
||||
const baseTreeTableData1 = ref([
|
||||
@@ -84,6 +88,10 @@ const baseTreeTableData1 = ref([
|
||||
const treeCheckChange = (val, row, selection) => {
|
||||
console.log('treeCheckChange', selection);
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
await dependencyTree(Number(route.params.versionId));
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -1,28 +1,22 @@
|
||||
<template>
|
||||
<div class="soft-detail-container">
|
||||
<div class="mt-3">
|
||||
<d-table class="jyh-table" v-if="tableData.length" :striped="false" :data="tableData" table-layout="auto">
|
||||
<d-table class="jyh-table" v-if="tableData.length" :striped="false" :data="valLists" table-layout="auto">
|
||||
<d-column type="index" width="40"></d-column>
|
||||
<d-column
|
||||
field="versionName"
|
||||
header="编码"
|
||||
filterable
|
||||
:filter-list="filterList"
|
||||
@filter-change="handleFilterChange"
|
||||
>
|
||||
<d-column field="vulnId" header="编码" filterable :filter-list="filterList" @filter-change="handleFilterChange">
|
||||
<template #default="scope">
|
||||
<a @click="openVulnDetail(scope.row)">{{ scope.row.versionName }}</a>
|
||||
<a @click="openVulnDetail(scope.row)">{{ scope.row.vulnId }}</a>
|
||||
</template>
|
||||
</d-column>
|
||||
<d-column
|
||||
field="name"
|
||||
field="cweId"
|
||||
header="CVE ID"
|
||||
filterable
|
||||
:filter-list="filterList"
|
||||
@filter-change="handleFilterChange"
|
||||
></d-column>
|
||||
<d-column
|
||||
field="code"
|
||||
field="cvssScore"
|
||||
header="CVSS 打分"
|
||||
filterable
|
||||
:filter-list="filterList"
|
||||
@@ -40,7 +34,7 @@
|
||||
</template>
|
||||
</d-column>
|
||||
<d-column
|
||||
field="versionCode"
|
||||
field="severity"
|
||||
header="漏洞级别"
|
||||
sortable
|
||||
:sort-method="sortNameMethod"
|
||||
@@ -49,11 +43,11 @@
|
||||
@filter-change="handleFilterChange"
|
||||
>
|
||||
<template #default="scope">
|
||||
<a>{{ scope.row.versionCode }}</a>
|
||||
<a>{{ scope.row.severity }}</a>
|
||||
</template>
|
||||
</d-column>
|
||||
<d-column
|
||||
field="versionCode"
|
||||
field="fixVersion"
|
||||
header="补丁版本"
|
||||
sortable
|
||||
:sort-method="sortNameMethod"
|
||||
@@ -62,10 +56,14 @@
|
||||
@filter-change="handleFilterChange"
|
||||
>
|
||||
<template #default="scope">
|
||||
<a>{{ scope.row.versionCode }}</a>
|
||||
<a>{{ scope.row.fixVersion }}</a>
|
||||
</template>
|
||||
</d-column>
|
||||
<d-column field="publishDate" header="补丁修复时间" fixed-right="0px">
|
||||
<template #default="scope">
|
||||
{{ dayjs(scope.row.publishDate).format('YYYY-MM-DD') }}
|
||||
</template>
|
||||
</d-column>
|
||||
<d-column field="created" header="补丁修复时间" fixed-right="0px"></d-column>
|
||||
</d-table>
|
||||
|
||||
<DataPanel v-else skeleton :card="false" :empty="true"> </DataPanel>
|
||||
@@ -100,25 +98,27 @@
|
||||
>你确认删除此项:{{ item.cla_name }} ?</span
|
||||
>
|
||||
</GModal>
|
||||
|
||||
|
||||
<!-- 漏洞详情 -->
|
||||
<d-drawer v-model="vulnDetailVisable" style="width: auto;">
|
||||
<d-drawer v-model="vulnDetailVisable" style="width: auto">
|
||||
<VulnerabilityDetail :softwareId="currentVuln.softwareId" :vulnId="currentVuln.id"></VulnerabilityDetail>
|
||||
</d-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import * as dayjs from 'dayjs';
|
||||
import SettingTitle from '@/components/Setting/SettingTitle/index.vue';
|
||||
import SettingText from '@/components/Setting/SettingText/index.vue';
|
||||
import { ref, reactive } from 'vue';
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import { getGroupClaList, setGroupClaStatus, deleteGroupCla } from '@/api/cla';
|
||||
import { useRouter, useRoute } from 'vue-router';
|
||||
import { GModal } from '@/components/Setting/index';
|
||||
import { reqCatch } from '@/utils/catch';
|
||||
import { reqCatch } from '@/utils/catch';
|
||||
import { getOrgInfo } from '@/views/Org/hooks/orgInfo';
|
||||
import { Message } from 'vue-devui';
|
||||
import VulnerabilityDetail from '@/views/Jyh/Version/Detail/VulnerabilityDetail.vue'
|
||||
import VulnerabilityDetail from '@/views/Jyh/Version/Detail/VulnerabilityDetail.vue';
|
||||
import { getVulnList } from '@/api/jyh';
|
||||
const { namespace } = getOrgInfo();
|
||||
|
||||
const tableData = ref([
|
||||
@@ -244,15 +244,25 @@ const vulnDetailVisable = ref(false);
|
||||
const currentVuln = ref();
|
||||
const openVulnDetail = (row) => {
|
||||
vulnDetailVisable.value = true;
|
||||
if(row.softwareId && row.id) {
|
||||
if (row.softwareId && row.id) {
|
||||
currentVuln.value = row;
|
||||
} else {
|
||||
currentVuln.value = {
|
||||
softwareId: 47,
|
||||
id: 72
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const valLists = ref([]);
|
||||
onMounted(async () => {
|
||||
const data = await getVulnList({
|
||||
softwareId: 47,
|
||||
current: 1,
|
||||
size: 10
|
||||
});
|
||||
valLists.value = data?.data?.data?.data?.records || [];
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
Reference in New Issue
Block a user