summaryrefslogtreecommitdiff
path: root/src/views/rangeManage
diff options
context:
space:
mode:
authorll <[email protected]>2024-07-11 20:41:37 +0800
committerll <[email protected]>2024-07-11 20:41:37 +0800
commitbafa736c04845e103d7e3747a8152b410d1628fb (patch)
tree032d00938963b7cb21ff5c57e4f08723b521ae41 /src/views/rangeManage
parentac8bc7f895baa346cdb498e1b8be41ce66130afd (diff)
Initial commitHEADmain
Diffstat (limited to 'src/views/rangeManage')
-rw-r--r--src/views/rangeManage/index.vue420
-rw-r--r--src/views/rangeManage/mock.js90
-rw-r--r--src/views/rangeManage/module/CustomCreate.vue183
-rw-r--r--src/views/rangeManage/module/Header.vue161
-rw-r--r--src/views/rangeManage/module/QuickCreate.vue437
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