Authored by 高磊

Merge branch 'wangfeng-500-dev' into 'master-500-dev'

Wangfeng 500 dev



See merge request !1233
... ... @@ -48,32 +48,34 @@ layui.define(['common', 'swiper', 'admin', 'commonDetail', 'mxClient', 'sessions
});
}
let list = [
{
title:'这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称',
level:'高',
time:'2023-12-20 18:00:00',
},
{
title:'这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称',
level:'高',
time:'2023-12-20 18:00:00',
},
]
vulnerabilityDialog();
var list = [];
// 读取漏洞信息
getVulnebilityList();
function getVulnebilityList() {
admin.req({
url: common.domainName + '/api-web/vulnerabilities/unread'
, type: "get"
, async: false
, done: function (res) {
if(res.data && res.data.length > 0){
list = res.data;
vulnerabilityDialog(res.data)
}
}
});
}
//漏洞处理弹窗
function vulnerabilityDialog(){
let dom = `
<ul style="padding: 10px 15px;">
function vulnerabilityDialog(list){
let dom = ` <ul style="padding: 10px 15px;">
${
list.map(item=>{
return `<li style="padding: 20px 0px;border-bottom: 2px solid #ccc;">
<span style="color: #C41011;border-bottom: 1px solid;cursor: pointer;overflow: hidden;
text-overflow: ellipsis;white-space: nowrap;max-width: 100%;display: inline-block;"
class="vulnerability-name">${item.title}</span>
class="vulnerability-name" data-id="${item.id}">${item.name}</span>
<div style="margin-top: 20px;">
<span style="margin-right: 30px;">漏洞级别:<span style="padding: 4px 10px;color: white;background-color: #C41011;border-radius: 4px;">${item.level}</span></span>
<span>披露时间:${item.time}</span>
<span>披露时间: ${item.createTime}</span>
</div>
</li>`
}).join('')
... ... @@ -91,64 +93,87 @@ layui.define(['common', 'swiper', 'admin', 'commonDetail', 'mxClient', 'sessions
btn: false,
move: false,
success:()=>{
let dialogIndex=layer.index;
$('.vulnerability-name').unbind("click").on('click',()=>{
layer.close(dialogIndex);
let detail = `
let dialogIndex = layer.index;
$('span.vulnerability-name').unbind("click").on('click',function () {
admin.req({
url: common.domainName + '/api-web/vulnerabilities/byId?id='+$(this).data("id")
, type: "get"
, async: false
, done: function (res) {
if(res.object){
let d = res.object;
layer.close(dialogIndex);
let detail = `
<form class="layui-form" style="margin-top: 15px;" lay-filter="vulnerabilityForm">
<div class="layui-form-item">
<label class="layui-form-label">漏洞名称:</label>
<div class="layui-input-block">这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称</div>
<div class="layui-input-block">${d.name}</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">漏洞详情:</label>
<div class="layui-input-block">这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称</div>
<div class="layui-input-block">${d.remark}</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">影响范围:</label>
<div class="layui-input-block">这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称</div>
<div class="layui-input-block">${d.impactSite}</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">修复建议:</label>
<div class="layui-input-block">这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称</div>
<div class="layui-input-block">${d.repairSuggestions}</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"><span style="color: red;">*</span>阅读状态:</label>
<div class="layui-input-inline">
<input type="radio" name="readStatus" value="已读" title="已读" lay-filter="readStatus">
<input type="radio" name="readStatus" value="未读" title="未读" lay-filter="readStatus" checked>
<input type="radio" name="isRead" value="1" title="已读" lay-filter="isRead"checked>
<input type="radio" name="isRead" value="0" title="未读" lay-filter="isRead">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"><span style="color: red;">*</span>是否涉及:</label>
<div class="layui-input-inline">
<input type="radio" name="whether" value="是" title="是" lay-filter="whether">
<input type="radio" name="whether" value="否" title="否" lay-filter="whether" checked>
<input type="radio" name="isRelated" value="1" title="是" lay-filter="isRelated">
<input type="radio" name="isRelated" value="0" title="否" lay-filter="isRelated" checked>
</div>
<div><input type="hidden" id="vulnerabilitiesId" name="vulnerabilitiesId" value="${d.id}"></div>
</div>
</form>
`
//漏洞处理抽屉
layer.open({
title: ['漏洞咨询', 'font-size:20px;background-color: #d0ddec;display:flex;align-items: center; justify-content: flex-start;'],
type: 1,
offset: 'rb',
area: ['30%', '100%'],
closeBtn:0,
anim:3,
content:detail,
btn: ['确定'],
move: false,
success:()=>{
form.render();
},
yes:(index)=>{
console.log(form.val('vulnerabilityForm'));
list.splice(0,1);
layer.close(index);
vulnerabilityDialog();
//漏洞处理抽屉
layer.open({
title: ['漏洞咨询', 'font-size:20px;background-color: #d0ddec;display:flex;align-items: center; justify-content: flex-start;'],
type: 1,
offset: 'rb',
area: ['30%', '100%'],
closeBtn:0,
anim:3,
content:detail,
btn: ['确定'],
move: false,
success:()=>{
form.render();
},
yes:(index)=>{
var formData = form.val('vulnerabilityForm');
admin.req({
url: common.domainName + '/api-web/vulnerabilities/read?access_token=' + access_token
, data: JSON.stringify(formData)
, type: 'post'
, contentType: "application/json; charset=utf-8"
, done: function (res) {
if (!res.success) {
layer.msg(res.msg ? res.msg : '保存失败', {offset: '15px', icon: 7, time: 1000});
}
}
});
list = list.filter((item) => {return item.id != formData.vulnerabilitiesId});
layer.close(index);
vulnerabilityDialog(list);
}
})
}
}
})
});
})
},
})
... ...
... ... @@ -4,18 +4,14 @@
<div class="condition esData-conditon" style="justify-content: space-between;width: 100%;">
<el-form :inline="true">
<el-form-item>
<el-input clearable :size="$global.elementConfig.size.input" v-model="queryParams.keyWord" placeholder="关键字搜索" />
<el-input clearable :size="$global.elementConfig.size.input" v-model="queryParams.name" placeholder="关键字搜索" />
</el-form-item>
<el-form-item>
<el-select clearable :size="$global.elementConfig.size.input" v-model="queryParams.type" placeholder="漏洞类型">
<el-option :value="1"></el-option>
<el-option :value="0"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-select clearable :size="$global.elementConfig.size.input" v-model="queryParams.enabled" placeholder="是否涉及">
<el-option :value="1"></el-option>
<el-option :value="0"></el-option>
<el-option :value="1">高危漏洞</el-option>
<el-option :value="2">中危漏洞</el-option>
<el-option :value="3">低危漏洞</el-option>
<el-option :value="4">信息漏洞</el-option>
</el-select>
</el-form-item>
<el-form-item>
... ... @@ -32,7 +28,7 @@
</el-row>
<div class="search-table">
<cm-table-page :columns="tableData.columns" :dataList="tableData.dataList"
<cm-table-page :columns="tableData.columns" :dataList="dataList"
:height="height - 550"
:loading="false"
:pageSize="queryParams.pageSize"
... ... @@ -44,21 +40,21 @@
:total="queryParams.count"
@loaddata="loaddata">
<template #default="{row,prop,column}">
<span style="color: blue;cursor: pointer;text-decoration: underline;" v-if="prop=='name'" @click="handleView">{{row.name}}</span>
</template>
<template #tools="{scope}">
<div class="list-handle">
<span class="icon-bg" @click="handleFun(scope.row)">
<i class="el-icon-document" title="处理"></i>
<i class="el-icon-s-check" title="处理"></i>
</span>
<span class="icon-bg" @click="handleDetail(scope.row)">
<i class="el-icon-document" title="详情"></i>
<i class="el-icon-view" title="详情"></i>
</span>
<span class="icon-bg"@click="handleDel(scope.row)">
<span class="icon-bg" @click="handleDel(scope.row)">
<i class="el-icon-delete"></i>
</span>
<span class="icon-bg"@click="handleDownload(scope.row)">
<i class="el-icon-delete" title="下载"></i>
<i class="el-icon-download" title="下载"></i>
</span>
</div>
</template>
... ... @@ -80,26 +76,28 @@
<el-form-item label="漏洞名称" prop="name">
<el-input :size="$global.elementConfig.size.input" clearable v-model="docForm.name"></el-input>
</el-form-item>
<el-form-item label="漏洞级别" prop="level">
<el-select v-model="docForm.level" style="width: 100%;">
<el-option :value="3"></el-option>
<el-option :value="2"></el-option>
<el-option :value="1"></el-option>
<el-form-item label="漏洞级别" prop="type">
<el-select v-model="docForm.type" style="width: 100%;">
<el-option :value="1">高危漏洞</el-option>
<el-option :value="2">中危漏洞</el-option>
<el-option :value="3">低危漏洞</el-option>
<el-option :value="4">信息漏洞</el-option>
</el-select>
</el-form-item>
<el-form-item label="漏洞详情" prop="detail">
<el-input type="textarea" v-model="docForm.detail"></el-input>
<el-form-item label="存在站点" prop="existsSite">
<el-input type="textarea" v-model="docForm.existsSite"></el-input>
</el-form-item>
<el-form-item label="影响范围" prop="reach">
<el-input type="textarea" v-model="docForm.reach"></el-input>
<el-form-item label="漏洞详情" prop="remark">
<el-input type="textarea" v-model="docForm.remark"></el-input>
</el-form-item>
<el-form-item label="修复建议" prop="response">
<el-input type="textarea" v-model="docForm.response"></el-input>
<el-form-item label="影响范围" prop="impactSite">
<el-input type="textarea" v-model="docForm.impactSite"></el-input>
</el-form-item>
<el-form-item label="录入人" prop="createUser">
<el-input v-model="docForm.createUser"></el-input>
<el-form-item label="修复建议" prop="repairSuggestions">
<el-input type="textarea" v-model="docForm.repairSuggestions"></el-input>
</el-form-item>
<el-form-item>
<el-button :size="$global.elementConfig.size.button" @click="addFolder('ruleForm')" type="primary">
保存
... ... @@ -121,27 +119,20 @@
ref="handleRefForm">
<el-form-item label="厂商" prop="manufacturer">
<el-input :size="$global.elementConfig.size.input" clearable v-model="handleForm.manufacturer"></el-input>
<el-input :size="$global.elementConfig.size.input" clearable v-model="handleForm.manufacturer" disabled></el-input>
</el-form-item>
<el-form-item label="处理人" prop="user">
<el-select v-model="handleForm.user" style="width: 100%;">
<el-option :value="3"></el-option>
<el-option :value="2"></el-option>
<el-option :value="1"></el-option>
</el-select>
</el-form-item>
<el-form-item label="处理时间" prop="time">
<el-date-picker v-model="handleForm.time"></el-date-picker>
<el-form-item label="处理时间" prop="solveTime">
<el-date-picker v-model="handleForm.solveTime"></el-date-picker>
</el-form-item>
<el-form-item label="处理情况" prop="state">
<el-select v-model="handleForm.state" style="width: 100%;">
<el-option :value="3"></el-option>
<el-option :value="2"></el-option>
<el-option :value="1"></el-option>
<el-form-item label="处理情况" prop="solveResult">
<el-select v-model="handleForm.solveResult" style="width: 100%;">
<el-option :value="1">已处理</el-option>
<el-option :value="0">未处理</el-option>
</el-select>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input type="textarea" v-model="handleForm.remark"></el-input>
<el-form-item label="处理说明" prop="solveRemark">
<el-input type="textarea" v-model="handleForm.solveRemark"></el-input>
</el-form-item>
<el-form-item>
... ... @@ -166,38 +157,44 @@
<ul>
<li style="margin-bottom: 15px;display: flex;">
<div style="width: 80px;">漏洞名称:</div>
<div style="flex: 1;">这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称</div>
<div style="flex: 1;">{{detail.name}}</div>
</li>
<li style="margin-bottom: 15px;display: flex;">
<div style="width: 80px;">漏洞级别:</div>
<div style="flex: 1;"></div>
<div style="flex: 1;">{{detail.level}}</div>
</li>
<li style="margin-bottom: 15px;display: flex;">
<div style="width: 80px;">漏洞详情:</div>
<div style="flex: 1;">这是漏洞详情这是漏洞详情这是漏洞详情这是漏洞详情这是漏洞详情这是漏洞详情这是漏洞详情这是漏洞详情这是漏洞详情这是漏洞详情</div>
<div style="flex: 1;">{{detail.remark}}</div>
</li>
<li style="margin-bottom: 15px;display: flex;">
<div style="width: 80px;">影响范围:</div>
<div style="flex: 1;">这是影响范围这是影响范围这是影响范围这是影响范围这是影响范围这是影响范围这是影响范围这是影响范围这是影响范围这是影响范围这是影响范围这是影响范围这是影响范围</div>
<div style="flex: 1;">{{detail.impactSite}}</div>
</li>
<li style="margin-bottom: 15px;display: flex;">
<div style="width: 80px;">修复建议:</div>
<div style="flex: 1;">这是修复建议这是影响范围这是影响范围这是影响范围这是影响范围这是影响范围这是影响范围这是影响范围这是影响范围这是影响范围这是影响范围这是影响范围这是影响范围</div>
<div style="flex: 1;">{{detail.repairSuggestions}}</div>
</li>
<li style="margin-bottom: 15px;display: flex;">
<div style="width: 80px;">录入人:</div>
<div style="flex: 1;">录入人</div>
<div style="flex: 1;">{{detail.createUserName}}</div>
</li>
</ul>
<el-table :data="viewManuResult">
<el-table-column align="center" prop="manu" label="处理厂商" width="100" show-overflow-tooltip/>
<el-table-column align="center" prop="status" label="处理状态" width="80" />
<el-table-column align="center" prop="user" label="处理人" width="80" />
<el-table-column align="center" prop="time" label="处理时间" width="160" />
<el-table-column align="center" prop="info" label="处理说明" />
<el-table :data="detail.resolutions" v-if="detail.resolutions.length > 0">
<el-table-column align="center" prop="manufacturerName" label="处理厂商" width="100" show-overflow-tooltip/>
<el-table-column align="center" prop="solveResult" label="处理状态" width="80" >
<template #default="scope">
<span v-if="scope.row.solveResult == '0'">未处理</span>
<span v-if="scope.row.solveResult == '1'">已处理</span>
</template>
</el-table-column>
<el-table-column align="center" prop="solveUserName" label="处理人" width="120" />
<el-table-column align="center" prop="solveTime" label="处理时间" width="160" />
<el-table-column align="center" prop="solveRemark" label="处理说明" />
</el-table>
</div>
</el-drawer>
</div>
\ No newline at end of file
</div>
... ...
... ... @@ -5,29 +5,18 @@ export default {
const {proxy} = Vue.getCurrentInstance()
let height = Vue.ref(window.innerHeight);
let queryParams = Vue.ref({
keyWord:'',
name:'',
type:'',
enabled:'',
pageNum: 1,
pageNo:1,
pageSize: 10,
count:0,
})
let tableData = Vue.ref({
count: 0,
dataList: [
{
name:'测试',
level:'高',
time:'',
admin:'',
busTypeName:'',
}
],
columns: [
{
prop: 'name',
label: '名称',
label: '漏洞名称',
sortable: true,
align: 'center',
width: '200',
... ... @@ -39,32 +28,44 @@ export default {
align: 'center'
},
{
prop: 'time',
label: '披露时间',
prop: 'existsSite',
label: '存在站点',
sortable: true,
align: 'center',
width: '130'
}, {
prop: 'admin',
label: '阅读情况',
},
{
prop: 'impactSite',
label: '影响范围',
sortable: true,
align: 'center',
width: '130'
width: '150'
},
{
prop: 'createTime',
label: '披露时间',
sortable: true,
align: 'center',
width: '180'
}, {
prop: 'busTypeName',
label: '处理情况',
prop: 'repairPriority',
label: '处理优先级',
sortable: true,
align: 'center',
width: '270'
},
width: '130'
}
]
})
let dataList = Vue.ref([]);
let totalCount = Vue.ref(0);
let addDialogVisible = Vue.ref(false)
let addDialogTitle = Vue.ref('')
// 新增按钮
const handleAdd = ()=>{
getManufacturer();
addDialogVisible.value = true;
addDialogTitle.value = '新增';
}
... ... @@ -78,16 +79,18 @@ export default {
docForm.value = {
name:'',
level:'',
detail:'',
reach:'',
response:'',
createUser:'',
remark:'',
impactSite:'',
repairSuggestions:''
}
}
// 保存漏洞
const addFolder = ()=>{
ruleForm.value.validate((validate)=>{
if (validate){
proxy.$http.post('/api-web/vulnerabilities/save', docForm.value, function (res) {
addDialogVisible.value = false;
})
}
})
}
... ... @@ -95,10 +98,9 @@ export default {
let docForm = Vue.ref({
name:'',
level:'',
detail:'',
reach:'',
response:'',
createUser:'',
remark:'',
impactSite:'',
repairSuggestions:'',
})
let docRulesForm = Vue.ref({
name:[
... ... @@ -107,25 +109,35 @@ export default {
level:[
{ required: true, message: '请选择漏洞级别', trigger: 'blur' },
],
detail:[
remark:[
{ required: true, message: '请输入漏洞详情', trigger: 'blur' },
],
reach:[
impactSite:[
{ required: true, message: '请输入影响范围', trigger: 'blur' },
],
response:[
repairSuggestions:[
{ required: true, message: '请输入修复建议', trigger: 'blur' },
],
createUser:[
{ required: true, message: '请输入录入人', trigger: 'blur' },
]
})
let ruleForm = Vue.ref();
let detail = Vue.ref({});
let viewDrawer = Vue.ref(false)
// 查看详细
const handleDetail = (obj) =>{
viewDrawer.value = true;
proxy.$http.get('/api-web/vulnerabilities/detail', {id:obj.id}, function (res) {
if (res.object) {
detail.value = res.object;
}
})
}
// 处理按钮
let handleFun = ()=>{
let handleFun = (v)=>{
handleVisible.value = true;
handleForm.value.vulnerabilitiesId = v.id;
getManufacturer();
}
let handleVisible = Vue.ref(false);
const showHandleFolder = ()=>{
... ... @@ -133,62 +145,75 @@ export default {
}
let handleForm = Vue.ref({
manufacturer:'',
user:'',
time:'',
state:'',
remark:'',
solveResult:'',
solveRemark:'',
solveTime:'',
vulnerabilitiesId:''
})
let handleRulesForm = Vue.ref({
manufacturer:[{
required: true, message: '请输入厂商名称', trigger: 'blur'
}],
user:[{
required: true, message: '请输入处理人', trigger: 'blur'
solveResult:[{
required: true, message: '请输出处理结果', trigger: 'blur'
}],
time:[{
solveTime:[{
required: true, message: '请输入处理时间', trigger: 'blur'
}],
state:[{
solveRemark:[{
required: true, message: '请输入处理情况', trigger: 'blur'
}]
})
let handleRefForm = Vue.ref();
// 保存处理漏洞
const addHandelFolder = ()=>{
handleRefForm.value.validate((validate)=>{
if (validate){
proxy.$http.post('/api-web/vulnerabilities/solve',handleForm.value, function (res) {
handleVisible.value = false;
})
}
})
}
//删除
const handleDel = (v) =>{
proxy.$global.confirm("删除后将不可恢复,您确定要删除吗?", function () {
proxy.$http.get('/api-web/vulnerabilities/delete',{id:v.id}, function (res) {
if(res.success){
proxy.$global.showMsg('删除成功');
getVulnerabilityList();
}else{
proxy.$global.showMsg(res.msg, 'warning');
}
})
});
}
// 获取当前登陆人所属厂商
const getManufacturer = ()=>{
proxy.$http.get('/api-web/vulnerabilities/manufacturer',{}, function (res) {
console.log("res---->",res.str)
handleForm.value.manufacturer = res.str;
})
}
// 获取漏洞列表
const getVulnerabilityList = ()=>{
proxy.$http.get('/api-web/vulnerabilities/list', queryParams, function (res) {
if (res.data) {
dataList.value = res.data;
queryParams.value.count = res.count;
}
})
}
let viewDrawer = Vue.ref(false)
const handleView = ()=>{
viewDrawer.value = true;
// 查询
const handleQuery = () => {
getVulnerabilityList();
}
let viewManuResult = Vue.ref([
{
manu:'厂商名',
status:'已处理',
user:'测试用户',
time:'2020-12-22 17:00:00',
info:'处理信息处理信息处理信息处理信息处理信息处理信息处理信息处理信息处理信息处理信息处理信息'
},{
manu:'厂商名',
status:'已处理',
user:'测试用户',
time:'2020-12-22 17:00:00',
info:'处理信息处理信息处理信息处理信息处理信息处理信息处理信息处理信息处理信息处理信息处理信息'
},{
manu:'厂商名',
status:'已处理',
user:'测试用户',
time:'2020-12-22 17:00:00',
info:'处理信息处理信息处理信息处理信息处理信息处理信息处理信息处理信息处理信息处理信息处理信息'
}
])
Vue.onMounted(() => {
getVulnerabilityList();
})
return {
... ... @@ -210,9 +235,12 @@ export default {
handleRefForm,
handleRulesForm,
handleForm,
handleView,
handleDel,
handleDetail,
dataList,
handleQuery,
viewDrawer,
viewManuResult,
detail
};
},
}
\ No newline at end of file
}
... ...
<div class="cm-card" style="text-align: left;padding: 10px 15px;">
<ul>
<li v-for="(item,index) in list" :key="index" style="padding: 20px 0px;border-bottom: 2px solid #ccc;">
<span style="color: red;border-bottom: 1px solid;cursor: pointer" @click="handleDetail">{{item.title}}</span>
<div style="margin-top: 20px;">
<span style="margin-right: 20px;">漏洞级别:<span style="padding: 2px 4px;color: white;background-color: red;">{{item.level}}</span></span>
<span>披露时间:{{item.time}}</span>
</div>
</li>
</ul>
</div>
<cm-dialog :showDialogVisible="addDialogVisible" :showFooter="false" :title="addDialogTitle" @hidedialog="showFolder"
width="600px">
</cm-dialog>
<el-drawer
v-model="drawer"
title="I am the title"
direction="rtl"
>
<span>Hi, there!</span>
</el-drawer>
\ No newline at end of file
export default {
name: 'vulnerableilityList',
template: '',
setup(props, {attrs, slots, emit}) {
const {proxy} = Vue.getCurrentInstance()
let list = Vue.ref([
{
title:'这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称',
level:'高',
time:'2023-12-20 18:00:00',
},
{
title:'这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称这是漏洞名称',
level:'高',
time:'2023-12-20 18:00:00',
},
])
let drawer = Vue.ref(false);
const handleDetail = ()=>{
drawer.value = true;
}
Vue.onMounted(() => {
})
return {
list,
handleDetail,
drawer,
};
},
}
\ No newline at end of file