Authored by 鲁尚清

【#1162】 变更相关业务选项卡配置为字典,建立选项卡组件 #2

Showing 20 changed files with 726 additions and 483 deletions
  1 +export default {
  2 + name: 'resourceTypePer',
  3 + template: '',
  4 + components: {
  5 +
  6 + },
  7 + data() {
  8 + },
  9 + props: {
  10 + },
  11 + setup: function (props, {attrs, slots, emit}) {
  12 + const {proxy} = Vue.getCurrentInstance();
  13 +
  14 + // 挂载完
  15 + Vue.onMounted(() => {
  16 + })
  17 + return {
  18 +
  19 + }
  20 + }
  21 +}
  1 +export default {
  2 + name: 'resourceTypePer',
  3 + template: '',
  4 + components: {
  5 +
  6 + },
  7 + data() {
  8 + },
  9 + props: {
  10 + },
  11 + setup: function (props, {attrs, slots, emit}) {
  12 + const {proxy} = Vue.getCurrentInstance();
  13 +
  14 + // 挂载完
  15 + Vue.onMounted(() => {
  16 + })
  17 + return {
  18 +
  19 + }
  20 + }
  21 +}
  1 +export default {
  2 + name: 'resourceTypePer',
  3 + template: '',
  4 + components: {
  5 +
  6 + },
  7 + data() {
  8 + },
  9 + props: {
  10 + },
  11 + setup: function (props, {attrs, slots, emit}) {
  12 + const {proxy} = Vue.getCurrentInstance();
  13 +
  14 + // 挂载完
  15 + Vue.onMounted(() => {
  16 + })
  17 + return {
  18 +
  19 + }
  20 + }
  21 +}
  1 +export default {
  2 + name: 'resourceTypePer',
  3 + template: '',
  4 + components: {
  5 +
  6 + },
  7 + data() {
  8 + },
  9 + props: {
  10 + },
  11 + setup: function (props, {attrs, slots, emit}) {
  12 + const {proxy} = Vue.getCurrentInstance();
  13 +
  14 + // 挂载完
  15 + Vue.onMounted(() => {
  16 + })
  17 + return {
  18 +
  19 + }
  20 + }
  21 +}
@@ -2,86 +2,39 @@ @@ -2,86 +2,39 @@
2 <el-row > 2 <el-row >
3 <el-col :span="24"> 3 <el-col :span="24">
4 <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick"> 4 <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
5 - <el-tab-pane v-for="(item,index) in tabData" :key="index" :label="item.name" :name="item.code"> 5 + <el-tab-pane v-for="(item,index) in tabData" :key="index" :label="item.ddicName" :name="item.ddicCode">
6 6
7 - <div class="table-container" v-if="item.code=='resourcePer'">  
8 -  
9 - <el-row>  
10 - <el-col :span="24" class="search">  
11 - <div class="condition" style="display: flex;">  
12 - <el-form-item style="margin-right: 6px;margin-bottom: 10px;">  
13 - <el-input v-model="search.keyword" placeholder="请输入关键字"></el-input>  
14 - </el-form-item>  
15 - <el-form-item style="margin-right: 6px;margin-bottom: 10px;">  
16 - <el-select clearable multiple v-model="search.resType" placeholder="请选择资源类型">  
17 - <el-option  
18 - v-for="item in resTypeOptions"  
19 - :key="item.kpiId"  
20 - :label="item.kpiName"  
21 - :value="item.kpiId">  
22 - <span style="float: left">{{ item.kpiId }}</span>  
23 - <span style="float: right;color: var(--el-text-color-secondary);font-size: 13px;">{{ item.kpiName }}</span>  
24 - </el-option>  
25 - </el-select>  
26 - </el-form-item>  
27 - <el-form-item style="margin-right: 6px;margin-bottom: 10px;">  
28 - <el-button @click="getListData">查询</el-button>  
29 - </el-form-item>  
30 - </div>  
31 - </el-col>  
32 - </el-row>  
33 - <el-row style="margin-bottom: 10px;">  
34 - <div class="flex-div-start">  
35 - <el-button type="primary" @click="save()" size="small">取消</el-button>  
36 - <el-button type="primary" @click="conserve()" size="small" style="margin-left: 6px">变更</el-button>  
37 - <el-button type="primary" @click="conserve()" size="small" style="margin-left: 6px">导出</el-button>  
38 - </div>  
39 - </el-row>  
40 - <el-row class="margin-bottom-50" style="margin-top: 3px">  
41 - <el-col :span="24" class="table-height">  
42 - <cm-table-page :columns="columns"  
43 - :dataList="portSenseConfigData"  
44 - :total="count"  
45 - :pageSize="pageSize"  
46 - @loaddata="loadTableDataList"  
47 - @selectionChange="selectionChange"  
48 - :showIndex="true"  
49 - :showSelection="true"  
50 - :showBorder="true"  
51 - :loading="loading"  
52 - :showPage="true"  
53 - :showTools="false"  
54 - :height="(height - 200)">  
55 - <template #default="{row,prop,column}">  
56 - <!-- <div v-if="prop == 'protocolType'">  
57 - <el-select placeholder="请选择" size="small" style="width: 100%"  
58 - @change="changePortSense(row,prop,column)" v-model="row.protocolType"  
59 - :multiple="false"  
60 - collapse-tags clearable filterable placeholder="请选择">  
61 - <el-option label="TCP协议" :value="'tcp-port'"></el-option>  
62 - <el-option label="UDP协议" :value="'udp-port'"></el-option>  
63 - </el-select>  
64 - </div>  
65 - <div v-else>  
66 - <el-input @blur="changePortSense(row,prop,column)"  
67 - :type="prop == intervalTime ? 'number' : 'text'"  
68 - size="small" placeholder="请填写"v-model="row[prop]">  
69 - <template #suffix>  
70 - <i class="el-icon-edit-outline"/>  
71 - </template>  
72 - </el-input>  
73 - </div>-->  
74 - </template>  
75 - <!-- <template #tools="{scope}">  
76 - <el-button type="text" size="small" @click.prevent="deleteItem(scope.row,scope.$index)">  
77 - <i class="el-icon-delete"/>  
78 - </el-button>  
79 - </template>-->  
80 - </cm-table-page>  
81 - </el-col>  
82 - </el-row> 7 + <div class="table-container" v-if="item.ddicCode=='resourcePer'">
  8 + <ResourcePer></ResourcePer>
  9 + </div>
  10 + <div class="table-container" v-else-if="item.ddicCode=='resourceLeader'">
  11 + <ResourceLeader></ResourceLeader>
  12 + </div>
  13 + <div class="table-container" v-else-if="item.ddicCode=='resourceTypePer'">
  14 + <ResourceTypePer></ResourceTypePer>
  15 + </div>
  16 + <div class="table-container" v-else-if="item.ddicCode=='bizPer'">
  17 + <BizPer></BizPer>
  18 + </div>
  19 + <div class="table-container" v-else-if="item.ddicCode=='bizLeader'">
  20 + <BizLeader></BizLeader>
  21 + </div>
  22 + <div class="table-container" v-else-if="item.ddicCode=='alarmSubPer'">
  23 + <AlarmSubPer></AlarmSubPer>
  24 + </div>
  25 + <div class="table-container" v-else-if="item.ddicCode=='rolePer'">
  26 + <RolePer></RolePer>
  27 + </div>
  28 + <div class="table-container" v-else-if="item.ddicCode=='topoPer'">
  29 + <TopoPer></TopoPer>
  30 + </div>
  31 + <div class="table-container" v-else-if="item.ddicCode=='autoPatrolPortPer'">
  32 + <AutoPatrolPortPer></AutoPatrolPortPer>
  33 + </div>
  34 + <div class="table-container" v-else-if="item.ddicCode=='fileManagePer'">
  35 + <FileManagePer></FileManagePer>
83 </div> 36 </div>
84 - <div class="table-container" v-else>{{item.name}}</div> 37 + <div class="table-container" v-else>暂无数据</div>
85 </el-tab-pane> 38 </el-tab-pane>
86 </el-tabs> 39 </el-tabs>
87 40
1 export default { 1 export default {
2 - name: 'portSense', 2 + name: 'batchChangeLeaders',
3 template: '', 3 template: '',
4 components: { 4 components: {
5 - //资源下拉框  
6 - 'port-sense-select': Vue.defineAsyncComponent(  
7 - () => myImport('views/portSenseSelect/index') 5 + //选项卡组件
  6 + 'ResourcePer': Vue.defineAsyncComponent(
  7 + () => myImport('views/batchChangeLeaders/resourcePer/index')
  8 + ),
  9 + 'ResourceLeader': Vue.defineAsyncComponent(
  10 + () => myImport('views/batchChangeLeaders/resourceLeader/index')
  11 + ),
  12 + 'ResourceTypePer': Vue.defineAsyncComponent(
  13 + () => myImport('views/batchChangeLeaders/resourceTypePer/index')
  14 + ),
  15 + 'BizPer': Vue.defineAsyncComponent(
  16 + () => myImport('views/batchChangeLeaders/bizPer/index')
  17 + ),
  18 + 'BizLeader': Vue.defineAsyncComponent(
  19 + () => myImport('views/batchChangeLeaders/bizLeader/index')
  20 + ),
  21 + 'BlarmSubPer': Vue.defineAsyncComponent(
  22 + () => myImport('views/batchChangeLeaders/alarmSubPer/index')
  23 + ),
  24 + 'BolePer': Vue.defineAsyncComponent(
  25 + () => myImport('views/batchChangeLeaders/rolePer/index')
  26 + ),
  27 + 'TopoPer': Vue.defineAsyncComponent(
  28 + () => myImport('views/batchChangeLeaders/topoPer/index')
  29 + ),
  30 + 'AutoPatrolPortPer': Vue.defineAsyncComponent(
  31 + () => myImport('views/batchChangeLeaders/autoPatrolPortPer/index')
  32 + ),
  33 + 'FileManagePer': Vue.defineAsyncComponent(
  34 + () => myImport('views/batchChangeLeaders/fileManagePer/index')
8 ), 35 ),
9 }, 36 },
10 data() { 37 data() {
11 }, 38 },
12 props: { 39 props: {
13 - parameter: {  
14 - type: Array,  
15 - default: []  
16 - }  
17 }, 40 },
18 setup: function (props, {attrs, slots, emit}) { 41 setup: function (props, {attrs, slots, emit}) {
19 const {proxy} = Vue.getCurrentInstance(); 42 const {proxy} = Vue.getCurrentInstance();
20 - const tabData=Vue.ref([  
21 - {name:'资源权限',code:'resourcePer'},  
22 - {name:'资源负责人',code:'resourceLeader'},  
23 - {name:'资源类型权限',code:'resourceTypePer'},  
24 - {name:'业务(乙方运维)权限',code:'bizPer'},  
25 - {name:'业务负责人',code:'bizLeader'},  
26 - {name:'告警订阅权限',code:'alarmSubPer'},  
27 - {name:'角色权限',code:'rolePer'},  
28 - {name:'拓扑负责人',code:'topoPer'},  
29 - {name:'自动化巡检报表权限',code:'autoPatrolPortPer'},  
30 - {name:'文档管理权限',code:'fileManagePer'}  
31 - ])  
32 - const activeName = Vue.ref(tabData.value[0].code) 43 + const tabData=Vue.ref()
  44 + const activeName = Vue.ref('')
33 const handleClick = (tab, event) => { 45 const handleClick = (tab, event) => {
34 console.log(tab, event) 46 console.log(tab, event)
35 } 47 }
36 - let showTypeList=Vue.ref([]);  
37 - let search = Vue.ref({  
38 - resType: '',  
39 - keyword: '',  
40 - page: 1,  
41 - limit: 20,  
42 - });  
43 - let resTypeOptions=Vue.ref([])  
44 -  
45 -  
46 - const columns = [  
47 - {  
48 - prop: 'resName',  
49 - label: '资源名称',  
50 - sortable: true,  
51 - align: 'center',  
52 - },  
53 - {  
54 - prop: 'ip',  
55 - label: 'IP地址',  
56 - sortable: true,  
57 - align: 'center',  
58 - },  
59 - {  
60 - prop: 'port',  
61 - label: '端口号',  
62 - sortable: true,  
63 - align: 'center',  
64 - },  
65 - {  
66 - prop: 'admin',  
67 - label: '负责人',  
68 - sortable: true,  
69 - align: 'center',  
70 - },  
71 - {  
72 - prop: 'resTypeName',  
73 - label: '资源类型',  
74 - sortable: true,  
75 - align: 'center',  
76 - },  
77 - {  
78 - prop: 'state',  
79 - label: '资源状态',  
80 - sortable: true,  
81 - align: 'center',  
82 - render: function (row) {  
83 - switch (row.state) {  
84 - case "new" :  
85 - return '<button type="button" class="layui-btn layui-btn-warm layui-bg-gray layui-btn-radius layui-btn-xs p-0-15">未监控</button>'  
86 - case "monitor" :  
87 - return '<button type="button" class="layui-btn layui-btn-radius layui-bg-green layui-btn-xs p-0-15" style="background-color: #0BAC33 !important;">监控中</button>'  
88 - case "stop" :  
89 - return '<button type="button" class="layui-btn layui-btn-warm layui-bg-red layui-btn-radius layui-btn-xs p-0-15">暂停</button>'  
90 - default :  
91 - return '<button type="button" class="layui-btn layui-btn-warm layui-bg-gray layui-btn-radius layui-btn-xs p-0-15">未监控</button>'  
92 - }  
93 - }  
94 - },  
95 - {  
96 - prop: 'paramDesc',  
97 - label: '展示类型',  
98 - sortable: true,  
99 - align: 'center',  
100 - render: function (row) {  
101 - if(row.resType == 'HOST_X86SERVER'){  
102 - //初始化select内容  
103 - /* var html='<div><select data-resId="'+d.resId+'" data-username="'+username+'" data-index="99" name="showType" class="layui-input user_showType" style="min-width: 150px;display: inline">';  
104 - showTypeList.value.map((v,i)=>{  
105 - if(d.showType == v.value){  
106 - html += '<option value="' + v.value + '" selected>' + v.name + '</option> '  
107 - }else{  
108 - html += '<option value="' + v.value + '">' + v.name + '</option> '  
109 - }  
110 - })  
111 - html+='</select></div>';  
112 - return html;*/  
113 - }else{  
114 - return '';  
115 - }  
116 - }  
117 - }  
118 - ];  
119 - //配置列表总数  
120 - let count = Vue.ref(0);  
121 - //列表数据  
122 - let portSenseConfigData = Vue.ref([]);  
123 - //数据库的数据  
124 - let portSenseConfigList = Vue.ref([]);  
125 - //资源数据  
126 - let resIdArr = Vue.ref([]);  
127 - //列表高度  
128 - let height = Vue.ref(window.innerHeight);  
129 - //列表分页  
130 - let pageSize = Vue.ref(400);  
131 - //加载  
132 - let loading = Vue.ref(true);  
133 - //选中数据  
134 - let pitch = Vue.ref([]);  
135 - //下拉框数据  
136 - let portSenseSelectData = Vue.ref([]);  
137 -  
138 - //获取列表数据  
139 - const getListData = ({page, limit}) => {  
140 - //获取传递过来的参数  
141 - resIdArr.value = JSON.parse(JSON.stringify(props.parameter));  
142 - //传递参数赋值给下拉框  
143 - portSenseSelectData.value = resIdArr.value;  
144 -  
145 - let username=proxy.$route.query.username;  
146 - let resName=proxy.$route.query.resName;  
147 - //定义列表参数  
148 - let getParams = {  
149 - resIds: resIdArr.value.join(','),  
150 - resName: resName,  
151 - userId: username,  
152 - page: page,  
153 - limit: limit  
154 - };  
155 - proxy.$http.get("/api-web/manage/resource/getAllResByUser", getParams, function (res) {  
156 - if (res && res.success) {  
157 - portSenseConfigData.value = res.data ? res.data : [];  
158 - count.value = res.count;  
159 - loading.value = false;  
160 - portSenseConfigList.value = res.data ? JSON.parse(JSON.stringify(res.data)) : [];  
161 - }  
162 - })  
163 - }  
164 -  
165 - //表格全选事件  
166 - let selectionChange = (val) => {  
167 - pitch.value = val;  
168 - proxy.portSenseConfigData.map((v, i) => {  
169 - v.checked = false;  
170 - });  
171 - let selectData = val;  
172 - if (selectData.length > 0) {  
173 - selectData.map((item, index) => {  
174 - proxy.portSenseConfigData.map((v, i) => {  
175 - if (item.id == v.id) {  
176 - v.checked = true;  
177 - }  
178 - })  
179 - })  
180 - } else {  
181 - proxy.portSenseConfigData.map((v, i) => {  
182 - v.checked = false;  
183 - })  
184 - }  
185 - }  
186 - //删除单个数据  
187 - let deleteItem = (row, index) => {  
188 - proxy.$global.confirm("确认删除吗?", function () {  
189 - deleteItems(row, index);  
190 - })  
191 - }  
192 - //删除多个或单个  
193 - let deleteItems = (row, index) => {  
194 - //新添加未保存的  
195 - let sign = deleteNotSave(row, index);  
196 - if (sign) {  
197 - return false;  
198 - }  
199 - proxy.$http.post('/api-web/bResourceExtendParam/deleteConfig', row, function (res) {  
200 - if (res && res.success) {  
201 - proxy.$global.showMsg('删除成功');  
202 - loadTableDataList({page: 1, limit: pageSize.value});  
203 - }  
204 - })  
205 - }  
206 - //删除新添加但未保存的  
207 - let deleteNotSave = (row, index) => {  
208 - let sign = false;  
209 - let list = portSenseConfigData.value;  
210 - if(row.id === ""){  
211 - portSenseConfigData.value = list.filter((item, i, array) => index !== i);  
212 - }  
213 - if (list.length > portSenseConfigData.value.length) {  
214 - proxy.$global.showMsg('删除成功');  
215 - sign = true;  
216 - }  
217 - return sign;  
218 - }  
219 - //新增 添加一行数据  
220 - let save = () => {  
221 - let data = {  
222 - id: "",  
223 - intervalTime: null,  
224 - paramCode: "",  
225 - paramDesc: "",  
226 - paramValue: "",  
227 - port: "",  
228 - portDesc: "",  
229 - protocolType: "",  
230 - resId: "",  
231 - resIdList: resIdArr.value,  
232 - }  
233 - portSenseConfigData.value.push(data);  
234 - }  
235 - //下拉框值改变事件  
236 - let changePortSense = () => {  
237 -  
238 - }  
239 - //保存  
240 - let conserve = () => {  
241 - //数据验证  
242 - let msg = verifyData();  
243 - if (msg !== "") {  
244 - proxy.$global.showMsg(msg, "warning");  
245 - return false;  
246 - }  
247 - //逻辑验证  
248 - let identifying = isSave();  
249 - if (identifying !== "") {  
250 - proxy.$global.showMsg(identifying, "warning");  
251 - return false;  
252 - }  
253 - proxy.$http.post("/api-web/bResourceExtendParam/conserve", portSenseConfigData.value, function (res) {  
254 - if (res && res.success) {  
255 - proxy.$global.showMsg("保存成功!");  
256 - loadTableDataList({page: 1, limit: pageSize.value});  
257 - }  
258 - })  
259 - }  
260 - //保存表单验证  
261 - let verifyData = () => {  
262 - let msg = "";  
263 - //协议类型不能为空,端口备注不能为空,端口号请输入数字,间隔时长请输入数字,  
264 - let list = portSenseConfigData.value;  
265 - let li = columns.filter(item => "paramDesc" !== item.prop);  
266 - list.forEach(function (item, index, arr) {  
267 - li.forEach(function (e, i, array) {  
268 - if (item[e.prop] == null || item[e.prop] === '') {  
269 - msg = e.label + '不能为空';  
270 - } else {  
271 - if (['protocolType', 'portDesc'].indexOf(e.prop) === -1 && !/^\d+$/.test(item[e.prop])) {  
272 - msg = e.label + '请输入数字';  
273 - }else{  
274 - if(['protocolType', 'portDesc'].indexOf(e.prop) === -1 && item[e.prop].length>=8){  
275 - msg = e.label + '不能超过8位';  
276 - }else{  
277 - if(['protocolType', 'portDesc'].indexOf(e.prop) === -1 && item[e.prop]<=0){  
278 - msg = e.label + '只能大于零';  
279 - }  
280 - }  
281 - }  
282 - }  
283 - })  
284 - })  
285 - return msg  
286 - }  
287 - //是否可以保存  
288 - let isSave = () => {  
289 - let msg = "";  
290 - //零个资源不用判断  
291 - if (resIdArr.value.length === 0) {  
292 - return "必须选中资源";  
293 - }  
294 - //单个资源不用判断  
295 - if (resIdArr.value.length === 1) {  
296 - return msg;  
297 - }  
298 - //多个资源时,如果当前已选资源中存在列表新增加的协议类型和端口号对应的数据时,提示不允许进行保存,提示信息中必须包含资源名称+端口类型、端口号,  
299 - let list = [];  
300 - let arr = [];  
301 - portSenseConfigData.value.forEach(item => {  
302 - item.resIdList.forEach(map => {  
303 - let obj = Object.assign({}, item);  
304 - obj["resId"] = map;  
305 - obj["resIdList"] = [map];  
306 - list.push(obj);  
307 - })  
308 - });  
309 - //查看当前页面数据是否重复  
310 - groupByCount(list, arr);  
311 - if (arr.length > 0) {  
312 - return arr.join(',');  
313 - }  
314 - //查看当前页面数据跟数据库是否重复  
315 - let presentArray = [];  
316 - //过滤不是新增的数据  
317 - list = list.filter(item => item.id === "");  
318 - resIdArr.value.forEach(item => {  
319 - let li = [];  
320 - let getParams = {  
321 - resIds: item,  
322 - page: 1,  
323 - limit: 9999  
324 - };  
325 - proxy.$http.get("/api-web/bResourceExtendParam/portSensePage", getParams, function (res) {  
326 - if (res && res.success) {  
327 - li = res.data ? res.data : [];  
328 - list.forEach(e => {  
329 - li.forEach(map => {  
330 - if (map.resId === e.resId && map.paramCode === e.protocolType && map.port === e.port) {  
331 - let obj = Object.assign({}, e);  
332 - obj["resName"] = map.resName;  
333 - presentArray.push(obj);  
334 - }  
335 - });  
336 - });  
337 - }  
338 - }, null, null, null, false);  
339 - });  
340 - presentArray.forEach(item => {  
341 - let str = item.resName + "的" + item.paramCode.split("-")[0] + "协议" + "侦测的" + item.port + "端口号已侦测";  
342 - arr.push(str);  
343 - })  
344 - msg = arr.join(',');  
345 - return msg;  
346 - }  
347 - //重新加载表格数据  
348 - let loadTableDataList = ({page, limit}) => {  
349 - getListData({page, limit});  
350 - }  
351 - //修改父组件的值  
352 - let selectRes = (item) => {  
353 - portSenseConfigData.value = item;  
354 - }  
355 - //数组查找重复数据并统计行数  
356 - let groupByCount = (arr, array) => {  
357 - let list = [];  
358 - arr.sort((a, b) => {  
359 - if (a.resId !== b.resId) {  
360 - return a.resId < b.resId ? -1 : 1;  
361 - } else {  
362 - return a.name < b.name ? -1 : 1;  
363 - }  
364 - });  
365 - for (let i = 0; i < arr.length;) {  
366 - let count = 0;  
367 - for (let j = i; j < arr.length; j++) {  
368 - if (arr[i].resId === arr[j].resId && arr[i].protocolType === arr[j].protocolType && arr[i].port === arr[j].port) {  
369 - count++;  
370 - }  
371 - }  
372 - list.push({array: arr[i], count: count});  
373 - i += count;  
374 - }  
375 - list.forEach(item => {  
376 - if (item.count > 1) {  
377 - let str = item.array.resName + "的" + item.array.paramCode.split("-")[0] + "协议" + "侦测的" + item.array.port + "端口号已侦测";  
378 - array.push(str);  
379 - }  
380 - })  
381 - }  
382 -  
383 -  
384 - //获取展示类型的字典数据  
385 - let initShowType=()=>{  
386 - proxy.$http.get("/api-web/manage/resource/getAllResByUser", getParams, function (res) {  
387 - if (res && res.success) {  
388 - let arr=res.data;  
389 - if(arr && arr.length>0){  
390 - arr.map(v=>{  
391 - showTypeList.value.push({  
392 - name: v.ddicName  
393 - ,value: v.ddicCode.substring(v.ddicCode.lastIndexOf("_")+1,v.ddicCode.length)  
394 - });  
395 - })  
396 - }  
397 48
  49 + //获取需变更的选项卡数据
  50 + let getBatchChangeData=()=>{
  51 + proxy.$http.post("/api-web/manage/ddic/findSucDdics/batch_change_leaders", {}, function (res) {
  52 + if (res && res.data) {
  53 + tabData.value = res.data;
  54 + activeName.value=tabData.value[0].ddicCode;
398 } 55 }
399 }) 56 })
400 } 57 }
401 // 挂载完 58 // 挂载完
402 Vue.onMounted(() => { 59 Vue.onMounted(() => {
403 - getListData({page: 1, limit: pageSize.value}); 60 + getBatchChangeData();
404 }) 61 })
405 return { 62 return {
  63 + getBatchChangeData,
406 activeName, 64 activeName,
407 handleClick, 65 handleClick,
408 tabData, 66 tabData,
409 - initShowType,  
410 - showTypeList,  
411 - search,  
412 - resTypeOptions,  
413 -  
414 - count,  
415 - portSenseConfigData,  
416 - columns,  
417 - height,  
418 - pageSize,  
419 - loading,  
420 -  
421 - selectionChange,  
422 - deleteItem,  
423 - save,  
424 - getListData,  
425 - loadTableDataList,  
426 - changePortSense,  
427 - conserve,  
428 - selectRes,  
429 -  
430 - portSenseSelectData  
431 } 67 }
432 } 68 }
433 } 69 }
  1 +export default {
  2 + name: 'resourceTypePer',
  3 + template: '',
  4 + components: {
  5 +
  6 + },
  7 + data() {
  8 + },
  9 + props: {
  10 + },
  11 + setup: function (props, {attrs, slots, emit}) {
  12 + const {proxy} = Vue.getCurrentInstance();
  13 +
  14 + // 挂载完
  15 + Vue.onMounted(() => {
  16 + })
  17 + return {
  18 +
  19 + }
  20 + }
  21 +}
  1 +<el-row>
  2 + <el-col :span="24" class="search">
  3 + <div class="condition" style="display: flex;">
  4 + <el-form-item style="margin-right: 6px;margin-bottom: 10px;">
  5 + <el-input v-model="search.keyword" placeholder="请输入关键字"></el-input>
  6 + </el-form-item>
  7 + <el-form-item style="margin-right: 6px;margin-bottom: 10px;">
  8 + <el-select clearable multiple v-model="search.resType" placeholder="请选择资源类型">
  9 + <el-option
  10 + v-for="item in resTypeOptions"
  11 + :key="item.kpiId"
  12 + :label="item.kpiName"
  13 + :value="item.kpiId">
  14 + <span style="float: left">{{ item.kpiId }}</span>
  15 + <span style="float: right;color: var(--el-text-color-secondary);font-size: 13px;">{{ item.kpiName }}</span>
  16 + </el-option>
  17 + </el-select>
  18 + </el-form-item>
  19 + <el-form-item style="margin-right: 6px;margin-bottom: 10px;">
  20 + <el-button @click="getListData">查询</el-button>
  21 + </el-form-item>
  22 + </div>
  23 + </el-col>
  24 +</el-row>
  25 +<el-row style="margin-bottom: 10px;">
  26 + <div class="flex-div-start">
  27 + <el-button type="primary" @click="save()" size="small">取消</el-button>
  28 + <el-button type="primary" @click="conserve()" size="small" style="margin-left: 6px">变更</el-button>
  29 + <el-button type="primary" @click="conserve()" size="small" style="margin-left: 6px">导出</el-button>
  30 + </div>
  31 +</el-row>
  32 +<el-row class="margin-bottom-50" style="margin-top: 3px">
  33 + <el-col :span="24" class="table-height">
  34 + <cm-table-page :columns="columns"
  35 + :dataList="portSenseConfigData"
  36 + :total="count"
  37 + :pageSize="pageSize"
  38 + @loaddata="loadTableDataList"
  39 + @selectionChange="selectionChange"
  40 + :showIndex="true"
  41 + :showSelection="true"
  42 + :showBorder="true"
  43 + :loading="loading"
  44 + :showPage="true"
  45 + :showTools="false"
  46 + :height="(height - 200)">
  47 + <template #default="{row,prop,column}">
  48 + <!-- <div v-if="prop == 'protocolType'">
  49 + <el-select placeholder="请选择" size="small" style="width: 100%"
  50 + @change="changePortSense(row,prop,column)" v-model="row.protocolType"
  51 + :multiple="false"
  52 + collapse-tags clearable filterable placeholder="请选择">
  53 + <el-option label="TCP协议" :value="'tcp-port'"></el-option>
  54 + <el-option label="UDP协议" :value="'udp-port'"></el-option>
  55 + </el-select>
  56 + </div>
  57 + <div v-else>
  58 + <el-input @blur="changePortSense(row,prop,column)"
  59 + :type="prop == intervalTime ? 'number' : 'text'"
  60 + size="small" placeholder="请填写"v-model="row[prop]">
  61 + <template #suffix>
  62 + <i class="el-icon-edit-outline"/>
  63 + </template>
  64 + </el-input>
  65 + </div>-->
  66 + </template>
  67 + <!-- <template #tools="{scope}">
  68 + <el-button type="text" size="small" @click.prevent="deleteItem(scope.row,scope.$index)">
  69 + <i class="el-icon-delete"/>
  70 + </el-button>
  71 + </template>-->
  72 + </cm-table-page>
  73 + </el-col>
  74 +</el-row>
  1 +export default {
  2 + name: 'resourcePer',
  3 + template: '',
  4 + components: {
  5 + },
  6 + data() {
  7 + },
  8 + props: {
  9 + parameter: {
  10 + type: Array,
  11 + default: []
  12 + }
  13 + },
  14 + setup: function (props, {attrs, slots, emit}) {
  15 + const {proxy} = Vue.getCurrentInstance();
  16 +
  17 + let showTypeList=Vue.ref([]);
  18 + let search = Vue.ref({
  19 + resType: '',
  20 + keyword: '',
  21 + page: 1,
  22 + limit: 20,
  23 + });
  24 + let resTypeOptions=Vue.ref([])
  25 +
  26 +
  27 + const columns = [
  28 + {
  29 + prop: 'resName',
  30 + label: '资源名称',
  31 + sortable: true,
  32 + align: 'center',
  33 + },
  34 + {
  35 + prop: 'ip',
  36 + label: 'IP地址',
  37 + sortable: true,
  38 + align: 'center',
  39 + },
  40 + {
  41 + prop: 'port',
  42 + label: '端口号',
  43 + sortable: true,
  44 + align: 'center',
  45 + },
  46 + {
  47 + prop: 'admin',
  48 + label: '负责人',
  49 + sortable: true,
  50 + align: 'center',
  51 + },
  52 + {
  53 + prop: 'resTypeName',
  54 + label: '资源类型',
  55 + sortable: true,
  56 + align: 'center',
  57 + },
  58 + {
  59 + prop: 'state',
  60 + label: '资源状态',
  61 + sortable: true,
  62 + align: 'center',
  63 + render: function (row) {
  64 + switch (row.state) {
  65 + case "new" :
  66 + return '<button type="button" class="layui-btn layui-btn-warm layui-bg-gray layui-btn-radius layui-btn-xs p-0-15">未监控</button>'
  67 + case "monitor" :
  68 + return '<button type="button" class="layui-btn layui-btn-radius layui-bg-green layui-btn-xs p-0-15" style="background-color: #0BAC33 !important;">监控中</button>'
  69 + case "stop" :
  70 + return '<button type="button" class="layui-btn layui-btn-warm layui-bg-red layui-btn-radius layui-btn-xs p-0-15">暂停</button>'
  71 + default :
  72 + return '<button type="button" class="layui-btn layui-btn-warm layui-bg-gray layui-btn-radius layui-btn-xs p-0-15">未监控</button>'
  73 + }
  74 + }
  75 + },
  76 + {
  77 + prop: 'paramDesc',
  78 + label: '展示类型',
  79 + sortable: true,
  80 + align: 'center',
  81 + render: function (row) {
  82 + if(row.resType == 'HOST_X86SERVER'){
  83 + //初始化select内容
  84 + /* var html='<div><select data-resId="'+d.resId+'" data-username="'+username+'" data-index="99" name="showType" class="layui-input user_showType" style="min-width: 150px;display: inline">';
  85 + showTypeList.value.map((v,i)=>{
  86 + if(d.showType == v.value){
  87 + html += '<option value="' + v.value + '" selected>' + v.name + '</option> '
  88 + }else{
  89 + html += '<option value="' + v.value + '">' + v.name + '</option> '
  90 + }
  91 + })
  92 + html+='</select></div>';
  93 + return html;*/
  94 + }else{
  95 + return '';
  96 + }
  97 + }
  98 + }
  99 + ];
  100 + //配置列表总数
  101 + let count = Vue.ref(0);
  102 + //列表数据
  103 + let portSenseConfigData = Vue.ref([]);
  104 + //数据库的数据
  105 + let portSenseConfigList = Vue.ref([]);
  106 + //资源数据
  107 + let resIdArr = Vue.ref([]);
  108 + //列表高度
  109 + let height = Vue.ref(window.innerHeight);
  110 + //列表分页
  111 + let pageSize = Vue.ref(400);
  112 + //加载
  113 + let loading = Vue.ref(true);
  114 + //选中数据
  115 + let pitch = Vue.ref([]);
  116 + //下拉框数据
  117 + let portSenseSelectData = Vue.ref([]);
  118 +
  119 + //获取列表数据
  120 + const getListData = ({page, limit}) => {
  121 + //获取传递过来的参数
  122 + resIdArr.value = JSON.parse(JSON.stringify(props.parameter));
  123 + //传递参数赋值给下拉框
  124 + portSenseSelectData.value = resIdArr.value;
  125 +
  126 + let username=proxy.$route.query.username;
  127 + let resName=proxy.$route.query.resName;
  128 + //定义列表参数
  129 + let getParams = {
  130 + resIds: resIdArr.value.join(','),
  131 + resName: resName,
  132 + userId: username,
  133 + page: page,
  134 + limit: limit
  135 + };
  136 + proxy.$http.get("/api-web/manage/resource/getAllResByUser", getParams, function (res) {
  137 + if (res && res.success) {
  138 + portSenseConfigData.value = res.data ? res.data : [];
  139 + count.value = res.count;
  140 + loading.value = false;
  141 + portSenseConfigList.value = res.data ? JSON.parse(JSON.stringify(res.data)) : [];
  142 + }
  143 + })
  144 + }
  145 +
  146 + //表格全选事件
  147 + let selectionChange = (val) => {
  148 + pitch.value = val;
  149 + proxy.portSenseConfigData.map((v, i) => {
  150 + v.checked = false;
  151 + });
  152 + let selectData = val;
  153 + if (selectData.length > 0) {
  154 + selectData.map((item, index) => {
  155 + proxy.portSenseConfigData.map((v, i) => {
  156 + if (item.id == v.id) {
  157 + v.checked = true;
  158 + }
  159 + })
  160 + })
  161 + } else {
  162 + proxy.portSenseConfigData.map((v, i) => {
  163 + v.checked = false;
  164 + })
  165 + }
  166 + }
  167 + //删除单个数据
  168 + let deleteItem = (row, index) => {
  169 + proxy.$global.confirm("确认删除吗?", function () {
  170 + deleteItems(row, index);
  171 + })
  172 + }
  173 + //删除多个或单个
  174 + let deleteItems = (row, index) => {
  175 + //新添加未保存的
  176 + let sign = deleteNotSave(row, index);
  177 + if (sign) {
  178 + return false;
  179 + }
  180 + proxy.$http.post('/api-web/bResourceExtendParam/deleteConfig', row, function (res) {
  181 + if (res && res.success) {
  182 + proxy.$global.showMsg('删除成功');
  183 + loadTableDataList({page: 1, limit: pageSize.value});
  184 + }
  185 + })
  186 + }
  187 + //删除新添加但未保存的
  188 + let deleteNotSave = (row, index) => {
  189 + let sign = false;
  190 + let list = portSenseConfigData.value;
  191 + if(row.id === ""){
  192 + portSenseConfigData.value = list.filter((item, i, array) => index !== i);
  193 + }
  194 + if (list.length > portSenseConfigData.value.length) {
  195 + proxy.$global.showMsg('删除成功');
  196 + sign = true;
  197 + }
  198 + return sign;
  199 + }
  200 + //新增 添加一行数据
  201 + let save = () => {
  202 + let data = {
  203 + id: "",
  204 + intervalTime: null,
  205 + paramCode: "",
  206 + paramDesc: "",
  207 + paramValue: "",
  208 + port: "",
  209 + portDesc: "",
  210 + protocolType: "",
  211 + resId: "",
  212 + resIdList: resIdArr.value,
  213 + }
  214 + portSenseConfigData.value.push(data);
  215 + }
  216 + //下拉框值改变事件
  217 + let changePortSense = () => {
  218 +
  219 + }
  220 + //保存
  221 + let conserve = () => {
  222 + //数据验证
  223 + let msg = verifyData();
  224 + if (msg !== "") {
  225 + proxy.$global.showMsg(msg, "warning");
  226 + return false;
  227 + }
  228 + //逻辑验证
  229 + let identifying = isSave();
  230 + if (identifying !== "") {
  231 + proxy.$global.showMsg(identifying, "warning");
  232 + return false;
  233 + }
  234 + proxy.$http.post("/api-web/bResourceExtendParam/conserve", portSenseConfigData.value, function (res) {
  235 + if (res && res.success) {
  236 + proxy.$global.showMsg("保存成功!");
  237 + loadTableDataList({page: 1, limit: pageSize.value});
  238 + }
  239 + })
  240 + }
  241 + //保存表单验证
  242 + let verifyData = () => {
  243 + let msg = "";
  244 + //协议类型不能为空,端口备注不能为空,端口号请输入数字,间隔时长请输入数字,
  245 + let list = portSenseConfigData.value;
  246 + let li = columns.filter(item => "paramDesc" !== item.prop);
  247 + list.forEach(function (item, index, arr) {
  248 + li.forEach(function (e, i, array) {
  249 + if (item[e.prop] == null || item[e.prop] === '') {
  250 + msg = e.label + '不能为空';
  251 + } else {
  252 + if (['protocolType', 'portDesc'].indexOf(e.prop) === -1 && !/^\d+$/.test(item[e.prop])) {
  253 + msg = e.label + '请输入数字';
  254 + }else{
  255 + if(['protocolType', 'portDesc'].indexOf(e.prop) === -1 && item[e.prop].length>=8){
  256 + msg = e.label + '不能超过8位';
  257 + }else{
  258 + if(['protocolType', 'portDesc'].indexOf(e.prop) === -1 && item[e.prop]<=0){
  259 + msg = e.label + '只能大于零';
  260 + }
  261 + }
  262 + }
  263 + }
  264 + })
  265 + })
  266 + return msg
  267 + }
  268 + //是否可以保存
  269 + let isSave = () => {
  270 + let msg = "";
  271 + //零个资源不用判断
  272 + if (resIdArr.value.length === 0) {
  273 + return "必须选中资源";
  274 + }
  275 + //单个资源不用判断
  276 + if (resIdArr.value.length === 1) {
  277 + return msg;
  278 + }
  279 + //多个资源时,如果当前已选资源中存在列表新增加的协议类型和端口号对应的数据时,提示不允许进行保存,提示信息中必须包含资源名称+端口类型、端口号,
  280 + let list = [];
  281 + let arr = [];
  282 + portSenseConfigData.value.forEach(item => {
  283 + item.resIdList.forEach(map => {
  284 + let obj = Object.assign({}, item);
  285 + obj["resId"] = map;
  286 + obj["resIdList"] = [map];
  287 + list.push(obj);
  288 + })
  289 + });
  290 + //查看当前页面数据是否重复
  291 + groupByCount(list, arr);
  292 + if (arr.length > 0) {
  293 + return arr.join(',');
  294 + }
  295 + //查看当前页面数据跟数据库是否重复
  296 + let presentArray = [];
  297 + //过滤不是新增的数据
  298 + list = list.filter(item => item.id === "");
  299 + resIdArr.value.forEach(item => {
  300 + let li = [];
  301 + let getParams = {
  302 + resIds: item,
  303 + page: 1,
  304 + limit: 9999
  305 + };
  306 + proxy.$http.get("/api-web/bResourceExtendParam/portSensePage", getParams, function (res) {
  307 + if (res && res.success) {
  308 + li = res.data ? res.data : [];
  309 + list.forEach(e => {
  310 + li.forEach(map => {
  311 + if (map.resId === e.resId && map.paramCode === e.protocolType && map.port === e.port) {
  312 + let obj = Object.assign({}, e);
  313 + obj["resName"] = map.resName;
  314 + presentArray.push(obj);
  315 + }
  316 + });
  317 + });
  318 + }
  319 + }, null, null, null, false);
  320 + });
  321 + presentArray.forEach(item => {
  322 + let str = item.resName + "的" + item.paramCode.split("-")[0] + "协议" + "侦测的" + item.port + "端口号已侦测";
  323 + arr.push(str);
  324 + })
  325 + msg = arr.join(',');
  326 + return msg;
  327 + }
  328 + //重新加载表格数据
  329 + let loadTableDataList = ({page, limit}) => {
  330 + getListData({page, limit});
  331 + }
  332 + //修改父组件的值
  333 + let selectRes = (item) => {
  334 + portSenseConfigData.value = item;
  335 + }
  336 + //数组查找重复数据并统计行数
  337 + let groupByCount = (arr, array) => {
  338 + let list = [];
  339 + arr.sort((a, b) => {
  340 + if (a.resId !== b.resId) {
  341 + return a.resId < b.resId ? -1 : 1;
  342 + } else {
  343 + return a.name < b.name ? -1 : 1;
  344 + }
  345 + });
  346 + for (let i = 0; i < arr.length;) {
  347 + let count = 0;
  348 + for (let j = i; j < arr.length; j++) {
  349 + if (arr[i].resId === arr[j].resId && arr[i].protocolType === arr[j].protocolType && arr[i].port === arr[j].port) {
  350 + count++;
  351 + }
  352 + }
  353 + list.push({array: arr[i], count: count});
  354 + i += count;
  355 + }
  356 + list.forEach(item => {
  357 + if (item.count > 1) {
  358 + let str = item.array.resName + "的" + item.array.paramCode.split("-")[0] + "协议" + "侦测的" + item.array.port + "端口号已侦测";
  359 + array.push(str);
  360 + }
  361 + })
  362 + }
  363 +
  364 +
  365 + //获取展示类型的字典数据
  366 + let initShowType=()=>{
  367 + proxy.$http.get("/api-web/manage/resource/getAllResByUser", {}, function (res) {
  368 + if (res && res.success) {
  369 + let arr=res.data;
  370 + if(arr && arr.length>0){
  371 + arr.map(v=>{
  372 + showTypeList.value.push({
  373 + name: v.ddicName
  374 + ,value: v.ddicCode.substring(v.ddicCode.lastIndexOf("_")+1,v.ddicCode.length)
  375 + });
  376 + })
  377 + }
  378 +
  379 + }
  380 + })
  381 + }
  382 +
  383 + // 挂载完
  384 + Vue.onMounted(() => {
  385 + getListData({page: 1, limit: pageSize.value});
  386 + })
  387 + return {
  388 + initShowType,
  389 + showTypeList,
  390 + search,
  391 + resTypeOptions,
  392 +
  393 + count,
  394 + portSenseConfigData,
  395 + columns,
  396 + height,
  397 + pageSize,
  398 + loading,
  399 +
  400 + selectionChange,
  401 + deleteItem,
  402 + save,
  403 + getListData,
  404 + loadTableDataList,
  405 + changePortSense,
  406 + conserve,
  407 + selectRes,
  408 +
  409 + portSenseSelectData
  410 + }
  411 + }
  412 +}
  1 +export default {
  2 + name: 'resourceTypePer',
  3 + template: '',
  4 + components: {
  5 +
  6 + },
  7 + data() {
  8 + },
  9 + props: {
  10 + },
  11 + setup: function (props, {attrs, slots, emit}) {
  12 + const {proxy} = Vue.getCurrentInstance();
  13 +
  14 + // 挂载完
  15 + Vue.onMounted(() => {
  16 + })
  17 + return {
  18 +
  19 + }
  20 + }
  21 +}
  1 +export default {
  2 + name: 'resourceTypePer',
  3 + template: '',
  4 + components: {
  5 +
  6 + },
  7 + data() {
  8 + },
  9 + props: {
  10 + },
  11 + setup: function (props, {attrs, slots, emit}) {
  12 + const {proxy} = Vue.getCurrentInstance();
  13 +
  14 + // 挂载完
  15 + Vue.onMounted(() => {
  16 + })
  17 + return {
  18 +
  19 + }
  20 + }
  21 +}
  1 +export default {
  2 + name: 'resourceTypePer',
  3 + template: '',
  4 + components: {
  5 +
  6 + },
  7 + data() {
  8 + },
  9 + props: {
  10 + },
  11 + setup: function (props, {attrs, slots, emit}) {
  12 + const {proxy} = Vue.getCurrentInstance();
  13 +
  14 + // 挂载完
  15 + Vue.onMounted(() => {
  16 + })
  17 + return {
  18 +
  19 + }
  20 + }
  21 +}