diff options
Diffstat (limited to 'src/views/rangeManage')
| -rw-r--r-- | src/views/rangeManage/index.vue | 420 | ||||
| -rw-r--r-- | src/views/rangeManage/mock.js | 90 | ||||
| -rw-r--r-- | src/views/rangeManage/module/CustomCreate.vue | 183 | ||||
| -rw-r--r-- | src/views/rangeManage/module/Header.vue | 161 | ||||
| -rw-r--r-- | src/views/rangeManage/module/QuickCreate.vue | 437 |
5 files changed, 0 insertions, 1291 deletions
diff --git a/src/views/rangeManage/index.vue b/src/views/rangeManage/index.vue deleted file mode 100644 index e19d55e..0000000 --- a/src/views/rangeManage/index.vue +++ /dev/null @@ -1,420 +0,0 @@ -<template> - <div class="range-manage" ref="appRef"> - <div class="show"> - <Header - @quickAdd="quickAdd" - @customAdd="customAdd" - @query="query" - ></Header> - <div class="list" id="show-loading"> - <div class="single" v-for="rangeItem in rangeList" :key="rangeItem.target_name"> - <div class="title"> - <span style="font-size: 20px;">{{rangeItem.target_name+' '+getDeployStatus(rangeItem,'deploy_status')}}</span> - <el-button :class="rangeItem.attribute==='public' ? 'gOsY' : 'gOsN'" >{{rangeItem.attribute==='public' ? '公用' : '私有'}}</el-button> - </div> - <div class="container"> - <div class="row"> - <div class="cell">{{`正常节点:${getDeployStatus(rangeItem,'deploy_success_count')}个`}}</div> - <div class="cell">{{`异常节点:${getDeployStatus(rangeItem,'deploy_default_count')}个`}}</div> - <div class="cell">{{`节点数量:${getDeployStatus(rangeItem,'deploy_total_count')}个`}}</div> - </div> - <div class="row"> - <div class="cell small">{{`创建人:${rangeItem.username}`}}</div> - <div class="cell large">{{`创建时间:${formatTime(rangeItem.create_time)}`}}</div> - </div> - </div> - <div class="buttons"> - <el-button class="glBut" type="primary" :disabled="rangeItem.delLoading" @click="edit(rangeItem)">修改</el-button> - <el-button class="glBut" type="primary" :loading="rangeItem.delLoading" @click="del(rangeItem)">删除</el-button> - <el-button class="glBut" type="primary" @click="goConfigManage(rangeItem.id)">配置管理</el-button> - <el-button class="glBut" type="primary" @click="goNodeManage(rangeItem.id)">节点管理</el-button> - </div> - </div> - </div> - <el-pagination - background - :current-page="page" - :page-sizes="[10, 20, 30, 40]" - :page-size="10" - :total="total" - layout="total, sizes, prev, pager, next, jumper" - @size-change="handleSizeChange" - @current-change="handleCurrentChange" - > - </el-pagination> - <div class="mask"></div> - <QuickCreate ref="quickCreate" :is-add="isAdd" @refresh="init"></QuickCreate> - <CustomCreate ref="customCreate" :is-add="isAdd" @refresh="init"></CustomCreate> - </div> - </div> -</template> - -<script> -import Header from './module/Header.vue' -import QuickCreate from './module/QuickCreate.vue' -import CustomCreate from './module/CustomCreate.vue' -import { formatTime } from '../../utils' -import { Loading } from 'element-ui' -import { getTargetsResponse } from './mock.js' -export default { - name: "RangeMange", - components:{ - Header, - QuickCreate, - CustomCreate - }, - // props:['fTag','fInput','fFrom','FIsConfigQuery'], - data(){ - return{ - page: 1, - size: 10, - total: 0, - isAdd: false, - rangeList:[], - delTimer: null, - pendingTimer: null, - counter: 0 - } - }, - computed: {}, - watch: {}, - filters: {}, - created() { - // this.init() - }, - mounted() { - this.init() - }, - destroyed() { - if (this.pendingTimer) { - clearInterval(this.pendingTimer) - this.pendingTimer = null - } - if(this.delTimer) { - clearInterval(this.delTimer) - this.delTimer = null - } - this.counter = 0 - }, - methods:{ - formatTime, - // 初始化数据 - init(params={}) { - // this.rangeList = getTargetsResponse?.result?.items - // this.total = getTargetsResponse?.result?.total - const reqParams = { - page: this.page, - size: this.size, - ...params - } - // TODO: 网络请求先注释,后期放开 - let loadingInstance = Loading.service({ text: '加载中...', target: '#show-loading'}) // 开启loading - this.$axios.get(this.$http.api.getTargets, reqParams).then(res => { - if (res.code == 200 || res.code == "OK") { - this.total = res?.result?.total - this.rangeList = res?.result?.items - this.rangeList.map(item => { - this.$set(item, 'delLoading', false) - return item - }) - let index = this.rangeList?.findIndex(item => { - return item.target_deploy_statuses[0].deploy_status === '部署中' || item.target_deploy_statuses[0].deploy_status === '删除中' - }) - if (index !== -1) { - if (!this.pendingTimer) { - this.pendingTimer = setInterval(() => { - this.timerUpdateList(params) - }, 10 * 1000) - } - } - } - }).catch(err => { - console.log(err) - }).finally(() => { - loadingInstance.close() - if(this.rangeList.length === 0) { - this.$store.commit('range/setTargetId', '') - } - }) - }, - // 查询 - query(params) { - this.init(params) - }, - // pendingTimer只刷新数据 - timerUpdateList(params) { - const reqParams = { - page: this.page, - size: this.size, - ...params - } - this.$axios.get(this.$http.api.getTargets, reqParams).then(res => { - if (res.code == 200 || res.code == "OK") { - this.total = res?.result?.total - this.rangeList = res?.result?.items - this.rangeList.map(item => { - this.$set(item, 'delLoading', false) - return item - }) - } - }).catch(err => { - console.log(err) - }).finally(() => { - if(this.rangeList.length === 0) { - this.$store.commit('range/setTargetId', '') - } - }) - }, - // 修改 - edit(rangeItem) { - if (rangeItem.create_mode === 'define') { - // 自定义靶场修改 - this.isAdd = false - this.$refs.customCreate.target_id = rangeItem.id - this.$refs.customCreate.user_id = rangeItem.user_id - this.$refs.customCreate.form.target_name = rangeItem.target_name - this.$refs.customCreate.form.description = rangeItem.description - this.$refs.customCreate.form.attribute = rangeItem.attribute - document.querySelector('.mask').style.display = 'block' - this.$refs.customCreate.visible = true - } else { - // 快速创建靶场修改 - this.isAdd = false - this.$refs.quickCreate.target_id = rangeItem.id - this.$refs.quickCreate.user_id = rangeItem.user_id - this.$refs.quickCreate.form.target_name = rangeItem.target_name - this.$refs.quickCreate.form.description = rangeItem.description - if (rangeItem.ratio === 0.01 || rangeItem.ratio === 0.005 || rangeItem.ratio === 0.002 || rangeItem.ratio === 0.001) { - this.$refs.quickCreate.form.ratio = rangeItem.ratio.toString() - } else { - this.$refs.quickCreate.otherRatio = rangeItem.ratio.toString() - } - this.$refs.quickCreate.form.attribute = rangeItem.attribute - this.$refs.quickCreate.form.createType = rangeItem.create_mode - document.querySelector('.mask').style.display = 'block' - this.$refs.quickCreate.visible = true - } - }, - // 删除 - del(rangeItem) { - rangeItem.delLoading = true - const url = this.$http.api.asyncTarget + '/' + rangeItem.id - this.$axios.delete(url, {}).then(res => { - if (res.code == 200 || res.code == "OK") { - this.$notify({ - title: res.message, - type: 'success', - duration: 2500 - }) - this.delTimer = setInterval(() => { - this.getTask(res?.result?.task_id || '') - }, 10 * 1000) - // this.init() - } - }).catch(err => { - console.log(err) - }).finally(() => { - // rangeItem.delLoading = false - }) - }, - // 获取任务进度 - getTask(task_id) { - const url = this.$http.api.task + '/' + task_id - this.$axios.get(url, {}).then(res => { - if(res.task_status !== 'PENDING' && res.task_status !== 'STARTED') { - if (res?.task_result?.code === 500 || res?.task_result?.message === 'false') { - this.$notify({ - title: `${res.task_id}任务执行完毕,删除靶场失败`, - type: 'success', - duration: 2500 - }) - } else { - this.$notify({ - title: `${res.task_id}任务执行完毕,删除靶场成功`, - type: 'success', - duration: 2500 - }) - } - clearInterval(this.delTimer) - this.delTimer = null - this.counter = 0 - this.init() - } else { - // this.$notify({ - // title: `${res.task_id}任务执行中`, - // type: 'success', - // duration: 2500 - // }) - } - }).catch(err => { - console.log(err) - }).finally(() => { - this.counter++ - if (this.counter >= 60) { - clearInterval(this.delTimer) - this.delTimer = null - this.counter = 0 - this.init() - } - }) - }, - // 配置管理页面 - goConfigManage(id) { - this.$store.commit('globalAttrs/setCheckMenu', 'rangeConfigManage') - this.$store.commit('range/setTargetId', id) - }, - // 节点管理页面 - goNodeManage(id) { - this.$store.commit('globalAttrs/setCheckMenu', 'rangeNodeManage') - this.$store.commit('range/setTargetId', id) - }, - // 打开快速创建靶场 - quickAdd() { - this.isAdd = true - document.querySelector('.mask').style.display = 'block' - this.$refs.quickCreate.visible = true - }, - // 打开自定义创建靶场 - customAdd() { - this.isAdd = true - document.querySelector('.mask').style.display = 'block' - this.$refs.customCreate.visible = true - }, - getDeployStatus(rangeItem, deploy) { - if (rangeItem.target_deploy_statuses.length > 0) { - return rangeItem.target_deploy_statuses[0][deploy] - } else { - return '--' - } - }, - handleSizeChange(val) { - console.log(`每页 ${val} 条`) - this.page=1 - this.size=val - this.query() - }, - handleCurrentChange(val) { - console.log(`当前页: ${val}`) - this.page=val - this.query() - } - } -} -</script> - -<style lang='less' scoped> - .range-manage{ - width: 100%; - height: 100%; - float: right; - position: relative; /* 确保相对定位生效 */ - - .show{ - width: 95%; - height: 95%; - position: absolute; /* 绝对定位 */ - top: 50%; /* 向下偏移50% */ - left: 50%; /* 向右偏移50% */ - transform: translate(-50%, -50%); /* 回移50% */ - background-image:url('../../img/backgroundFourCorner.png'); - background-repeat: no-repeat; /* 可选,防止图像重复 */ - background-size: 100% 100%; /* 宽度为100%,高度自适应保持宽高比 */ - .list{ - display:flex; - flex-direction: row; - justify-content: flex-start; - flex-wrap: wrap; - align-content: flex-start; - width: 95%; - height: 84%; - margin-left: 2.5%; - .single:hover{ - border: 1px solid #159dd3; - } - .single{ - width: 32%; - height: 23.5%; - border-radius: 8px; - border: 1px solid rgba(186, 208, 241, 0.10); - background: rgba(25, 33, 61, 0.40); - margin-left: 1.2%; - margin-bottom: 0.9%; - padding: 20px; - display: inline-block; - .title{ - text-align: left; - .gOsY{ - width: 15px; - height: 10px; - display: inline-flex; - align-items: center; - justify-content: center; - margin-left: 2%; - background-color: rgba(121, 175, 122, 0.3); - color: #36af04; - } - .gOsN{ - width: 15px; - height: 10px; - display: inline-flex; - align-items: center; - justify-content: center; - margin-left: 2%; - background-color: rgba(207, 172, 93, 0.3); - color: #af8109; - } - } - .container{ - width: 100%; - display: flex; - flex-direction: column; - margin: 10px 0 10px 0; - .row { - display: flex; - padding-bottom: 10px; - } - - .cell { - flex-grow: 1; - color: rgba(255, 255, 255, 0.6); - border: none; - text-align: left; - } - - .cell.small { - flex-basis: 33.5%; - } - - .cell.large { - flex-basis: 66.5%; - } - } - .buttons{ - text-align: left; - - .glBut{ - width: 80px; - height: 30px; - display: inline-flex; - align-items: center; - justify-content: center; - // margin-left: 2%; - background-color: rgba(14, 61, 138, 0.50); - color: #02DDEA; - } - } - } - } - // 遮罩层 - .mask{ - position: fixed; /*将元素设置为固定定位*/ - top: 0; - right: 0; - bottom: 0; - left: 0; - background-color: rgba(0,0,0,0.5); /*通过rgba函数来控制遮罩层的透明度*/ - display: none; /*将元素隐藏*/ - } - } - } -</style>
\ No newline at end of file diff --git a/src/views/rangeManage/mock.js b/src/views/rangeManage/mock.js deleted file mode 100644 index 029336a..0000000 --- a/src/views/rangeManage/mock.js +++ /dev/null @@ -1,90 +0,0 @@ -const getTargetsResponse = { - "code":200, - "message":"success", - "result":{ - "items":[ - { - "target_name":"tor测试靶场", - "description":"部署tor网络", - "attribute":"public", - "id":23, - "user_id":2, - "create_time":"2023-12-07T14:24:53", - "target_deploy_statuses":[ - { - "deploy_status":"部署成功", - "deploy_total_count":20, - "deploy_success_count":18, - "deploy_default_count":2 - } - ] - }, - { - "target_name":"tor测试靶场2", - "description":"部署tor网络", - "attribute":"public", - "id":24, - "user_id":2, - "create_time":"2023-12-07T14:37:54", - "target_deploy_statuses":[ - { - "deploy_status":"未部署", - "deploy_total_count":0, - "deploy_success_count":0, - "deploy_default_count":0 - } - ] - }, - { - "target_name":"string", - "description":"string", - "attribute":"public", - "id":34, - "user_id":4, - "create_time":"2023-12-13T00:30:22", - "target_deploy_statuses":[ - - ] - }, - { - "target_name":"XT-RANGE1", - "description":"XT测试靶场1", - "attribute":"public", - "id":35, - "user_id":4, - "create_time":"2023-12-13T10:57:05", - "target_deploy_statuses":[ - - ] - }, - { - "target_name":"XT-RANGE2", - "description":"XT测试靶场2", - "attribute":"public", - "id":36, - "user_id":4, - "create_time":"2023-12-13T15:55:12", - "target_deploy_statuses":[ - - ] - }, - { - "target_name":"XT-RANGE3", - "description":"XT测试靶场3", - "attribute":"public", - "id":37, - "user_id":4, - "create_time":"2023-12-13T15:55:12", - "target_deploy_statuses":[ - - ] - } - ], - "total":6, - "page":1, - "size":50, - "pages":1 - } -} - -export { getTargetsResponse }
\ No newline at end of file diff --git a/src/views/rangeManage/module/CustomCreate.vue b/src/views/rangeManage/module/CustomCreate.vue deleted file mode 100644 index 0c42609..0000000 --- a/src/views/rangeManage/module/CustomCreate.vue +++ /dev/null @@ -1,183 +0,0 @@ -<template> - <div - class="custom-dialog" - v-if="visible" - > - <!-- 在此处指定弹窗的样式和内容 --> - <i class="el-icon-close" style="float: right; padding-right: 8%;padding-top: 3%" @click="close"></i> - <el-form - ref="customForm" - :model="form" - :rules="rules" - label-width="150px" - class="custom-form" - > - <el-row> - <el-col :span="20"> - <el-form-item label="靶场名称" prop="target_name"> - <el-input v-model="form.target_name" placeholder="请输入内容"></el-input> - </el-form-item> - </el-col> - </el-row> - <el-row> - <el-col :span="20"> - <el-form-item label="靶场描述" prop="description"> - <el-input type="textarea" v-model="form.description" placeholder="请输入内容"></el-input> - </el-form-item> - </el-col> - </el-row> - <el-row> - <el-col :span="20"> - <el-form-item label="所有权" prop="attribute"> - <el-radio v-model="form.attribute" label="private">私有</el-radio> - <el-radio v-model="form.attribute" label="public">公用</el-radio> - </el-form-item> - </el-col> - </el-row> - </el-form> - <div class="submit-footer"> - <div> - <el-button class="glBut" type="primary" @click="resetForm">重置</el-button> - <el-button class="glBut but-color" type="primary" @click="submit" :loading="loading">{{isAdd ? '提交' : '确定'}}</el-button> - </div> - </div> - </div> -</template> - -<script> -export default { - name: 'CustomCreate', - props: { - isAdd: { - typeof: Boolean, - required: true - } - }, - data() { - return { - visible: false, - loading: false, - form: { - target_name: '', // 靶场名称 - description: '', // 靶场描述 - attribute: '' // 所有权 - }, - target_id: '', - user_id: '', - rules: { - target_name: [ - { required: true, message: '请输入靶场名称', trigger: 'blur' } - ], - description: [ - { required: false, message: '请输入描述', trigger: 'blur' } - ], - attribute: [ - { required: true, message: '请选择所有权', trigger: 'change' } - ] - } - } - }, - methods: { - close() { - this.resetForm() - document.querySelector('.mask').style.display = 'none' - this.visible = false - }, - submit() { - this.$refs.customForm.validate((valid) => { - if (valid) { - if (this.isAdd) { - this.add() - } else { - this.edit() - } - } - }) - }, - add () { - this.loading = true - const url = this.$http.api.target - this.$axios.post(url, this.form).then(res => { - if (res.code == 200 || res.code == "OK") { - this.resetForm() - this.close() - this.$emit('refresh') - this.$notify({ - title: '创建靶场成功', - type: 'success', - duration: 2500 - }) - } - }).catch(err => { - console.log(err) - }).finally(() => { - this.loading = false - }) - }, - edit() { - this.loading = true - const url = this.$http.api.target + `/${this.target_id}` - this.$axios.put(url, this.form).then(res => { - if (res.code == 200 || res.code == "OK") { - this.resetForm() - this.close() - this.$emit('refresh') - this.$notify({ - title: '编辑靶场成功', - type: 'success', - duration: 2500 - }) - } - }).catch(err => { - console.log(err) - }).finally(() => { - this.loading = false - }) - }, - resetForm() { - this.form = { - target_name: '', // 靶场名称 - description: '', // 靶场描述 - attribute: '' // 所有权 - } - } - } -} -</script> - -<style lang="less" scoped> - .custom-dialog{ - width: 520px; - height: 363px; - position: absolute; /* 绝对定位 */ - top: 50%; /* 向下偏移50% */ - left: 50%; /* 向右偏移50% */ - transform: translate(-50%, -50%); /* 回移50% */ - background-image:url('../../../img/Group.svg'); - background-repeat: no-repeat; /* 可选,防止图像重复 */ - background-size: 100% 100%; /* 宽度为100%,高度自适应保持宽高比 */ - - .custom-form { - margin-top: 70px; - text-align: left; - } - .submit-footer{ - width: 100%; - float: left; - text-align: center; - .glBut{ - width: 90px; - height: 30px; - display: inline-flex; - align-items: center; - justify-content: center; - margin-left: 2%; - background-color: rgba(24, 133, 234, 0.2); - color: #1b7cc4; - } - .but-color { - background-color: #02DDEA; - } - } - } -</style>
\ No newline at end of file diff --git a/src/views/rangeManage/module/Header.vue b/src/views/rangeManage/module/Header.vue deleted file mode 100644 index c4c8352..0000000 --- a/src/views/rangeManage/module/Header.vue +++ /dev/null @@ -1,161 +0,0 @@ -<template> - <div class="head"> - <span style="font-size: 14px;float: left;padding-top: 1%">靶场列表</span> - <img src="../../../img/btn/quickCreateRangeBtn.svg" style="height: 70% ;width: 10%;margin-right: 7%;color: #ffffff" @click="quickAdd"> - <img src="../../../img/btn/customCreateRangeBtn.svg" style="height: 70% ;width: 10%;margin-right: 7%;color: #ffffff" @click="customAdd"> - <div class="input"> - <el-input v-model="target_name" placeholder="名称查询输入" suffix icon=""> - <template v-slot:suffix> - <div class="icon-group"> - <img src="../../../img/inputl.png" alt="**"> - <img src="../../../img/inputIcon.png" alt="*" @click="query"> - </div> - </template> - </el-input> - </div> - <div class="state"> - <el-select v-model="deploy_status" placeholder="全部状态" clearable @change="query"> - <el-option - v-for="item in statusDict" - :key="item.value" - :label="item.label" - :value="item.value"> - </el-option> - </el-select> - </div> - <div class="project"> - <el-select v-model="attribute" placeholder="全部工程" clearable @change="query"> - <el-option - v-for="item in attributeDict" - :key="item.value" - :label="item.label" - :value="item.value"> - </el-option> - </el-select> - </div> - </div> -</template> - -<script> -export default { - data () { - return { - target_name: '', // 靶场名称 - deploy_status: '', - attribute: '', - statusDict: [ - { - value: '部署成功', - label: '部署成功' - }, - { - value: '部署中', - label: '部署中' - }, - { - value: '未部署', - label: '未部署' - }, - { - value: '部署失败', - label: '部署失败' - } - ], - attributeDict: [ - { - value: 'public', - label: '公用' - }, - { - value: 'private', - label: '私有' - } - ], - - - } - }, - methods: { - quickAdd() { - this.$emit('quickAdd') - }, - customAdd() { - this.$emit('customAdd') - }, - query() { - const params = { - target_name: this.target_name, - deploy_status: this.deploy_status, - attribute: this.attribute - } - this.$emit('query', params) - } - } -} -</script> - -<style lang="less" scoped> - .head{ - width: 95%; - height: 7%; - margin-top: 1%; - margin-left: 2.5%; - text-align: right; - .block{ - display: inline-block; - margin-left: 2%; - - } - .input{ - display: inline-block; - height: 60%; - width: 10%; - margin-left: 0.5%; - .el-input::placeholder { - width: auto; - } - .icon-group { - display: flex; /* 设置容器为 Flexbox 容器 */ - align-items: center; /* 垂直居中图片 */ - gap: 5px; /* 图片和文字之间的间距,可以根据需要进行调整 */ - - } - .icon-group img { - transform: scale(1); - margin-right: 15px; - margin-top: 6px; - } - } - .state{ - display: inline-block; - height: 60%; - width: 10%; - margin-left: 0.5%; - .custom-popper .el-select-dropdown { - max-height: 3px; - } - } - .project{ - display: inline-block; - height: 60%; - width: 10%; - margin-left: 0.5%; - margin-right: 3%; - .el-input::placeholder { - width: auto; - } - .icon-group { - display: flex; /* 设置容器为 Flexbox 容器 */ - align-items: center; /* 垂直居中图片 */ - gap: 5px; /* 图片和文字之间的间距,可以根据需要进行调整 */ - - } - .icon-group img { - transform: scale(1); - margin-right: 15px; - margin-top: 6px; - } - - } - } -</style>
\ No newline at end of file diff --git a/src/views/rangeManage/module/QuickCreate.vue b/src/views/rangeManage/module/QuickCreate.vue deleted file mode 100644 index bf83639..0000000 --- a/src/views/rangeManage/module/QuickCreate.vue +++ /dev/null @@ -1,437 +0,0 @@ -<template> - <div class="quick-dialog" v-if="visible"> - <!-- 在此处指定弹窗的样式和内容 --> - <i class="el-icon-close" style="float: right; padding-right: 8%;padding-top: 3%" @click="close"></i> - <el-form - ref="quickForm" - :model="form" - :rules="rules" - label-width="150px" - class="quick-form" - > - <el-row> - <el-col :span="20"> - <el-form-item label="靶场名称" prop="target_name"> - <el-input v-model="form.target_name" placeholder="请输入内容"></el-input> - </el-form-item> - </el-col> - </el-row> - <el-row> - <el-col :span="20"> - <el-form-item label="靶场描述" prop="description"> - <el-input type="textarea" v-model="form.description" placeholder="请输入内容"></el-input> - </el-form-item> - </el-col> - </el-row> - <el-row> - <el-col :span="20"> - <el-form-item label="选择按真实tor网络模拟比例" class="long-item-label"> - <el-radio-group v-model="form.ratio" @change="radioChange"> - <el-radio label="0.01">1:100</el-radio> - <el-radio label="0.02">1:200</el-radio> - <el-radio label="0.002">1:500</el-radio> - <el-radio label="0.001">1:1000</el-radio> - </el-radio-group> - <div style="margin-top: 2%"> - <span style="font-size: 12px">其他</span> - <el-input v-model="otherRatio" class="other-ratio" placeholder="请输入内容" @focus="otherRadioInput"></el-input> - <span style="font-size: 14px;color: #4b5362">(范围在0.001-0.01之间)</span> - </div> - </el-form-item> - </el-col> - </el-row> - <el-row> - <el-col :span="20"> - <el-form-item label="所有权" prop="attribute"> - <el-radio v-model="form.attribute" label="private">私有</el-radio> - <el-radio v-model="form.attribute" label="public">公用</el-radio> - </el-form-item> - </el-col> - </el-row> - <el-row> - <el-col :span="20"> - <el-form-item label="创建方式" prop="createType"> - <el-radio v-model="form.createType" label="interface">接口模式</el-radio> - <el-radio v-model="form.createType" label="consensus">consensus模式</el-radio> - </el-form-item> - </el-col> - </el-row> - <el-row> - <div class="upload-file" v-if="form.createType==='consensus'"> - <input class="uploadBgImg" type="file" name="file" @change="selectFile" /> - <div v-if="fileName">{{ fileName }}</div> - </div> - </el-row> - </el-form> - <div class="submit-footer" :style="form.createType==='consensus'?'margin-top: 60px':'margin-top: 120px'"> - <div> - <el-button class="glBut" type="primary" @click="resetForm">重置</el-button> - <el-button class="glBut but-color" style="width: 120px;" type="primary" @click="submitConfig" :loading="configLoading">仅添加配置</el-button> - <el-button class="glBut but-color" type="primary" @click="submit" :loading="createLoading">创建</el-button> - </div> - </div> - </div> -</template> - -<script> -export default { - name: 'QuickCreate', - props: { - isAdd: { - typeof: Boolean, - required: true - } - }, - data() { - return { - visible: false, - createLoading: false, - configLoading: false, - form: { - target_name: '', // 靶场名称 - description: '', // 靶场描述 - ratio: '', // 选择按真实tor网络模拟的比例 - attribute: '', // 所有权 - createType: '', // 创建方式 - file: '' // 上传文件 - }, - target_id: '', - user_id: '', - fileName: '', - otherRatio: '', - delTimer: null, - counter: 0, - rules: { - target_name: [ - { required: true, message: '请输入靶场名称', trigger: 'blur' } - ], - description: [ - { required: false, message: '请输入描述', trigger: 'blur' } - ], - ratio: [ - { required: true, message: '请选择模拟比例', trigger: 'change' } - ], - attribute: [ - { required: true, message: '请选择所有权', trigger: 'change' } - ], - createType: [ - { required: true, message: '请选择创建方式', trigger: 'change' } - ] - } - } - }, - destroyed() { - if(this.delTimer) { - clearInterval(this.delTimer) - this.delTimer = null - } - this.counter = 0 - }, - methods: { - close() { - this.resetForm() - document.querySelector('.mask').style.display = 'none' - this.visible = false - }, - // 重置 - resetForm() { - this.fileName = '' - this.otherRatio = '' - this.form = { - target_name: '', // 靶场名称 - description: '', // 靶场描述 - ratio: '', // 选择按真实tor网络模拟的比例 - attribute: '', // 所有权 - createType: '', // 创建方式 - file: '' // 上传文件 - } - }, - // 仅添加配置 - submitConfig() { - this.$refs.quickForm.validate((valid) => { - if (valid) { - this.configLoading = true - if (this.isAdd) { - this.add(false) - } else { - this.edit(false) - } - } - }) - }, - // 创建 - submit() { - this.$refs.quickForm.validate((valid) => { - if (valid) { - this.createLoading = true - if (this.isAdd) { - this.add(true) - } else { - this.edit(true) - } - } - }) - }, - add (isCreate) { - if (this.form.createType === 'interface') { - // 接口模式 - const url = isCreate ? this.$http.api.asyncQuickInterface + '/?direct=true' : this.$http.api.asyncQuickInterface + '/?direct=false' - const {target_name, description, ratio, attribute} = this.form - const submitForm = { target_name, description, ratio, attribute } - this.$axios.postForm(url, submitForm).then(res => { - if (res.code == 200 || res.code == "OK") { - this.close() - this.$emit('refresh') - // this.$notify({ - // title: '创建靶场成功', - // type: 'success', - // duration: 2500 - // }) - this.$notify({ - title: res.message, - type: 'success', - duration: 2500 - }) - this.delTimer = setInterval(() => { - this.getTask(res?.result?.task_id || '') - }, 10 * 1000) - } - }).catch(err => { - console.log(err) - }).finally(() => { - this.createLoading = false - this.configLoading = false - }) - } else { - // consensus模式 - const url = isCreate ? this.$http.api.asyncQuickConsensus + '/?direct=true' : this.$http.api.asyncQuickConsensus + '/?direct=false' - const submitForm = new FormData() - for(const key in this.form) { - submitForm.append(key, this.form[key]) - } - this.$axios.postFormData(url, submitForm).then(res => { - if (res.code == 200 || res.code == "OK") { - this.close() - this.$emit('refresh') - // this.$notify({ - // title: '创建靶场成功', - // type: 'success', - // duration: 2500 - // }) - this.$notify({ - title: res.message, - type: 'success', - duration: 2500 - }) - this.delTimer = setInterval(() => { - this.getTask(res?.result?.task_id || '') - },10 * 1000) - } - }).catch(err => { - console.log(err) - }).finally(() => { - this.createLoading = false - this.configLoading = false - }) - } - }, - edit(isCreate) { - const editForm = JSON.parse(JSON.stringify(this.form)) - if (this.otherRatio !== '') { - editForm.ratio = this.otherRatio - } - if(this.form.createType === 'interface') { - // 接口模式 - const url = isCreate ? this.$http.api.asyncQuickInterface + `/${this.target_id}/?direct=true` : this.$http.api.asyncQuickInterface + `/${this.target_id}/?direct=false` - this.$axios.putForm(url, editForm).then(res => { - if (res.code == 200 || res.code == "OK") { - this.close() - this.$emit('refresh') - // this.$notify({ - // title: '编辑靶场成功', - // type: 'success', - // duration: 2500 - // }) - this.$notify({ - title: res.message, - type: 'success', - duration: 2500 - }) - this.delTimer = setInterval(() => { - this.getTask(res?.result?.task_id || '') - }, 10 * 1000) - } - }).catch(err => { - console.log(err) - }).finally(() => { - this.createLoading = false - this.configLoading = false - }) - } else { - // consensus模式 - const url = isCreate ? this.$http.api.asyncQuickConsensus + `/${this.target_id}/?direct=true` : this.$http.api.asyncQuickConsensus + `/${this.target_id}/?direct=false` - const submitForm = new FormData() - for(const key in editForm) { - submitForm.append(key, editForm[key]) - } - this.$axios.putFormData(url, submitForm).then(res => { - if (res.code == 200 || res.code == "OK") { - this.close() - this.$emit('refresh') - // this.$notify({ - // title: '编辑靶场成功', - // type: 'success', - // duration: 2500 - // }) - this.$notify({ - title: res.message, - type: 'success', - duration: 2500 - }) - this.delTimer = setInterval(() => { - this.getTask(res?.result?.task_id || '') - },10 * 1000) - } - }).catch(err => { - console.log(err) - }).finally(() => { - this.createLoading = false - this.configLoading = false - }) - } - }, - // 模拟比例选择 - radioChange(val) { - this.otherRatio = '' - }, - // 模拟比例用输入框输入 - otherRadioInput(val) { - this.form.ratio = '' - }, - // 选择上传文件 - selectFile(e) { - this.form.file = e.target.files[0] - this.fileName = e.target.files[0].name - }, - // 获取任务进度 - getTask(task_id) { - const url = this.$http.api.task + '/' + task_id - this.$axios.get(url, {}).then(res => { - if(res.task_status !== 'PENDING' && res.task_status !== 'STARTED') { - if (res?.task_result?.code === 500 || res?.task_result?.message === 'false') { - this.$notify({ - title: res?.task_result?.result || `${res.task_id}任务执行完毕,靶场部署失败`, - type: 'success', - duration: 2500 - }) - } else { - this.$notify({ - title: res?.task_result?.result || `${res.task_id}任务执行完毕,靶场部署成功`, - type: 'success', - duration: 2500 - }) - } - clearInterval(this.delTimer) - this.delTimer = null - this.counter = 0 - this.$emit('refresh') - } else { - // this.$notify({ - // title: `${res.task_id}任务执行中`, - // type: 'success', - // duration: 2500 - // }) - } - }).catch(err => { - console.log(err) - }).finally(() => { - this.counter++ - if (this.counter >= 60) { - clearInterval(this.delTimer) - this.delTimer = null - this.counter = 0 - this.$emit('refresh') - } - }) - }, - } -} -</script> - -<style lang="less" scoped> - .quick-dialog{ - width: 620px; - height: 675px; - position: absolute; /* 绝对定位 */ - top: 50%; /* 向下偏移50% */ - left: 50%; /* 向右偏移50% */ - transform: translate(-50%, -50%); /* 回移50% */ - background-image:url('../../../img/Group (2).svg'); - background-repeat: no-repeat; /* 可选,防止图像重复 */ - background-size: 100% 100%; /* 宽度为100%,高度自适应保持宽高比 */ - .quick-form { - margin-top: 70px; - text-align: left; - .long-item-label { - ::v-deep .el-form-item__label { - padding: 12px 12px 0 70px; - } - } - .other-ratio{ - width: 40%; - margin-left: 5%; - margin-right: 5%; - background-color: #0c295b; - display: inline-block; - border: none; - } - } - .upload-file{ - width: 100%; - /*margin-left: 10%;*/ - text-align: center; - color: rgba(81, 84, 102, 0.84); - ::v-deep .el-upload-list { - margin: 0; - list-style: none; - width: 400px !important; - padding-left: 20%; - } - .uploadBgImg{ - width: 320px; - height: 40px; - background-image: url("../../../img/shangchuan.png"); - background-repeat: no-repeat; /* 可选,防止图像重复 */ - background-size: 100% auto; /* 宽度为100%,高度自适应保持宽高比 */ - text-align: right; - padding-right: 10%; - padding-top: 2%; - font-size: 0; - } - .uploadBgImg::file-selector-button{ - padding: 0; - background-color: transparent; - cursor: pointer; - font-size: 0; - } - } - .submit-footer{ - width: 100%; - float: left; - text-align: center; - .glBut{ - width: 90px; - height: 30px; - display: inline-flex; - align-items: center; - justify-content: center; - margin-left: 2%; - background-color: rgba(24, 133, 234, 0.2); - color: #1b7cc4; - } - .but-color { - background-color: #02DDEA; - } - } - } -</style>
\ No newline at end of file |
