NEZ-2121 feat : issue 列表页面开发

This commit is contained in:
likexuan
2022-08-12 17:52:06 +08:00
parent 8d711da2cf
commit c318d77be0
9 changed files with 1087 additions and 30 deletions

View File

@@ -1401,7 +1401,7 @@
},
"@mapbox/geojson-rewind": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/@mapbox/geojson-rewind/-/geojson-rewind-0.5.2.tgz",
"resolved": "https://registry.npmmirror.com/@mapbox/geojson-rewind/-/geojson-rewind-0.5.2.tgz",
"integrity": "sha512-tJaT+RbYGJYStt7wI3cq4Nl4SXxG8W7JDG5DMJu97V25RnbNg3QtQtf+KD+VLjNpWKYsRvXDNmNrBgEETr1ifA==",
"requires": {
"get-stream": "^6.0.1",
@@ -1410,44 +1410,44 @@
"dependencies": {
"get-stream": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
"resolved": "https://registry.npmmirror.com/get-stream/-/get-stream-6.0.1.tgz",
"integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg=="
},
"minimist": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
"resolved": "https://registry.npmmirror.com/minimist/-/minimist-1.2.6.tgz",
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
}
}
},
"@mapbox/jsonlint-lines-primitives": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz",
"resolved": "https://registry.npmmirror.com/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz",
"integrity": "sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ=="
},
"@mapbox/mapbox-gl-supported": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-2.0.1.tgz",
"resolved": "https://registry.npmmirror.com/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-2.0.1.tgz",
"integrity": "sha512-HP6XvfNIzfoMVfyGjBckjiAOQK9WfX0ywdLubuPMPv+Vqf5fj0uCbgBQYpiqcWZT6cbyyRnTSXDheT1ugvF6UQ=="
},
"@mapbox/point-geometry": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz",
"resolved": "https://registry.npmmirror.com/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz",
"integrity": "sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ=="
},
"@mapbox/tiny-sdf": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-2.0.5.tgz",
"resolved": "https://registry.npmmirror.com/@mapbox/tiny-sdf/-/tiny-sdf-2.0.5.tgz",
"integrity": "sha512-OhXt2lS//WpLdkqrzo/KwB7SRD8AiNTFFzuo9n14IBupzIMa67yGItcK7I2W9D8Ghpa4T04Sw9FWsKCJG50Bxw=="
},
"@mapbox/unitbezier": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/@mapbox/unitbezier/-/unitbezier-0.0.1.tgz",
"resolved": "https://registry.npmmirror.com/@mapbox/unitbezier/-/unitbezier-0.0.1.tgz",
"integrity": "sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw=="
},
"@mapbox/vector-tile": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/@mapbox/vector-tile/-/vector-tile-1.3.1.tgz",
"resolved": "https://registry.npmmirror.com/@mapbox/vector-tile/-/vector-tile-1.3.1.tgz",
"integrity": "sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw==",
"requires": {
"@mapbox/point-geometry": "~0.1.0"
@@ -1455,7 +1455,7 @@
},
"@mapbox/whoots-js": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz",
"resolved": "https://registry.npmmirror.com/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz",
"integrity": "sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q=="
},
"@riophae/vue-treeselect": {
@@ -1573,7 +1573,7 @@
},
"@types/geojson": {
"version": "7946.0.10",
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.10.tgz",
"resolved": "https://registry.npmmirror.com/@types/geojson/-/geojson-7946.0.10.tgz",
"integrity": "sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA=="
},
"@types/istanbul-lib-coverage": {
@@ -1609,12 +1609,12 @@
},
"@types/mapbox__point-geometry": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/@types/mapbox__point-geometry/-/mapbox__point-geometry-0.1.2.tgz",
"resolved": "https://registry.npmmirror.com/@types/mapbox__point-geometry/-/mapbox__point-geometry-0.1.2.tgz",
"integrity": "sha512-D0lgCq+3VWV85ey1MZVkE8ZveyuvW5VAfuahVTQRpXFQTxw03SuIf1/K4UQ87MMIXVKzpFjXFiFMZzLj2kU+iA=="
},
"@types/mapbox__vector-tile": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@types/mapbox__vector-tile/-/mapbox__vector-tile-1.3.0.tgz",
"resolved": "https://registry.npmmirror.com/@types/mapbox__vector-tile/-/mapbox__vector-tile-1.3.0.tgz",
"integrity": "sha512-kDwVreQO5V4c8yAxzZVQLE5tyWF+IPToAanloQaSnwfXmIcJ7cyOrv8z4Ft4y7PsLYmhWXmON8MBV8RX0Rgr8g==",
"requires": {
"@types/geojson": "*",
@@ -1624,7 +1624,7 @@
},
"@types/pbf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@types/pbf/-/pbf-3.0.2.tgz",
"resolved": "https://registry.npmmirror.com/@types/pbf/-/pbf-3.0.2.tgz",
"integrity": "sha512-EDrLIPaPXOZqDjrkzxxbX7UlJSeQVgah3i0aA4pOSzmK9zq3BIh7/MZIQxED7slJByvKM4Gc6Hypyu2lJzh3SQ=="
},
"@types/q": {
@@ -5014,7 +5014,7 @@
},
"csscolorparser": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/csscolorparser/-/csscolorparser-1.0.3.tgz",
"resolved": "https://registry.npmmirror.com/csscolorparser/-/csscolorparser-1.0.3.tgz",
"integrity": "sha512-umPSgYwZkdFoUrH5hIq5kf0wPSXiro51nPw0j2K/c83KflkPSTBGMz6NJvMB+07VlL0y7VPo6QJcDjcgKTTm3w=="
},
"cssesc": {
@@ -6457,7 +6457,7 @@
},
"earcut": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz",
"resolved": "https://registry.npmmirror.com/earcut/-/earcut-2.2.4.tgz",
"integrity": "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ=="
},
"easings-css": {
@@ -8351,7 +8351,7 @@
},
"geojson-vt": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-3.2.1.tgz",
"resolved": "https://registry.npmmirror.com/geojson-vt/-/geojson-vt-3.2.1.tgz",
"integrity": "sha512-EvGQQi/zPrDA6zr6BnJD/YhwAkBP8nnJ9emh3EnHQKVMfg/MRVtPbMYdgVy/IaEmn4UfagD2a6fafPDL5hbtwg=="
},
"get-caller-file": {
@@ -8403,7 +8403,7 @@
},
"gl-matrix": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.4.3.tgz",
"resolved": "https://registry.npmmirror.com/gl-matrix/-/gl-matrix-3.4.3.tgz",
"integrity": "sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA=="
},
"glob": {
@@ -11033,7 +11033,7 @@
},
"kdbush": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/kdbush/-/kdbush-3.0.0.tgz",
"resolved": "https://registry.npmmirror.com/kdbush/-/kdbush-3.0.0.tgz",
"integrity": "sha512-hRkd6/XW4HTsA9vjVpY9tuXJYLSlelnkTmVFu4M9/7MIYQtFcHpbugAU7UbOfjOiVSVYl2fqgBuJ32JUmRo5Ew=="
},
"keyv": {
@@ -11391,7 +11391,7 @@
},
"maplibre-gl": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-2.2.0.tgz",
"resolved": "https://registry.npmmirror.com/maplibre-gl/-/maplibre-gl-2.2.0.tgz",
"integrity": "sha512-5LB7ROIxvBADPa4PmU2j+mp0jG5IIbEidCOyZEXVbEriluMJn0hz28vszVb4Cr2IA4YQ9cnERqjHaf33MHIRBQ==",
"requires": {
"@mapbox/geojson-rewind": "^0.5.2",
@@ -11911,7 +11911,7 @@
},
"murmurhash-js": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/murmurhash-js/-/murmurhash-js-1.0.0.tgz",
"resolved": "https://registry.npmmirror.com/murmurhash-js/-/murmurhash-js-1.0.0.tgz",
"integrity": "sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw=="
},
"mv": {
@@ -12838,7 +12838,7 @@
},
"pbf": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/pbf/-/pbf-3.2.1.tgz",
"resolved": "https://registry.npmmirror.com/pbf/-/pbf-3.2.1.tgz",
"integrity": "sha512-ClrV7pNOn7rtmoQVF4TS1vyU0WhYRnP92fzbfF75jAIwpnzdJXf8iTd4CMEqO4yUenH6NDqLiwjqlh6QgZzgLQ==",
"requires": {
"ieee754": "^1.1.12",
@@ -15279,7 +15279,7 @@
},
"potpack": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/potpack/-/potpack-1.0.2.tgz",
"resolved": "https://registry.npmmirror.com/potpack/-/potpack-1.0.2.tgz",
"integrity": "sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ=="
},
"preload": {
@@ -15428,7 +15428,7 @@
},
"protocol-buffers-schema": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz",
"resolved": "https://registry.npmmirror.com/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz",
"integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw=="
},
"proxy-addr": {
@@ -15550,7 +15550,7 @@
},
"quickselect": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz",
"resolved": "https://registry.npmmirror.com/quickselect/-/quickselect-2.0.0.tgz",
"integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw=="
},
"quill": {
@@ -16045,7 +16045,7 @@
},
"resolve-protobuf-schema": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz",
"resolved": "https://registry.npmmirror.com/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz",
"integrity": "sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==",
"requires": {
"protocol-buffers-schema": "^3.3.1"
@@ -17548,7 +17548,7 @@
},
"supercluster": {
"version": "7.1.5",
"resolved": "https://registry.npmjs.org/supercluster/-/supercluster-7.1.5.tgz",
"resolved": "https://registry.npmmirror.com/supercluster/-/supercluster-7.1.5.tgz",
"integrity": "sha512-EulshI3pGUM66o6ZdH3ReiFcvHpM3vAigyK+vcxdjpJyEbIIrtbmBdY23mGgnI24uXiGFvrGq9Gkum/8U7vJWg==",
"requires": {
"kdbush": "^3.0.0"
@@ -18030,7 +18030,7 @@
},
"tinyqueue": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-2.0.3.tgz",
"resolved": "https://registry.npmmirror.com/tinyqueue/-/tinyqueue-2.0.3.tgz",
"integrity": "sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA=="
},
"tmp": {
@@ -18704,7 +18704,7 @@
},
"vt-pbf": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/vt-pbf/-/vt-pbf-3.1.3.tgz",
"resolved": "https://registry.npmmirror.com/vt-pbf/-/vt-pbf-3.1.3.tgz",
"integrity": "sha512-2LzDFzt0mZKZ9IpVF2r69G9bXaP2Q2sArJCmcCgvfTdCCZzSyz4aCLoQyUilu37Ll56tCblIZrXFIjNUpGIlmA==",
"requires": {
"@mapbox/point-geometry": "0.1.0",

View File

@@ -361,6 +361,7 @@ export const fromRoute = {
user: 'user',
agent: 'agent',
recordRule: 'recordRule',
issue: 'issue',
dc: 'dc',
role: 'role',
project: 'project',

View File

@@ -1111,6 +1111,185 @@ export default {
jsonKey: 'val'
}
}
} else if (path === 'issue') {
searchKeys = {
// key: path 键
// value: vue set 参数
pageNo: { target: this.pageObj, propertyName: 'pageNo', type: 'number' },
pageSize: { target: this.pageObj, propertyName: 'pageSize', type: 'number' },
orderBy: { target: this.$data, propertyName: 'orderBy', type: 'string' },
ids: {
target: this.searchLabel,
isSearchInput: true,
propertyName: 'ids',
type: 'string',
defaultJson: {
disabled: false,
label: 'ids',
name: 'ID',
type: 'input',
val: ''
},
jsonKey: 'val'
},
name: {
target: this.searchLabel,
isSearchInput: true,
propertyName: 'name',
type: 'string',
defaultJson: {
disabled: false,
id: 'name',
label: 'name',
name: 'Name',
type: 'input',
val: ''
},
jsonKey: 'val'
},
type: {
target: this.searchLabel,
isSearchInput: true,
propertyName: 'type',
type: 'string',
defaultJson: {
disabled: false,
label: 'issueType',
name: 'Type',
readonly: true,
type: 'issueType',
val: ''
},
jsonKey: 'val'
},
state: {
target: this.searchLabel,
isSearchInput: true,
propertyName: 'state',
type: 'Number',
defaultJson: {
disabled: false,
label: 'issueState',
name: 'State',
readonly: true,
type: 'select',
val: ''
},
jsonKey: 'val'
},
priority: {
target: this.searchLabel,
isSearchInput: true,
propertyName: 'priority',
type: 'Number',
defaultJson: {
disabled: false,
label: 'priority',
name: 'Priority',
type: 'select',
val: ''
},
jsonKey: 'val'
},
assetsId: {
target: this.searchLabel,
isSearchInput: true,
propertyName: 'assetsId',
type: 'Number',
defaultJson: {
disabled: false,
label: 'assetsId',
name: 'Assets id',
type: 'input',
val: ''
},
jsonKey: 'val'
},
assetName: {
target: this.searchLabel,
isSearchInput: true,
propertyName: 'assetName',
type: 'string',
defaultJson: {
disabled: false,
label: 'assetName',
name: 'Assets name',
type: 'input',
val: ''
},
jsonKey: 'val'
},
cid: {
target: this.searchLabel,
isSearchInput: true,
propertyName: 'cid',
type: 'string',
defaultJson: {
disabled: false,
label: 'cid',
name: 'Create user',
type: 'issue',
val: ''
},
jsonKey: 'val'
},
uid: {
target: this.searchLabel,
isSearchInput: true,
propertyName: 'uid',
type: 'string',
defaultJson: {
disabled: false,
label: 'uid',
name: 'Update user',
type: 'issue',
val: ''
},
jsonKey: 'val'
},
rid: {
target: this.searchLabel,
isSearchInput: true,
propertyName: 'rid',
type: 'string',
defaultJson: {
disabled: false,
label: 'rid',
name: 'Reporter',
type: 'issue',
val: ''
},
jsonKey: 'val'
},
aid: {
target: this.searchLabel,
isSearchInput: true,
propertyName: 'aid',
type: 'string',
defaultJson: {
disabled: false,
label: 'aid',
name: 'Assignee',
type: 'issue',
val: ''
},
jsonKey: 'val'
},
starrd: {
target: this.searchLabel,
isSearchInput: true,
propertyName: 'starrd',
type: 'Number',
defaultJson: {
disabled: false,
label: 'starrd',
name: 'Starrd',
type: 'select',
val: ''
},
jsonKey: 'val'
}
}
}
this.initQueryFromPath(searchKeys)
},

View File

@@ -0,0 +1,350 @@
<template>
<div class="right-box right-box-issue" v-clickoutside="{obj:editIssue,func:clickOutside}">
<!-- begin--标题-->
<div class="right-box__header">
<div class="header__title">{{editIssue.id ? $t("overall.issue.edit") : $t("overall.createIssue")}}</div>
<div class="header__operation">
<span v-cancel="{obj: editIssue, func: esc}"><i class="nz-icon nz-icon-close" :title="$t('overall.close')"></i></span>
</div>
</div>
<!-- end--标题-->
<!-- begin--表单-->
<div class="right-box__container">
<div class="container__form">
<el-form ref="issueForm" :model="editIssue"
:rules="rules" label-position="top" label-width="120px">
<!-- title -->
<el-form-item :label='$t("project.topology.title")' prop="name">
<el-input
v-model="editIssue.name" :placeholder="''"
maxlength="64"
show-word-limit
size="small">
</el-input>
</el-form-item>
<!--type-->
<el-form-item prop="type" :label='$t("overall.type")' :rules="{ required: true, message: $t('validate.required'), change: 'blur'}">
<el-select
v-model="editIssue.type"
:placeholder="issueTypeSelect[0]"
style="margin-right: 10px"
filterable
allow-create
default-first-option
>
<el-option
v-for="item in issueTypeSelect"
:value="item"
:label="item"
:key="item"/>
</el-select>
</el-form-item>
<!--priority-->
<el-form-item :label='$t("alert.severity")' prop="priority">
<el-input v-model="editIssue.priority" :placeholder="'High'" size="small"></el-input>
</el-form-item>
<!--state-->
<el-form-item :label="$t('overall.state')" prop="state">
<el-select v-model="editIssue.state" clearable :placeholder="$t('issue.open')" size="small" value-key="state">
<el-option v-for="item in stateData" :key="item.id" :label="item.value" :value="item.value">
{{item.value}}
</el-option>
</el-select>
</el-form-item>
<!-- Relate Assets -->
<el-form-item :label="$t('issue.relateAssets')" prop="assetIds">
<v-selectpage
ref="selectPage"
style="flex: 1"
data="asset/asset"
:params="selectPageParams"
:tb-columns="columns"
key-field="id"
show-field="manageIp"
search-field="manageIp"
v-model="editIssue.assetIds"
size="small"
:language="language"
:placeholder="$t('dashboard.panel.chartForm.selectAsset')"
id="box-input-asset-id"
:result-format="resultFormat"></v-selectpage>
</el-form-item>
<!-- Reporter -->
<el-form-item :label='$t("issue.reporter")' prop="rid">
<el-select
id="issue-box-input-receiver"
v-model.trim="editIssue.rid"
class="right-box__select"
filterable
multiple
placeholder=""
popper-class="prevent-clickoutside right-box-select-top"
size="small"
value-key="userId"
>
<el-option
style="width: 620px"
v-for="item in userData"
:key="item.id"
:label="item.name"
:value="item.id">
<span class="user-name" :title="item.name">{{item.name}}</span><span class="user-username" :title="item.username">@{{item.username}}</span>
</el-option>
</el-select>
</el-form-item>
<!-- Assignee -->
<el-form-item :label='$t("issue.assignee")' prop="aid">
<el-select
id="issue-box-input-receiver"
v-model.trim="editIssue.aid"
class="right-box__select"
filterable
multiple
placeholder=""
popper-class="prevent-clickoutside right-box-select-top"
size="small"
value-key="userId"
>
<el-option
style="width: 620px"
v-for="item in userData"
:key="item.id"
:label="item.name"
:value="item.id">
<span class="user-name" :title="item.name">{{item.name}}</span><span class="user-username" :title="item.username">@{{item.username}}</span>
</el-option>
</el-select>
</el-form-item>
<!-- remark -->
<el-form-item :label='$t("overall.remark")' prop="content">
<rich-text-editor ref="richTextEditor" :edit-data="editIssue.content" @after-init="afterInitRich"></rich-text-editor>
</el-form-item>
</el-form>
</div>
</div>
<!-- end--表单-->
<!--底部按钮-->
<div class="right-box__footer">
<button v-cancel="{obj:editIssue,func:esc}" id="alert-box-esc"
class="footer__btn footer__btn--light">
<span>{{$t('overall.cancel')}}</span>
</button>
<button :class="{'nz-btn-disabled':prevent_opt.save}" :disabled="prevent_opt.save" @click="save"
class="footer__btn" id="alert-box-save">
<span>{{$t('overall.save')}}</span>
</button>
</div>
</div>
</template>
<script>
import editRigthBox from '../mixin/editRigthBox'
import richTextEditor from '@/components/chart/richTextEditor'
export default {
name: 'issueBox',
components: {
richTextEditor
},
mixins: [editRigthBox],
props: {
issue: Object
},
data () {
return {
issueTypeSelect: [],
selectPageParams: { pageNumber: 1 },
userData: [],
editIssue: {
id: '',
name: '',
type: '',
content: '',
state: '',
priority: '',
rid: '',
aid: '',
assetIds: ''
},
rules: {
name: [
{ required: true, message: this.$t('validate.required'), trigger: 'change' }
]
// type: [
// { required: true, message: this.$t('validate.required'), trigger: 'change' }
// ],
// expr: [
// { required: true, message: this.$t('validate.required'), trigger: 'change' }
// ],
// labels: [
// { required: true, message: this.$t('validate.required'), trigger: 'change' },
// { validator: arrLength, trigger: 'change' }
// ],
// state: [
// { required: true, message: this.$t('validate.required'), trigger: 'change' }
// ]
},
columns: [
{ title: 'ID', data: 'id' },
{
title: 'Name',
data: function (row) {
if (row.name.length > 15) {
return row.name.substring(0, 12) + '...'
}
return row.name
}
},
{ title: 'Manage Ip', data: 'manageIp' },
{
title: 'Type',
data: (row) => {
return row.type ? row.type.name : ''
}
},
{
title: 'Model',
data: (row) => {
return row.model ? row.model.name : ''
}
},
{
title: 'Datacenter',
data: (row) => {
return row.dc ? row.dc.name : ''
}
}
],
stateData: [
{
id: 1,
value: this.$t('issue.open')
}, {
id: 2,
value: this.$t('issue.hasBeenAssigned')
}, {
id: 3,
value: this.$t('issue.beingProcessed')
}, {
id: 4,
value: this.$t('issue.hangUp')
}, {
id: 5,
value: this.$t('issue.resolved')
}, {
id: 6,
value: this.$t('overall.close')
}, {
id: 7,
value: this.$t('overall.cancel')
}
]
}
},
mounted () {
this.getTypeData()
this.getUserList()
},
methods: {
getTypeData () {
this.$get('issue/type').then(response => {
if (response.code === 200) {
this.issueTypeSelect = response.data
}
})
},
getUserList () {
this.$get('sys/user', { pageNo: 1, pageSize: -1 }).then(response => {
if (response.code == 200) {
this.userData = response.data.list
}
})
},
resultFormat (resp) {
if (resp && resp.data) {
const assetData = {}
assetData.list = resp.data.list
assetData.totalRow = resp.data.total
return assetData
}
},
clickOutside () {
this.esc(false)
},
esc (refresh) {
this.prevent_opt.save = false
this.$emit('close', refresh)
},
afterInitRich () {
this.$refs.alertName.focus()
},
save () {
this.editIssue.expr = this.expressions[0]
this.$refs.issueForm.validate((valid) => {
// 处理labels数据
const obj = {}
this.editIssue.labels.forEach(item => {
obj[item.label] = item.value
})
const params = {
...this.editIssue,
state: Number(this.editIssue.state),
type: Number(this.editIssue.type),
inr: Number(this.editIssue.inr),
labels: this.editIssue.labels[0].label != '' ? JSON.stringify(obj) : {}
}
if (valid) {
this.prevent_opt.save = true
if (this.editIssue.id) {
this.$put('/record/rule', params).then(response => {
this.prevent_opt.save = false
if (response.code === 200) {
this.$message({ duration: 1000, type: 'success', message: this.$t('tip.saveSuccess') })
this.esc(true)
} else {
this.$message.error(response.msg)
}
this.prevent_opt.save = false
})
} else {
this.$post('record/rule', params).then(response => {
if (response.code === 200) {
this.$message({ duration: 1000, type: 'success', message: this.$t('tip.saveSuccess') })
this.esc(true)
} else {
this.$message.error(response.msg)
}
this.prevent_opt.save = false
})
}
} else {
this.prevent_opt.save = false
}
})
}
},
computed: {
language () { return this.$store.getters.getLanguage }
},
watch: {
// issue: {
// deep: true,
// immediate: true,
// handler (n, o) {
// this.isEdit = true
// const editObj = lodash.cloneDeep(n)
// this.editIssue = {
// ...editObj,
// type: editObj.type + '',
// inr: editObj.inr + '',
// labels: typeof editObj.labels != 'object' ? this.labelsSort(editObj.labels) : editObj.labels,
// state: editObj.state + ''
// }
// }
// }
}
}
</script>

View File

@@ -109,6 +109,26 @@
<ul v-else>
<li v-for="(item,key) in assetTypeTree" :key="key" :class="search_select_style_num==key?'search-style-ind':''" @click="selectObject(val, item, $event)">{{$t(item.name)}}</li>
</ul>
</div>
<div v-if="val.type === 'issueType'" :style="'top:' + selectDom.top +'; left:'+selectDom.left" class="select_info_list">
<el-scrollbar v-if="issueTypeSelect.length > 8" class="el-scrollbar-small" style="height: 240px;">
<ul>
<li v-for="(item,key) in issueTypeSelect" :key="key" :class="search_select_style_num==key?'search-style-ind':''" @click="selectObject(val, item, $event)">{{$t(item.name)}}</li>
</ul>
</el-scrollbar>
<ul v-else>
<li v-for="(item,key) in issueTypeSelect" :key="key" :class="search_select_style_num==key?'search-style-ind':''" @click="selectObject(val, item, $event)">{{$t(item.name)}}</li>
</ul>
</div>
<div v-if="val.type === 'issue'" :style="'top:' + selectDom.top +'; left:'+selectDom.left" class="select_info_list">
<el-scrollbar v-if="issueData.length > 8" class="el-scrollbar-small" style="height: 240px;">
<ul>
<li v-for="(item,key) in issueData" :key="key" :class="search_select_style_num==key?'search-style-ind':''" @click="selectObject(val, item, $event)">{{$t(item.username)}}</li>
</ul>
</el-scrollbar>
<ul v-else>
<li v-for="(item,key) in issueData" :key="key" :class="search_select_style_num==key?'search-style-ind':''" @click="selectObject(val, item, $event)">{{$t(item.username)}}</li>
</ul>
</div>
<div v-if="val.type === 'brand'" :style="'top:' + selectDom.top +'; left:'+selectDom.left" class="select_info_list">
<el-scrollbar v-if="brandSelect.length > 8" class="el-scrollbar-small" style="height: 240px;">
@@ -286,6 +306,8 @@ export default {
dcSelect: [], // 数据中心
assetSelect: [], // 资产
assetStateSelect: [],
issueTypeSelect: [], // issue type
issueData: [], // issue
brandSelect: [],
groupSelect: [],
projectSelect: [],
@@ -540,6 +562,14 @@ export default {
val.val = selectItem.name
val.valnum = selectItem.id
val.valString = ''
} else if (val.type === 'issue' && selectItem.searchType === 'issue') {
val.val = selectItem.name
val.valnum = selectItem.id
val.valString = ''
} else if (val.type === 'issueType') {
val.val = selectItem.name
val.valnum = selectItem.id
val.valString = ''
}
}
// this.select_list.push({type: 'dc', val: selectItem.name, valnum: selectItem.id});
@@ -638,6 +668,29 @@ export default {
}
})
},
getIssueTypeData () {
this.$get('issue/type').then(response => {
if (response.code === 200) {
this.issueTypeSelect = response.data.map((item, index) => {
return {
value: item,
name: item,
id: index
}
})
}
})
},
getUserList () {
this.$get('sys/user', { pageNo: 1, pageSize: -1 }).then(response => {
if (response.code == 200) {
this.issueData = response.data.list
this.issueData.forEach((item, index) => {
this.$set(item, 'searchType', 'issue')
})
}
})
},
getBrandData () {
this.$get('asset/brand', { pageNo: 1, pageSize: -1 }).then(response => {
if (response.code === 200) {
@@ -910,6 +963,10 @@ export default {
objectInfo.type = val.valnum
} else if (val.label === 'buildIn') {
objectInfo.buildIn = val.valnum
} else if (val.label === 'issueState') {
objectInfo.state = val.valnum
} else if (val.label === 'priority') {
objectInfo.priority = val.valnum
} else if (typeof (val.valnum) === 'undefined' || val.valnum == '') {
this.selectInfoList[val.label].forEach(item => {
if (item.label === val.val) {
@@ -947,6 +1004,18 @@ export default {
objectInfo.brandIds = val.valnum
} else if (val.type === 'group') {
objectInfo.groupIds = val.valnum
} else if (val.type === 'issueType') {
objectInfo.type = val.val
} else if (val.type === 'issue') {
if (val.label === 'cid') {
objectInfo.cid = val.valnum
} else if (val.label === 'uid') {
objectInfo.uid = val.valnum
} else if (val.label === 'rid') {
objectInfo.rid = val.valnum
} else if (val.label === 'aid') {
objectInfo.aid = val.valnum
}
} else if (val.type === 'selectString') {
if (val.label === 'dcState') {
objectInfo.state = val.val
@@ -1530,6 +1599,10 @@ export default {
if (this.$route.path === '/exprTemp') {
this.getGnameList()
}
if (this.$route.path === '/issue') {
this.getIssueTypeData()
this.getUserList()
}
this.searchLabelList = this.searchLabelList.filter(item => !this.select_list.find(select => select.label === item.label))
setTimeout(() => {
this.select_list.forEach(item => {

View File

@@ -320,7 +320,41 @@ const searchSelectInfo = { // value: 传给后台的值label显示给用
ipamType: [
{ label: 'IPV4', value: 4 },
{ label: 'IPV6', value: 6 }
]
],
issueState: [
{
value: 1,
label: i18n.t('issue.open')
}, {
value: 2,
label: i18n.t('issue.hasBeenAssigned')
}, {
value: 3,
label: i18n.t('issue.beingProcessed')
}, {
value: 4,
label: i18n.t('issue.hangUp')
}, {
value: 5,
label: i18n.t('issue.resolved')
}, {
value: 6,
label: i18n.t('overall.close')
}, {
value: 7,
label: i18n.t('overall.cancel')
}
],
priority: [{
value: 1,
label: i18n.t('dashboard.panel.chartForm.high')
}, {
value: 2,
label: i18n.t('issue.middle')
}, {
value: 3,
label: i18n.t('issue.low')
}]
}
export default searchSelectInfo
</script>

View File

@@ -0,0 +1,237 @@
<template>
<el-table
id="issueTable"
ref="dataTable"
:data="tableData"
:height="height"
border
:default-sort="orderBy"
@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 customTableTitle"
v-if="item.show"
: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 slot="header">
<span class="data-column__span">{{ item.label }}</span>
<div class="col-resize-area"></div>
</template>
<template slot-scope="scope" :column="item">
<template v-if="item.prop === 'name'">
<div class="document-copy-block">
<span class="document-copy-text">{{scope.row.name ? scope.row.name : '-'}}</span>
<i v-if="scope.row.name" class="nz-icon nz-icon-override" style="visibility: hidden" @click="onCopy(scope.row.name)" :title="$t('overall.copyText')"></i>
</div>
</template>
<template v-else-if="item.prop === 'type'">
<div class="document-copy-block">
<span class="document-copy-text">{{scope.row.type ? scope.row.type : '-'}}</span>
<i v-if="scope.row.type" class="nz-icon nz-icon-override" style="visibility: hidden" @click="onCopy(scope.row.type)" :title="$t('overall.copyText')"></i>
</div>
</template>
<template v-else-if="item.prop === 'reporter'">
<template>{{scope.row[item.prop] ? scope.row[item.prop].name : '-'}}</template>
</template>
<template v-else-if="item.prop === 'assignee'">
<template>{{scope.row[item.prop] ? scope.row[item.prop].name : '-'}}</template>
</template>
<template v-else-if="item.prop === 'priority'">
<div v-if="scope.row[item.prop] == 1">
{{ $t('dashboard.panel.chartForm.high') }}
</div>
<div v-else-if="scope.row[item.prop] == 2">
{{ $t('issue.middle') }}
</div>
<div v-else-if="scope.row[item.prop] == 3">
{{ $t('issue.low') }}
</div>
</template>
<template v-else-if="item.prop === 'state'">
<div v-for="key in stateData" :key="key.id">
<div v-if="scope.row[item.prop] === key.id">
{{ key.value }}
</div>
</div>
</template>
<template v-else-if="item.prop === 'createUser'">
<template>{{scope.row[item.prop] ? scope.row[item.prop].name : '-'}}</template>
</template>
<template v-else-if="item.prop === 'cts'">
<template>{{scope.row[item.prop] ? utcTimeToTimezoneStr(scope.row[item.prop]) : '-'}}</template>
</template>
<template v-else-if="item.prop === 'updateUser'">
<template>{{scope.row[item.prop] ? scope.row[item.prop].name : '-'}}</template>
</template>
<template v-else-if="item.prop === 'uts'">
<template>{{scope.row[item.prop] ? utcTimeToTimezoneStr(scope.row[item.prop]) : '-'}}</template>
</template>
<template v-else-if="scope.row[item.prop]">{{scope.row[item.prop]}}</template>
<template v-else>-</template>
</template>
</el-table-column>
<el-table-column :resizable="false" :width="operationWidth" fixed="right">
<div slot="header" class="table-operation-title">
{{ $t("overall.option") }}
</div>
<div slot-scope="scope" class="table-operation-items">
<button class="table-operation-item" @click="showBottomBox('recordRule', scope.row)" :title="$t('overall.view')"><i class="nz-icon nz-icon-view1"></i></button>
<el-dropdown size="medium" v-has="['record_rule_edit','record_rule_delete']" trigger="click" @command="tableOperation">
<div class="table-operation-item table-operation-item--more" :title="$t('overall.moreOperations')">
<i class="nz-icon nz-icon-more3"></i>
</div>
<el-dropdown-menu slot="dropdown" class="right-box-select-top right-public-box-dropdown-top">
<el-dropdown-item v-if="!scope.row.buildIn" v-has="'record_rule_edit'" :command="['edit', scope.row]"><i class="nz-icon nz-icon-edit"></i><span class="operation-dropdown-text">{{$t('overall.edit')}}</span></el-dropdown-item>
<el-dropdown-item v-if="!scope.row.buildIn" v-has="'record_rule_edit'" :command="['copy', scope.row]"><i class="nz-icon nz-icon-override"></i><span class="operation-dropdown-text">{{$t('overall.duplicate')}}</span></el-dropdown-item>
<el-dropdown-item v-if="!scope.row.buildIn" v-has="'record_rule_delete'" :command="['delete', scope.row]"><i class="nz-icon nz-icon-delete"></i><span class="operation-dropdown-text">{{$t('overall.delete')}}</span></el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</el-table-column>
<template slot="empty">
<div v-if="!loading" class="table-no-data">
<svg class="icon" aria-hidden="true">
<use xlink:href="#nz-icon-no-data-list"></use>
</svg>
<div class="table-no-data__title">No results found</div>
</div>
<div v-else>&nbsp;</div>
</template>
</el-table>
</template>
<script>
import table from '@/components/common/mixin/table'
export default {
name: 'issueTable',
mixins: [table],
props: {
loading: Boolean
},
data () {
return {
/* 表格相关 */
tableTitle: [
{
label: this.$t('asset.id'),
prop: 'id',
show: true,
width: 80,
sortable: 'custom'
},
{
label: this.$t('project.topology.title'),
prop: 'name',
show: true,
minWidth: 150,
sortable: 'custom'
},
{
label: this.$t('overall.type'),
prop: 'type',
show: true,
minWidth: 150
},
{
label: this.$t('issue.reporter'),
prop: 'reporter',
show: true,
width: 300
},
{
label: this.$t('issue.assignee'),
prop: 'assignee',
show: true,
width: 300
},
{
label: this.$t('alert.severity'),
prop: 'priority',
show: true,
width: 300,
sortable: 'custom'
},
{
label: this.$t('overall.state'),
prop: 'state',
show: true,
minWidth: 150,
sortable: 'custom'
},
{
label: this.$t('issue.createUser'),
prop: 'createUser',
show: false,
width: 150
},
{
label: this.$t('issue.createTime'),
prop: 'cts',
show: false,
width: 300,
sortable: 'custom'
},
{
label: this.$t('config.mib.updateUser'),
prop: 'updateUser',
show: false,
width: 150
},
{
label: this.$t('alert.silence.upTime'),
prop: 'uts',
show: false,
width: 300,
sortable: 'custom'
}
],
stateData: [
{
id: 1,
value: this.$t('issue.open')
}, {
id: 2,
value: this.$t('issue.hasBeenAssigned')
}, {
id: 3,
value: this.$t('issue.beingProcessed')
}, {
id: 4,
value: this.$t('issue.hangUp')
}, {
id: 5,
value: this.$t('issue.resolved')
}, {
id: 6,
value: this.$t('overall.close')
}, {
id: 7,
value: this.$t('overall.cancel')
}
]
}
},
computed: {
},
methods: {
}
}
</script>

View File

@@ -0,0 +1,179 @@
<template>
<div>
<nz-data-list
ref="dataList"
:api="url"
:custom-table-title.sync="tools.customTableTitle"
:from="fromRoute.issue"
:layout="['searchInput', 'elementSet', 'pagination']"
:search-msg="searchMsg"
@search="search"
@getTableData="getTableData"
>
<template v-slot:top-tool-right>
<button id="record-add" v-has="'issue_record_add'" :title="$t('overall.createIssue')" class="top-tool-btn margin-r-10" @click.stop="add">
<i class="nz-icon nz-icon-create-square"></i>
</button>
</template>
<template v-slot:default="slotProps">
<issue-table
ref="dataTable"
:orderByFa="orderBy"
v-my-loading="tools.loading"
:loading="tools.loading"
:api="url"
:custom-table-title="tools.customTableTitle"
:height="mainTableHeight"
:table-data="tableData"
@del="del"
@edit="edit"
@copy="copy"
@orderBy="tableDataSort"
@reload="getTableData"
@selectionChange="selectionChange"
@showBottomBox="
(targetTab, object) => {
$refs.dataList.showBottomBox(targetTab, object);
}
"
></issue-table>
</template>
<!-- 分页组件 -->
<template v-slot:pagination>
<Pagination
ref="Pagination"
:pageObj="pageObj"
:tableId="tableId"
@pageNo="pageNo"
@pageSize="pageSize"
></Pagination>
</template>
</nz-data-list>
<!-- <transition name="right-box">
<issue-box
v-if="rightBox.show"
:record-rule="object"
@close="closeRightBox"
></issue-box>
</transition> -->
</div>
</template>
<script>
import nzDataList from '@/components/common/table/nzDataList'
import dataListMixin from '@/components/common/mixin/dataList'
import routerPathParams from '@/components/common/mixin/routerPathParams'
import issueTable from '@/components/common/table/settings/issueTable'
// import issueBox from '@/components/common/rightBox/issueBox'
export default {
name: 'issue',
components: {
issueTable,
nzDataList,
// issueBox
},
mixins: [dataListMixin, routerPathParams],
data () {
return {
url: 'issue',
tableId: 'issueTable',
orderBy: '-id',
searchMsg: { // 给搜索框子组件传递的信息
searchLabelList: [
{
name: 'ID',
type: 'input',
label: 'ids',
disabled: false
},
{
name: this.$t('overall.name'),
type: 'input',
label: 'name',
disabled: false
},
{
name: this.$t('overall.type'),
type: 'issueType',
label: 'issueType',
disabled: false
},
{
name: this.$t('overall.state'),
type: 'select',
label: 'issueState',
disabled: false
},
{
name: this.$t('alert.severity'),
type: 'select',
label: 'priority',
disabled: false
},
{
name: this.$t('issue.assetId'),
type: 'input',
label: 'assetId',
disabled: false
},
{
name: this.$t('issue.assetName'),
type: 'input',
label: 'assetName',
disabled: false
},
{
name: this.$t('issue.createUser'),
type: 'issue',
label: 'cid',
disabled: false
},
{
name: this.$t('config.mib.updateUser'),
type: 'issue',
label: 'uid',
disabled: false
},
{
name: this.$t('issue.reporter'),
type: 'issue',
label: 'rid',
disabled: false
},
{
name: this.$t('issue.assignee'),
type: 'issue',
label: 'aid',
disabled: false
},
{
name: this.$t('overall.starred'),
type: 'select',
label: 'starrd',
disabled: false
}
]
},
// 创建修改相关
blankObject: {
id: '',
name: '',
type: '',
content: '',
state: '',
priority: '',
rid: '',
aid: -1,
assetIds: ''
}
}
},
mounted () {
},
methods: {
},
created () {
}
}
</script>

View File

@@ -68,6 +68,10 @@ export default new Router({
path: '/recordRule',
component: resolve => require(['@/components/page/config/recordRule'], resolve)
},
{
path: '/issue',
component: resolve => require(['@/components/page/config/issue'], resolve)
},
{
path: '/assetType',
component: resolve => require(['@/components/page/config/assetType'], resolve)