1.list–>tree
let lists = [
{ "id": "ckb696kne0001lj3dejycrvew","ip": "192.188.1.112", "parentIp": null },
{ "id": "ckb698ybv0002lj3d19qp8a40", "ip": "172.21.45.97", "parentIp": "192.188.1.112"},
{ "id": "ckb699pvf0005lj3da9uqxgoy", "ip": "192.188.1.108","parentIp": "192.188.1.112" },
{ "id": "ckb69b1070009lj3d1o39j8uc", "ip": "192.188.1.111", "parentIp": "192.188.1.108" },
{ "id": "ckb69bpoh0012lj3dfq7d2ns4","ip": "192.188.1.109", "parentIp": "192.188.1.111"},
{ "id": "ckb69clw90014lj3doet59ntt", "ip": "128.0.3.7","parentIp": "192.188.1.108" },
{ "id": "ckb69d7680015lj3dss5fhoo9", "ip": "128.0.3.8", "parentIp": "128.0.3.7"},
{ "id": "ckcwpe75300151bkf4fourifa", "ip": "192.168.1.33", "parentIp": "128.0.3.7" }
]
function listToTree(list, parentIp) {
return list
.filter(item => item.parentIp === parentIp)
.map(item => ({
...item,
children: this.listToTree(list, item.ip)
}))
}
const res = listToTree(lists, null)
console.log(res)
'res--result':
[{…}]
0:
children: Array(2)
0: {id: "ckb698ybv0002lj3d19qp8a40", ip: "172.21.45.97", parentIp: "192.188.1.112", children: Array(0)}
1: {id: "ckb699pvf0005lj3da9uqxgoy", ip: "192.188.1.108", parentIp: "192.188.1.112", children: Array(2)}
length: 2
[[Prototype]]: Array(0)
id: "ckb696kne0001lj3dejycrvew"
ip: "192.188.1.112"
parentIp: null
[[Prototype]]: Object
length: 1
[[Prototype]]: Array(0)
-----------------------------------------------------------------------------------------------------
//上面结果展开:
[{…}]
0:
children: Array(2)
0:
children: Array(0)
length: 0
[[Prototype]]: Array(0)
id: "ckb698ybv0002lj3d19qp8a40"
ip: "172.21.45.97"
parentIp: "192.188.1.112"
[[Prototype]]: Object
1:
children: Array(2)
0:
children: Array(1)
0: {id: "ckb69bpoh0012lj3dfq7d2ns4", ip: "192.188.1.109", parentIp: "192.188.1.111", children: Array(0)}
length: 1
[[Prototype]]: Array(0)
id: "ckb69b1070009lj3d1o39j8uc"
ip: "192.188.1.111"
parentIp: "192.188.1.108"
[[Prototype]]: Object
1:
children: Array(2)
0: {id: "ckb69d7680015lj3dss5fhoo9", ip: "128.0.3.8", parentIp: "128.0.3.7", children: Array(0)}
1: {id: "ckcwpe75300151bkf4fourifa", ip: "192.168.1.33", parentIp: "128.0.3.7", children: Array(0)}
length: 2
[[Prototype]]: Array(0)
id: "ckb69clw90014lj3doet59ntt"
ip: "128.0.3.7"
parentIp: "192.188.1.108"
[[Prototype]]: Object
length: 2
[[Prototype]]: Array(0)
id: "ckb699pvf0005lj3da9uqxgoy"
ip: "192.188.1.108"
parentIp: "192.188.1.112"
[[Prototype]]: Object
length: 2
[[Prototype]]: Array(0)
id: "ckb696kne0001lj3dejycrvew"
ip: "192.188.1.112"
parentIp: null
[[Prototype]]: Object
length: 1
[[Prototype]]: Array(0)
2.tree–>list
//使用上面生成的tree数据
treeToArray(list, newArr) {
list.forEach(item => {
const { children } = item
if (children) {
delete item.children
if (children.length) {
newArr.push(item)
return this.treeToArray(children, newArr)
}
}
newArr.push(item)
})
return newArr
}
const res = this.listToTree(this.refss, null)
const rrs = this.treeToArray(res, [])
console.log(rrs)
'rrs--result':
[{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
0: {id: "ckb696kne0001lj3dejycrvew", ip: "192.188.1.112", parentIp: null}
1: {id: "ckb698ybv0002lj3d19qp8a40", ip: "172.21.45.97", parentIp: "192.188.1.112"}
2: {id: "ckb699pvf0005lj3da9uqxgoy", ip: "192.188.1.108", parentIp: "192.188.1.112"}
3: {id: "ckb69b1070009lj3d1o39j8uc", ip: "192.188.1.111", parentIp: "192.188.1.108"}
4: {id: "ckb69bpoh0012lj3dfq7d2ns4", ip: "192.188.1.109", parentIp: "192.188.1.111"}
5: {id: "ckb69clw90014lj3doet59ntt", ip: "128.0.3.7", parentIp: "192.188.1.108"}
6: {id: "ckb69d7680015lj3dss5fhoo9", ip: "128.0.3.8", parentIp: "128.0.3.7"}
7: {id: "ckcwpe75300151bkf4fourifa", ip: "192.168.1.33", parentIp: "128.0.3.7"}
length: 8
[[Prototype]]: Array(0)
注:1.list<–>tree 2. 菜单tree
附:
<!--
FilePath: \src\views\license\license-dialog.vue
Project: HolliTrust
CreatedAt: 2021-04-12 10:05:27
CreatedBy: ylx (<1415023245@qq.com>)
Copyright: (c) 2021
Task: #1
新增授权弹框
-->
<template>
<edit-dialog
@cancel="cancel"
@ok="ok"
max-width="1000"
scrollable
v-model="value"
>
<vee-ob ref="ob">
<form-flex>
<v-row>
<v-col
cols="12"
sm="3"
>
<vee
:rules="{required:true}"
v-slot="{ errors }"
>
<v-select
:error-messages="errors"
:items="productNames"
:label="$t('schema.license.product')"
v-model="currentModel.product"
></v-select>
</vee>
</v-col>
<v-col
cols="12"
sm="3"
>
<vee
:rules="{required:true}"
v-slot="{ errors }"
>
<v-select
:error-messages="errors"
:items="versions"
:label="$t('schema.license.productVersion')"
v-model="currentModel.version"
></v-select>
</vee>
</v-col>
<v-col
cols="12"
sm="3"
>
<date-time-picker
:date="currentModel.expirationDate"
:disabled="disabled"
></date-time-picker>
</v-col>
<v-col
cols="12"
sm="3"
>
<v-checkbox
:label="$t('schema.license.valid')"
hide-details
v-model="currentModel.authType"
></v-checkbox>
</v-col>
<v-col
class="num"
cols="12"
sm="6"
>
<v-text-field
:label="$t('schema.license.projectName')"
hide-details
v-model="currentModel.projectName"
></v-text-field>
</v-col>
<v-col
class="num"
cols="12"
sm="6"
>
<v-text-field
:label="$t('schema.license.projectNumber')"
hide-details
v-model="currentModel.projectNumber"
></v-text-field>
</v-col>
<v-col
class="num"
cols="12"
sm="6"
>
<vee
:rules="{required:true}"
v-slot="{ errors }"
>
<v-text-field
:error-messages="errors"
:label="$t('schema.license.customerCompanyName')"
hide-details
v-model="currentModel.customerCompanyName"
></v-text-field>
</vee>
</v-col>
<v-col
class="num"
cols="12"
sm="6"
>
<v-text-field
:label="$t('schema.license.contractNumber')"
hide-details
v-model="currentModel.contractNumber"
></v-text-field>
</v-col>
<v-col cols="12">
<vee
:rules="{required:true, max: 128}"
v-slot="{ errors }"
>
<v-textarea
:error-messages="errors"
:label="$t('schema.license.customerUuid')"
:rows="1"
auto-grow
v-model="currentModel.customerUuid"
></v-textarea>
</vee>
</v-col>
<v-col
:key="i"
class="my-n4"
cols="12"
v-for="(item,i) in groupLabels"
>
<div>{{item}}</div>
<v-row class="pl-4 my-n2">
<v-col
:key="n"
:style="{display: (item !== k.groupLabel ? 'none' : 'block')}"
cols="4"
v-for="(k,n) in productRestrictions"
>
<div
class="d-flex align-end"
v-if="item === k.groupLabel"
>
<!-- <span>{{k.fieldLabel}}</span> -->
<vee
rules="numeric"
v-if="k.fieldType === 'NUMBER'"
v-slot="{ errors }"
>
<v-text-field
:error-messages="errors"
:label="k.fieldLabel"
class="field-label"
min="0"
persistent-hint
placeholder="0"
style="width:20px"
type="number"
v-model.number="k.fieldValue"
></v-text-field>
</vee>
<v-checkbox
:label="k.fieldLabel"
hide-details
v-else
v-model="k.fieldValue"
></v-checkbox>
</div>
</v-col>
</v-row>
</v-col>
<v-col>
<p>菜单授权</p>
<v-row>
<v-col class="menu pa-0">
<v-treeview
:items="menus"
dense
open-all
selectable
selected-color="#1976d2"
v-model="menusValues"
></v-treeview>
</v-col>
</v-row>
</v-col>
<v-col cols="12">
<v-text-field
:label="$t('schema.license.remark')"
hide-details
v-model="currentModel.remark"
></v-text-field>
</v-col>
</v-row>
</form-flex>
</vee-ob>
</edit-dialog>
</template>
<script>
import { editDialog } from '@c/dialogs'
import { formFlex } from '@c/forms'
import dateTimePicker from './date-time-picker'
import { format } from 'date-fns'
import { error } from '@utils/message'
import { create } from '@api/license'
import { find } from 'lodash'
export default {
components: { editDialog, dateTimePicker, formFlex },
props: {
value: {
type: Boolean,
default: false
},
model: {
type: Object,
default: () => {}
},
products: {
type: Array,
default: () => []
}
},
data() {
return {
currentModel: {},
versions: [],
productNames: [],
show: true,
disabled: false,
expirationDate: '',
productRestrictions: [],
product: { productRestrictions: [] },
// fieldValue: '',
menusValues: [],
groupLabels: [],
restrictions: [],
menus: [
{
id: 1,
name: '全景态势'
},
{
id: 2,
name: '威胁分析'
},
{
id: 3,
name: '告警管理',
children: [
{ id: 4, name: '告警记录' },
{ id: 5, name: '告警规则' }
]
},
{
id: 6,
name: '事件管理',
children: [
{ id: 7, name: '事件记录' },
{ id: 8, name: '事件规则' }
]
},
{
id: 9,
name: '设备管理',
children: [{ id: 10, name: '设备列表' }]
},
{
id: 11,
name: '资产管理',
children: [
{ id: 12, name: '资产列表' },
{ id: 13, name: '网络拓扑' },
{ id: 14, name: 'SNMP参数配置' }
]
},
{
id: 26,
name: '统计报表',
children: [
{ id: 27, name: '统计分析' },
{ id: 28, name: '安全报表' }
]
},
{
id: 15,
name: '日志管理',
children: [
{ id: 16, name: '采集器管理' },
{ id: 19, name: '数据源' },
{ id: 17, name: '日志解析' },
{ id: 18, name: '原始日志' }
]
},
{
id: 20,
name: '工控专家库',
children: [
{ id: 21, name: '威胁分析规则' },
{ id: 22, name: '工控系统问题' },
{ id: 23, name: '网络应用问题' },
{ id: 25, name: '漏洞列表' }
]
}
]
}
},
watch: {
model: {
handler(val) {
this.currentModel = JSON.parse(JSON.stringify(val))
},
immediate: true
},
'currentModel.authType': {
handler(val) {
if (val) {
this.expirationDate = format(
new Date('2099-01-01 00:00:00'),
'yyyy-MM-dd HH:mm:ss'
)
this.disabled = true
} else {
this.disabled = false
}
},
immediate: true
},
'currentModel.product': {
handler(val) {
this.versions = this.products
.filter(item => item.name == val)
.map(item => item.version)
this.currentModel.version = this.versions[0]
this.product = find(this.products, {
name: val,
version: this.currentModel.version
})
this.productRestrictions = this.product.productRestrictions
this.groupLabels = []
if (this.productRestrictions.length) {
this.productRestrictions.forEach(item => {
item.fieldValue = ''
})
this.groupLabels = [
...new Set(
this.productRestrictions.map(item => {
return item.groupLabel
})
)
]
}
}
},
'currentModel.version': {
handler(val) {
this.product = find(this.products, {
name: this.currentModel.product,
version: val
})
this.productRestrictions = this.product.productRestrictions
this.groupLabels = []
if (this.productRestrictions.length) {
this.productRestrictions.forEach(item => {
item.fieldValue = ''
})
this.groupLabels = [
...new Set(
this.productRestrictions.map(item => {
return item.groupLabel
})
)
]
}
}
}
},
methods: {
async ok() {
// console.log(this.menusValues)
const valid = await this.$refs.ob.validate()
if (!valid) {
return
}
//截止日期为空判断
if (
this.currentModel.expirationDate.time === null &&
this.currentModel.authType === false
) {
error(this.$t('schema.license.expirationDateEmpty'))
return
} else {
//填写具体日期
if (
this.currentModel.authType === false &&
this.currentModel.expirationDate.time !== null
) {
this.expirationDate = format(
new Date(this.currentModel.expirationDate.time),
'yyyy-MM-dd HH:mm:ss'
)
}
//截止日期不能小于等于当前时间
const expirationDates = +new Date(this.expirationDate)
const currentTime = +new Date()
if (currentTime >= expirationDates) {
error(this.$t('schema.license.validMessage'))
return
}
}
this.restrictions = this.productRestrictions.map(item => {
let { fieldValue, id: productRestrictionId } = item
fieldValue = '' + fieldValue
return { fieldValue, productRestrictionId }
})
// 组装数据
const {
projectName,
projectNumber,
customerCompanyName,
contractNumber,
customerUuid,
remark
} = this.currentModel
let data = {
productId: this.product.id,
projectName,
projectNumber,
customerCompanyName,
contractNumber,
customerUuid,
restrictions: this.restrictions,
expirationDate: new Date(this.expirationDate).toISOString(),
remark
}
// 创建授权数据请求
try {
const licenId = await create(data)
const licenseid = licenId.id
this.$emit('input', false)
this.$emit('changed', licenseid)
} catch {
error()
}
},
cancel() {
this.$emit('input', false)
}
},
created() {
this.productNames = this.products.map(item => {
return item.name
})
this.currentModel.product = this.productNames[0]
}
}
</script>
<style lang="scss" scoped>
.num {
padding-bottom: 35px;
}
.field-label {
::v-deep .v-input__slot {
width: 80px;
}
}
.menu {
::v-deep .v-treeview-node__children {
display: flex;
padding-left: 48px;
.v-treeview-node__root {
width: 150px;
.v-treeview-node__level {
width: 0px;
}
}
}
}
</style>