summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhyx <[email protected]>2021-10-15 16:42:15 +0800
committerhyx <[email protected]>2021-10-15 16:42:15 +0800
commit7c45b758efded216582dbc976226cb4e66ee5b9c (patch)
tree9f64b6ef3f6d839f67caf67df03ce9eaa176297c
parent3c492fdad9f787bf27443b1cb2a226c49ddae472 (diff)
CN-154 chart列表页面开发
CN-155 chart编辑页面开发
-rw-r--r--src/components/rightBox/settings/ChartBox.vue382
-rw-r--r--src/components/table/settings/ChartTable.vue177
-rw-r--r--src/mixins/dataList.js6
-rw-r--r--src/router/index.js4
-rw-r--r--src/utils/api.js1
-rw-r--r--src/utils/constants.js3
-rw-r--r--src/views/settings/Chart.vue83
7 files changed, 654 insertions, 2 deletions
diff --git a/src/components/rightBox/settings/ChartBox.vue b/src/components/rightBox/settings/ChartBox.vue
new file mode 100644
index 00000000..044adf1f
--- /dev/null
+++ b/src/components/rightBox/settings/ChartBox.vue
@@ -0,0 +1,382 @@
+<template>
+ <div v-click-outside="{object: editObject, func: esc}" class="right-box right-box-user">
+ <div class="right-box__header">
+ <div class="header__title">{{editObject.id ? $t('config.chart.edit') : $t('config.chart.add')}}</div>
+ <div class="header__operation">
+ <span v-cancel="{object: editObject, func: esc}"><i class="cn-icon cn-icon-close"></i></span>
+ </div>
+ </div>
+ <div class="right-box__container">
+ <div class="container__form">
+ <el-form ref="chartForm" :model="editObject" :rules="editObject.id ? rules2 : rules" label-position="top" label-width="120px">
+ <!--name-->
+ <el-form-item :label="$t('overall.name')" prop="name">
+ <el-input id="chart-input-name" v-model="editObject.name" :disabled="editObject.name==='admin' && editObject.id === 1"
+ maxlength="64" placeholder="" show-word-limit size="small" type="text"></el-input>
+ </el-form-item>
+ <!--i18n-->
+ <el-form-item :label="$t('config.chart.i18n')" prop="i18n">
+ <el-input id="chart-input-i18n" v-model="editObject.i18n"
+ maxlength="64" placeholder="" show-word-limit size="small" type="text"></el-input>
+ </el-form-item>
+ <!--type-->
+ <el-form-item :label="$t('config.chart.type')" prop="type">
+ <el-select id="chart-type"
+ v-model="editObject.type"
+ class="right-box__select"
+ clearable
+ collapse-tags
+ placeholder=""
+ popper-class="right-box-select-dropdown prevent-clickoutside"
+ size="small"
+ @change="()=>{ this.$forceUpdate() }">
+
+ <el-option
+ v-for="item in options"
+ :key="item.value"
+ :label="item.label"
+ :value="item.value">
+ <span style="float: left">{{ item.label }}</span><span style="float: right;color: #909399;font-size: 13px;">{{ item.remark }}</span>
+ </el-option>
+
+ </el-select>
+ </el-form-item>
+ <!--panel-->
+ <el-form-item :label="$t('config.chart.panel')" prop="panelId">
+ <el-select id="chart-input-panelId"
+ v-model="editObject.panelId"
+ class="right-box__select"
+ clearable
+ collapse-tags
+ placeholder=""
+ :disabled="editObject.id?true:false"
+ popper-class="right-box-select-dropdown prevent-clickoutside"
+ size="small"
+ @change="getChartData">
+
+ <el-option :key="panelTypeAndRouteMapping.trafficSummary" :label="$t('trafficSummary.trafficSummary')" :value="panelTypeAndRouteMapping.trafficSummary"></el-option>
+ <el-option :key="panelTypeAndRouteMapping.networkAppPerformance" :label="$t('networkAppPerformance.networkAppPerformance')" :value="panelTypeAndRouteMapping.networkAppPerformance"></el-option>
+ <el-option :key="panelTypeAndRouteMapping.dnsServiceInsights" :label="$t('dnsServiceInsights.dnsServiceInsights')" :value="panelTypeAndRouteMapping.dnsServiceInsights"></el-option>
+ <el-option :key="panelTypeAndRouteMapping.ipEntityDetail" :label="$t('entities.ipEntityDetail')" :value="panelTypeAndRouteMapping.ipEntityDetail"></el-option>
+ <el-option :key="panelTypeAndRouteMapping.domainEntityDetail" :label="$t('entities.domainEntityDetail')" :value="panelTypeAndRouteMapping.domainEntityDetail"></el-option>
+ <el-option :key="panelTypeAndRouteMapping.appEntityDetail" :label="$t('entities.appEntityDetail')" :value="panelTypeAndRouteMapping.appEntityDetail"></el-option>
+
+ </el-select>
+ </el-form-item>
+ <!--pid-->
+ <el-form-item :label="$t('config.chart.pid')" prop="pid">
+ <el-select id="chart-pid"
+ v-model="editObject.pid"
+ class="right-box__select"
+ clearable
+ collapse-tags
+ placeholder=""
+ :disabled="editObject.id?true:false"
+ popper-class="right-box-select-dropdown prevent-clickoutside"
+ size="small"
+ @change="()=>{ this.$forceUpdate() }">
+
+ <template v-for="chart in chartData" :key="chart.id">
+ <el-option :label="chart.name" :value="chart.id"></el-option>
+ </template>
+ </el-select>
+ </el-form-item>
+ <!--x-->
+ <el-form-item :label="$t('config.chart.x')" prop="x">
+ <el-input id="chart-input-x" v-model="editObject.x"
+ maxlength="64" placeholder="" show-word-limit size="small" type="text"></el-input>
+ </el-form-item>
+ <!--y-->
+ <el-form-item :label="$t('config.chart.y')" prop="y">
+ <el-input id="chart-input-y" v-model="editObject.y"
+ maxlength="64" placeholder="" show-word-limit size="small" type="text"></el-input>
+ </el-form-item>
+ <!--w-->
+ <el-form-item :label="$t('config.chart.w')" prop="w">
+ <el-input id="chart-input-x" v-model="editObject.w"
+ maxlength="64" placeholder="" show-word-limit size="small" type="text"></el-input>
+ </el-form-item>
+ <!--h-->
+ <el-form-item :label="$t('config.chart.h')" prop="h">
+ <el-input id="chart-input-y" v-model="editObject.h"
+ maxlength="64" placeholder="" show-word-limit size="small" type="text"></el-input>
+ </el-form-item>
+
+ <!--params-->
+ <el-form-item :label="$t('config.chart.params')">
+ <el-input maxlength="1024" show-word-limit :rows="2" size='mini' type="textarea" v-model="editObject.params" id="chart-box-params"/>
+ </el-form-item>
+ <!--remark-->
+ <el-form-item :label="$t('config.chart.remark')">
+ <el-input maxlength="1024" show-word-limit :rows="2" size='mini' type="textarea" v-model="editObject.remark" id="chart-box-remark"/>
+ </el-form-item>
+
+ </el-form>
+ </div>
+ </div>
+ <div class="right-box__footer">
+ <button id="chart-edit-cancel" v-cancel="{object: editObject, func: esc}" class="footer__btn footer__btn--light">
+ <span>{{$t('overall.cancel')}}</span>
+ </button>
+ <button id="chart-edit-save" :class="{'footer__btn--disabled': blockOperation.save}" :disabled="blockOperation.save" class="footer__btn" @click="save">
+ <span>{{$t('overall.save')}}</span>
+ </button>
+ </div>
+ </div>
+</template>
+
+<script>
+import rightBoxMixin from '@/mixins/rightBox'
+import { get, post, put } from '@/utils/http'
+import { panelTypeAndRouteMapping } from '@/utils/constants'
+import { api } from '@/utils/api'
+
+export default {
+ name: 'ChartBox',
+ mixins: [rightBoxMixin],
+ data () {
+ return {
+ url: api.chart,
+ loginName: localStorage.getItem('cn-username'),
+ panelTypeAndRouteMapping: panelTypeAndRouteMapping,
+ rules: { // 表单校验规则
+ name: [
+ { required: true, message: this.$t('validate.required'), trigger: 'blur' }
+ ],
+ type: [
+ { required: true, message: this.$t('validate.required'), trigger: 'blur' }
+ ],
+ panel_id: [
+ { required: true, message: this.$t('validate.required'), trigger: 'blur' }
+ ],
+ x: [
+ { required: true, message: this.$t('validate.required'), trigger: 'blur' }
+ ],
+ y: [
+ { required: true, message: this.$t('validate.required'), trigger: 'blur' }
+ ],
+ w: [
+ { required: true, message: this.$t('validate.required'), trigger: 'blur' }
+ ],
+ h: [
+ { required: true, message: this.$t('validate.required'), trigger: 'blur' }
+ ]
+ },
+ rules2: { // 表单校验规则
+ name: [
+ { required: true, message: this.$t('validate.required'), trigger: 'blur' }
+ ],
+ type: [
+ { required: true, message: this.$t('validate.required'), trigger: 'blur' }
+ ],
+ panel_id: [
+ { required: true, message: this.$t('validate.required'), trigger: 'blur' }
+ ],
+ x: [
+ { required: true, message: this.$t('validate.required'), trigger: 'blur' }
+ ],
+ y: [
+ { required: true, message: this.$t('validate.required'), trigger: 'blur' }
+ ],
+ w: [
+ { required: true, message: this.$t('validate.required'), trigger: 'blur' }
+ ],
+ h: [
+ { required: true, message: this.$t('validate.required'), trigger: 'blur' }
+ ]
+ },
+ chartData: [],
+ options: [
+ {
+ value: 1,
+ label: 'map-1',
+ remark: '流量流向地图-连线'
+ },
+ {
+ value: 2,
+ label: 'map-2',
+ remark: '地图-色块'
+ }, {
+ value: 3,
+ label: 'map-3',
+ remark: '地图-点'
+ },
+ {
+ value: 4,
+ label: 'map-4',
+ remark: '地图-点'
+ }, {
+ value: 11,
+ label: 'line-1',
+ remark: '折线图-常规'
+ },
+ {
+ value: 61,
+ label: 'table-1',
+ remark: '表格'
+ }, {
+ value: 62,
+ label: 'table-2',
+ remark: 'DNS记录'
+ },
+ {
+ value: 31,
+ label: 'pie-1',
+ remark: '饼图-带联动表格'
+ }, {
+ value: 51,
+ label: 'singleValue-1',
+ remark: '单值图'
+ },
+ {
+ value: 91,
+ label: 'tab-container',
+ remark: 'tab标签(容器)'
+ }, {
+ value: 92,
+ label: 'tab-item',
+ remark: 'tab标签(标签页)'
+ },
+ {
+ value: 93,
+ label: 'title',
+ remark: '标题'
+ }, {
+ value: 94,
+ label: 'group',
+ remark: '组'
+ },
+ {
+ value: 12,
+ label: 'line-2',
+ remark: '折线图-带统计'
+ }, {
+ value: 52,
+ label: 'singleValue-2',
+ remark: '详情单值图'
+ },
+ {
+ value: 53,
+ label: 'singleValue-3',
+ remark: '单值图'
+ }, {
+ value: 13,
+ label: 'line-3',
+ remark: '折线图-堆叠面积'
+ },
+ {
+ value: 21,
+ label: 'bar-1',
+ remark: '柱状图'
+ }, {
+ value: 22,
+ label: 'bar-2',
+ remark: '开放端口'
+ },
+ {
+ value: 32,
+ label: 'pie-2',
+ remark: '饼图-常规'
+ }, {
+ value: 33,
+ label: 'pie-3',
+ remark: '托管域名'
+ },
+ {
+ value: 34,
+ label: 'pie-4',
+ remark: '相关域名'
+ }, {
+ value: 42,
+ label: 'relation-2',
+ remark: '关系图谱'
+ },
+ {
+ value: 43,
+ label: 'relation-3',
+ remark: '访问链路图'
+ },
+ {
+ value: 82,
+ label: 'base-2',
+ remark: 'APP基本信息'
+ }, {
+ value: 83,
+ label: 'list-1',
+ remark: 'Whois'
+ },
+ {
+ value: 84,
+ label: 'list-2',
+ remark: 'DNS记录'
+ }
+ ]
+ }
+ },
+ setup () {
+ },
+ mounted () {
+ if (this.editObject.id) {
+ this.getChartData(this.editObject.panelId)
+ }
+ },
+ watch: {
+ 'editObject.panelId': function (newValue, oldValue) {
+ this.editObject.pid = ''
+ }
+ },
+ methods: {
+ isCurrentUser (username) {
+ return localStorage.getItem('cn-username') === username
+ },
+ /* 密码失去焦点 检验确认密码 */
+ pinBlur () {
+ if (this.editObject.pin && this.editObject.pinChange) {
+ this.$refs.chartForm.validateField('pinChange')
+ }
+ },
+ save () {
+ if (this.blockOperation.save) { return }
+ this.blockOperation.save = true
+
+ this.$refs.chartForm.validate((valid) => {
+ if (valid) {
+ if (this.editObject.id) {
+ put(this.url, this.editObject).then(res => {
+ this.blockOperation.save = false
+ if (res.code === 200) {
+ this.$message({ duration: 2000, type: 'success', message: this.$t('tip.saveSuccess') })
+ this.esc(true)
+ } else {
+ this.$message.error(res.msg)
+ }
+ })
+ } else {
+ post(this.url, this.editObject).then(res => {
+ this.blockOperation.save = false
+ if (res.code === 200) {
+ this.$message({ duration: 2000, type: 'success', message: this.$t('tip.saveSuccess') })
+ this.esc(true)
+ } else {
+ this.$message.error(res.msg)
+ }
+ })
+ }
+ } else {
+ this.blockOperation.save = false
+ return false
+ }
+ })
+ },
+ async getChartData (value) {
+ await get('/visual/chart?panelId=' + value).then(response => {
+ if (response.code === 200) {
+ this.chartData = response.data.list
+ }
+ })
+
+ // this.$set(this.editObject, 'pid', '')
+ }
+ }
+}
+</script>
diff --git a/src/components/table/settings/ChartTable.vue b/src/components/table/settings/ChartTable.vue
new file mode 100644
index 00000000..18794378
--- /dev/null
+++ b/src/components/table/settings/ChartTable.vue
@@ -0,0 +1,177 @@
+<template>
+ <el-table
+ id="chartTable"
+ ref="dataTable"
+ :data="tableData"
+ :height="height"
+ border
+ @header-dragend="dragend"
+ @sort-change="tableDataSort"
+ @selection-change="selectionChange"
+ >
+ <el-table-column
+ :resizable="false"
+ align="center"
+ type="selection"
+ width="55">
+ </el-table-column>
+ <el-table-column
+ v-for="(item, index) in customTableTitles"
+ :key="`col-${index}`"
+ :fixed="item.fixed"
+ :label="item.label"
+ :min-width="`${item.minWidth}`"
+ :prop="item.prop"
+ :resizable="true"
+ :sort-orders="['ascending', 'descending']"
+ :sortable="item.sortable"
+ :width="`${item.width}`"
+ class="data-column"
+ >
+ <template #header>
+ <span class="data-column__span">{{item.label}}</span>
+ <div class="col-resize-area"></div>
+ </template>
+ <template #default="scope" :column="item">
+ <template v-if="item.prop === 'name'">
+ <template v-if="scope.row.i18n">
+ <span>{{$t(scope.row.i18n)}}</span>
+ </template>
+ <template v-else-if="scope.row.name">
+ <span>{{scope.row.name}}</span>
+ </template>
+ <template v-else>
+ <span>-</span>
+ </template>
+ </template>
+ <template v-else-if="item.prop === 'buildIn'">
+ <template v-if="scope.row[item.prop]==1">
+ {{$t('config.chart.buildIn.yes')}}
+ </template>
+ <template v-else-if="scope.row[item.prop]==0">
+ {{$t('config.chart.buildIn.no')}}
+ </template>
+ <template v-else>
+ {{scope.row[item.prop]}}
+ </template>
+ </template>
+ <template v-else-if="item.prop === 'panelId'">
+ <template v-if="scope.row[item.prop]==panelTypeAndRouteMapping.trafficSummary">
+ {{$t('trafficSummary.trafficSummary')}}
+ </template>
+ <template v-else-if="scope.row[item.prop]==panelTypeAndRouteMapping.networkAppPerformance">
+ {{$t('networkAppPerformance.networkAppPerformance')}}
+ </template>
+ <template v-else-if="scope.row[item.prop]==panelTypeAndRouteMapping.dnsServiceInsights">
+ {{$t('dnsServiceInsights.dnsServiceInsights')}}
+ </template>
+ <template v-else-if="scope.row[item.prop]==panelTypeAndRouteMapping.ipEntityDetail">
+ {{$t('entities.ipEntityDetail')}}
+ </template>
+ <template v-else-if="scope.row[item.prop]==panelTypeAndRouteMapping.domainEntityDetail">
+ {{$t('entities.domainEntityDetail')}}
+ </template>
+ <template v-else-if="scope.row[item.prop]==panelTypeAndRouteMapping.appEntityDetail">
+ {{$t('entities.appEntityDetail')}}
+ </template>
+ <template v-else>
+ {{scope.row[item.prop]}}
+ </template>
+ </template>
+ <span v-else>{{scope.row[item.prop]}}</span>
+ </template>
+ </el-table-column>
+ <el-table-column
+ :resizable="false"
+ :width="operationWidth"
+ fixed="right">
+ <template #header>
+ <div class="table-operation-title">{{$t('overall.option')}}</div>
+ </template>
+ <template #default="scope">
+ <div class="table-operation-items">
+ <button class="table-operation-item" @click="tableOperation(['edit', scope.row])"><i class="cn-icon cn-icon-edit"></i></button>
+ <el-dropdown size="medium" trigger="hover" @command="tableOperation">
+ <div class="table-operation-item table-operation-item--more">
+ <i class="cn-icon cn-icon-more-arrow-down"></i>
+ </div>
+ <template #dropdown>
+ <el-dropdown-menu >
+ <el-dropdown-item :command="['delete', scope.row]" :disabled="scope.row['buildIn'] === 1"><i class="cn-icon cn-icon-delete"></i><span class="operation-dropdown-text">{{$t('overall.delete')}}</span></el-dropdown-item>
+ </el-dropdown-menu>
+ </template>
+ </el-dropdown>
+ </div>
+ </template>
+ </el-table-column>
+ </el-table>
+</template>
+
+<script>
+import table from '@/mixins/table'
+import { panelTypeAndRouteMapping } from '@/utils/constants'
+import { api } from '@/utils/api'
+
+export default {
+ name: 'chartTable',
+ mixins: [table],
+ data () {
+ return {
+ panelTypeAndRouteMapping: panelTypeAndRouteMapping,
+ tableTitle: [ // 原table列
+ {
+ label: 'ID',
+ prop: 'id',
+ show: true,
+ width: 80,
+ sortable: 'custom'
+ }, {
+ label: this.$t('config.chart.name'),
+ prop: 'name',
+ show: true
+ }, {
+ label: this.$t('config.chart.params'),
+ prop: 'params',
+ show: true
+ }, {
+ label: this.$t('config.chart.panel'),
+ prop: 'panelId',
+ show: true
+ }, {
+ label: this.$t('config.chart.i18n'),
+ prop: 'i18n',
+ show: true
+ }, {
+ label: this.$t('config.chart.type'),
+ prop: 'type',
+ show: true
+ }, {
+ label: this.$t('config.chart.x'),
+ prop: 'x',
+ show: true
+ }, {
+ label: this.$t('config.chart.y'),
+ prop: 'y',
+ show: true
+ }, {
+ label: this.$t('config.chart.w'),
+ prop: 'w',
+ show: true
+ }, {
+ label: this.$t('config.chart.h'),
+ prop: 'h',
+ show: true
+ }, {
+ label: this.$t('config.chart.buildIn'),
+ prop: 'buildIn',
+ show: true
+ }, {
+ label: this.$t('config.chart.remark'),
+ prop: 'remark',
+ show: true
+ }
+ ]
+ }
+ }
+}
+</script>
diff --git a/src/mixins/dataList.js b/src/mixins/dataList.js
index ed261072..b9581603 100644
--- a/src/mixins/dataList.js
+++ b/src/mixins/dataList.js
@@ -69,7 +69,11 @@ export default {
this.searchLabel = { ...this.searchLabel, ...this.pageObj }
this.tools.loading = true
delete this.searchLabel.total
- get(this.url, this.searchLabel).then(response => {
+ let listUrl = this.url
+ if (this.listUrl) {
+ listUrl = this.listUrl
+ }
+ get(listUrl, this.searchLabel).then(response => {
this.tools.loading = false
if (response.code === 200) {
for (let i = 0; i < response.data.list.length; i++) {
diff --git a/src/router/index.js b/src/router/index.js
index eb35f671..14ac931d 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -37,6 +37,10 @@ const routes = [
{
path: '/galaxyProxy',
component: () => import('@/views/settings/GalaxyProxy')
+ },
+ {
+ path: '/chart',
+ component: () => import('@/views/settings/Chart')
}
]
}
diff --git a/src/utils/api.js b/src/utils/api.js
index 5154d77a..93c07e18 100644
--- a/src/utils/api.js
+++ b/src/utils/api.js
@@ -16,6 +16,7 @@ export const api = {
role: '/sys/role',
galaxyProxy: '/galaxy/setting',
operationLog: '/sys/log',
+ chartList: '/visual/chart/list',
// 业务
panel: '/visual/panel',
chart: '/visual/chart',
diff --git a/src/utils/constants.js b/src/utils/constants.js
index 3e63a9f4..f365fe8f 100644
--- a/src/utils/constants.js
+++ b/src/utils/constants.js
@@ -30,7 +30,8 @@ export const fromRoute = {
networkAppPerformance: 'networkAppPerformance',
dnsServiceInsights: 'dnsServiceInsights',
user: 'user',
- galaxyProxy: 'galaxyProxy'
+ galaxyProxy: 'galaxyProxy',
+ chart: 'chart'
}
/* panel类别和名称之间的映射 */
diff --git a/src/views/settings/Chart.vue b/src/views/settings/Chart.vue
new file mode 100644
index 00000000..72e2edf3
--- /dev/null
+++ b/src/views/settings/Chart.vue
@@ -0,0 +1,83 @@
+<template>
+ <div>
+ <cn-data-list
+ ref="dataList"
+ :tableId="tableId"
+ v-model:custom-table-title="tools.customTableTitle"
+ :api="url"
+ :from="fromRoute.chart"
+ :layout="['columnCustomize','elementSet','searchInput']"
+ @search="search"
+ >
+ <template #top-tool-right>
+ <button
+ id="account-add"
+ class="top-tool-btn margin-r-10"
+ type="button"
+ @click="add"
+ >
+ <i class="cn-icon-add cn-icon"/>
+ </button>
+ </template>
+ <template #default>
+ <chart-table
+ ref="dataTable"
+ v-loading="tools.loading"
+ :api="url"
+ :custom-table-title="tools.customTableTitle"
+ :height="mainTableHeight"
+ :table-data="tableData"
+ @delete="del"
+ @edit="edit"
+ @orderBy="tableDataSort"
+ @reload="getTableData"
+ @selectionChange="selectionChange"
+ />
+ </template>
+ <template #pagination>
+ <pagination ref="pagination" :page-obj="pageObj" :table-id="tableId" @pageNo='pageNo' @pageSize='pageSize'></pagination>
+ </template>
+ </cn-data-list>
+ <el-drawer
+ v-model="rightBox.show"
+ direction="rtl"
+ :with-header="false"
+ :size="700"
+ destroy-on-close>
+ <chart-box
+ :object="object"
+ @close="closeRightBox"
+ />
+ </el-drawer>
+ </div>
+</template>
+<script>
+import cnDataList from '@/components/table/CnDataList'
+import dataListMixin from '@/mixins/dataList'
+import chartTable from '@/components/table/settings/ChartTable'
+import chartBox from '@/components/rightBox/settings/ChartBox'
+import { api } from '@/utils/api'
+
+export default {
+ name: 'Chart',
+ mixins: [dataListMixin],
+ components: {
+ cnDataList,
+ chartTable,
+ chartBox
+ },
+ data () {
+ return {
+ url: api.chart,
+ listUrl: api.chartList,
+ blankObject: { // 空白对象
+ id: '',
+ name: '',
+ params: '',
+ i18n: ''
+ },
+ tableId: 'chartTable'
+ }
+ }
+}
+</script>