Commit a9cc0aa4 by 谢林威

Merge branch 'develop' of gitlab.seetatech.com:seeta-device/deviceManage into develop

2 parents fa5bd8c9 3a4ea50a
Pipeline #5898 passed
in 2 minutes 13 seconds
......@@ -1871,63 +1871,6 @@
"integrity": "sha1-/q7SVZc9LndVW4PbwIhRpsY1IPo=",
"dev": true
},
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"optional": true,
"requires": {
"color-convert": "^2.0.1"
}
},
"chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"optional": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"optional": true,
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true,
"optional": true
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
"optional": true
},
"loader-utils": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
"integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
"dev": true,
"optional": true,
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
}
},
"ssri": {
"version": "8.0.1",
"resolved": "https://registry.nlark.com/ssri/download/ssri-8.0.1.tgz?cache=0&sync_timestamp=1621364668574&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fssri%2Fdownload%2Fssri-8.0.1.tgz",
......@@ -1936,28 +1879,6 @@
"requires": {
"minipass": "^3.1.1"
}
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"optional": true,
"requires": {
"has-flag": "^4.0.0"
}
},
"vue-loader-v16": {
"version": "npm:vue-loader@16.4.1",
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.4.1.tgz",
"integrity": "sha512-nL1bDhfMAZgTVmVkOXQaK/WJa9zFDLM9vKHbh5uGv6HeH1TmZrXMWUEVhUrACT38XPhXM4Awtjj25EvhChEgXw==",
"dev": true,
"optional": true,
"requires": {
"chalk": "^4.1.0",
"hash-sum": "^2.0.0",
"loader-utils": "^2.0.0"
}
}
}
},
......@@ -13017,6 +12938,11 @@
}
}
},
"sortablejs": {
"version": "1.10.2",
"resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.10.2.tgz",
"integrity": "sha512-YkPGufevysvfwn5rfdlGyrGjt7/CRHwvRPogD/lC+TnvcN29jDpCifKP+rBqf+LRldfXSTh+0CGLcSg0VIxq3A=="
},
"source-list-map": {
"version": "2.0.1",
"resolved": "https://registry.npm.taobao.org/source-list-map/download/source-list-map-2.0.1.tgz",
......@@ -14527,6 +14453,87 @@
}
}
},
"vue-loader-v16": {
"version": "npm:vue-loader@16.5.0",
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.5.0.tgz",
"integrity": "sha512-WXh+7AgFxGTgb5QAkQtFeUcHNIEq3PGVQ8WskY5ZiFbWBkOwcCPRs4w/2tVyTbh2q6TVRlO3xfvIukUtjsu62A==",
"dev": true,
"optional": true,
"requires": {
"chalk": "^4.1.0",
"hash-sum": "^2.0.0",
"loader-utils": "^2.0.0"
},
"dependencies": {
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"optional": true,
"requires": {
"color-convert": "^2.0.1"
}
},
"chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"optional": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"optional": true,
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true,
"optional": true
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
"optional": true
},
"loader-utils": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
"integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
"dev": true,
"optional": true,
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
}
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"optional": true,
"requires": {
"has-flag": "^4.0.0"
}
}
}
},
"vue-property-decorator": {
"version": "9.1.2",
"resolved": "https://registry.npmjs.org/vue-property-decorator/-/vue-property-decorator-9.1.2.tgz",
......@@ -14579,6 +14586,14 @@
"integrity": "sha1-HuO8mhbsv1EYvjNLsV+cRvgvWCU=",
"dev": true
},
"vuedraggable": {
"version": "2.24.3",
"resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-2.24.3.tgz",
"integrity": "sha512-6/HDXi92GzB+Hcs9fC6PAAozK1RLt1ewPTLjK0anTYguXLAeySDmcnqE8IC0xa7shvSzRjQXq3/+dsZ7ETGF3g==",
"requires": {
"sortablejs": "1.10.2"
}
},
"vuex": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/vuex/-/vuex-3.6.2.tgz",
......
......@@ -40,6 +40,7 @@
"vue-property-decorator": "^9.1.2",
"vue-router": "^3.1.3",
"vue-showdown": "^2.4.1",
"vuedraggable": "^2.24.3",
"vuex": "^3.0.1",
"vuex-persistedstate": "^4.0.0-beta.3",
"xregexp": "^4.2.4",
......
......@@ -6,7 +6,7 @@
<style>
#app {
font-family: PingFangSC-Regular, PingFang SC, Avenir, Helvetica, Arial, sans-serif;
font-family: PingFangSC-Regular, 微软雅黑;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
......
......@@ -48,7 +48,7 @@
<g id="page2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="任务流-导航收起" transform="translate(-647.000000, -297.000000)">
<g id="编组-9" transform="translate(651.000000, 299.000000)">
<text id="请从左侧拖入元素开始运行" font-family="PingFangSC-Regular, PingFang SC" font-size="14" font-weight="normal" fill="#99A1A9">
<text id="请从左侧拖入元素开始运行" font-family="PingFangSC-Regular, 微软雅黑" font-size="14" font-weight="normal" fill="#99A1A9">
<tspan x="223" y="349">请从左侧拖入元素开始运行</tspan>
</text>
<g id="编组-8">
......@@ -63,7 +63,7 @@
<path d="M0.00398211327,2.32857083 L0.669189476,2.32857083 L0.669189476,10.3110592 L0.00398211327,10.3110592 L0.00398211327,2.32857083 Z M10.6472999,2.32857083 L11.3125073,2.32857083 L11.3125073,10.3110592 L10.6472999,10.3110592 L10.6472999,2.32857083 Z" id="形状"></path>
<path d="M10.6472999,10.3110592 L11.3125073,10.3110592 C11.3125073,11.596905 8.78072806,12.639285 5.6582447,12.639285 C2.53576134,12.639285 0.00398211327,11.596905 0.00398211327,10.3110592 L0.669189476,10.3110592 C0.669189476,11.0680652 2.86903023,11.9740776 5.6582447,11.9740776 C8.44745917,11.9740776 10.6472999,11.0680652 10.6472999,10.3110592 Z M10.6472999,10.3110592 L11.3125073,10.3110592 C11.3125073,11.596905 8.78072806,12.639285 5.6582447,12.639285 C2.53576134,12.639285 0.00398211327,11.596905 0.00398211327,10.3110592 L0.669189476,10.3110592 C0.669189476,11.0680652 2.86903023,11.9740776 5.6582447,11.9740776 C8.44745917,11.9740776 10.6472999,11.0680652 10.6472999,10.3110592 Z M10.6472999,7.65022974 L11.3125073,7.65022974 C11.3125073,8.93607557 8.78072806,9.9784555 5.6582447,9.9784555 C2.53576134,9.9784555 0.00398211327,8.93607557 0.00398211327,7.65022974 L0.669189476,7.65022974 C0.669189476,8.40723571 2.86903023,9.31324814 5.6582447,9.31324814 C8.44745917,9.31324814 10.6472999,8.40723571 10.6472999,7.65022974 Z M10.6472999,7.65022974 L11.3125073,7.65022974 C11.3125073,8.93607557 8.78072806,9.9784555 5.6582447,9.9784555 C2.53576134,9.9784555 0.00398211327,8.93607557 0.00398211327,7.65022974 L0.669189476,7.65022974 C0.669189476,8.40723571 2.86903023,9.31324814 5.6582447,9.31324814 C8.44745917,9.31324814 10.6472999,8.40723571 10.6472999,7.65022974 Z M10.6472999,4.98940028 L11.3125073,4.98940028 C11.3125073,6.27524612 8.78072806,7.31762605 5.6582447,7.31762605 C2.53576134,7.31762605 0.00398211327,6.27524612 0.00398211327,4.98940028 L0.669189476,4.98940028 C0.669189476,5.74640626 2.86903023,6.65241869 5.6582447,6.65241869 C8.44745917,6.65241869 10.6472999,5.74640626 10.6472999,4.98940028 L10.6472999,4.98940028 Z M10.6472999,4.98940028 L11.3125073,4.98940028 C11.3125073,6.27524612 8.78072806,7.31762605 5.6582447,7.31762605 C2.53576134,7.31762605 0.00398211327,6.27524612 0.00398211327,4.98940028 L0.669189476,4.98940028 C0.669189476,5.74640626 2.86903023,6.65241869 5.6582447,6.65241869 C8.44745917,6.65241869 10.6472999,5.74640626 10.6472999,4.98940028 L10.6472999,4.98940028 Z M5.6582447,3.99158924 C8.44745917,3.99158924 10.6472999,3.08557681 10.6472999,2.32857083 C10.6472999,1.57156485 8.44745917,0.665552426 5.6582447,0.665552426 C2.86903022,0.665552426 0.669189476,1.57156485 0.669189476,2.32857083 C0.669189476,3.08557681 2.86903023,3.99158924 5.6582447,3.99158924 L5.6582447,3.99158924 Z M5.6582447,4.6567966 C2.53576134,4.6567966 0.00398211327,3.61441667 0.00398211327,2.32857083 C0.00398211327,1.042725 2.53576134,0.000345063332 5.6582447,0.000345063332 C8.78072806,0.000345063332 11.3125073,1.042725 11.3125073,2.32857083 C11.3125073,3.61441667 8.78072806,4.6567966 5.6582447,4.6567966 L5.6582447,4.6567966 Z M9.15058335,4.6567966 C9.42612126,4.6567966 9.64948887,4.88016421 9.64948887,5.15570212 C9.64948887,5.43124004 9.42612126,5.65460765 9.15058335,5.65460765 C8.87504544,5.65460765 8.65167783,5.43124004 8.65167783,5.15570212 C8.65167783,4.88016421 8.87504544,4.6567966 9.15058335,4.6567966 Z M9.15058335,7.31762605 C9.42612126,7.31762605 9.64948887,7.54099366 9.64948887,7.81653158 C9.64948887,8.09206949 9.42612126,8.3154371 9.15058335,8.3154371 C8.87504544,8.3154371 8.65167783,8.09206949 8.65167783,7.81653158 C8.65167783,7.54099366 8.87504544,7.31762605 9.15058335,7.31762605 L9.15058335,7.31762605 Z M9.15058335,9.9784555 C9.42612126,9.9784555 9.64948887,10.2018231 9.64948887,10.477361 C9.64948887,10.7528989 9.42612126,10.9762665 9.15058335,10.9762665 C8.87504544,10.9762665 8.65167783,10.7528989 8.65167783,10.477361 C8.65167783,10.2018231 8.87504544,9.9784555 9.15058335,9.9784555 L9.15058335,9.9784555 Z" id="形状"></path>
</g>
<text id="数据集备份-15" font-family="PingFangSC-Regular, PingFang SC" font-size="12" font-weight="normal" fill="#99A1A9">
<text id="数据集备份-15" font-family="PingFangSC-Regular, 微软雅黑" font-size="12" font-weight="normal" fill="#99A1A9">
<tspan x="28" y="148">数据集</tspan>
</text>
<g id="编组-10备份" transform="translate(217.000000, 0.000000)">
......@@ -77,7 +77,7 @@
<g id="形状-2备份-9" transform="translate(12.000000, 34.000000)" fill="#ACACAC" fill-rule="nonzero">
<path d="M0.666666666,3.33333333 L0.666666666,2.66666667 L11.3333333,2.66666667 L11.3333333,0.666666667 L0.666666666,0.666666667 L0.666666666,10 L11.3333333,10 L11.3333333,3.33333333 L0.666666666,3.33333333 Z M0.666666666,1.51212376e-13 L11.3333333,1.51212376e-13 C11.5101443,1.51212376e-13 11.6797136,0.0702378937 11.8047379,0.195262146 C11.9297621,0.320286398 12,0.489855674 12,0.666666667 L12,10 C12,10.176811 11.9297621,10.3463803 11.8047379,10.4714045 C11.6797136,10.5964288 11.5101443,10.6666667 11.3333333,10.6666667 L0.666666666,10.6666667 C0.489855673,10.6666667 0.320286398,10.5964288 0.195262146,10.4714045 C0.0702378933,10.3463803 0,10.176811 0,10 L0,0.666666667 C0,0.489855674 0.0702378933,0.320286398 0.195262146,0.195262146 C0.320286398,0.0702378937 0.489855673,1.51212376e-13 0.666666666,1.51212376e-13 Z M4.236,7.512 C4.3661551,7.6423392 4.36600585,7.85351156 4.23566666,7.98366666 C4.10532746,8.11382176 3.89415511,8.11367253 3.764,7.98333333 L2.35066667,6.56933333 C2.2879722,6.50679716 2.25273748,6.42188484 2.25273748,6.33333333 C2.25273748,6.24478183 2.2879722,6.15986951 2.35066667,6.09733333 L3.764,4.684 C3.84757067,4.59723764 3.97145193,4.56231662 4.08803308,4.59265798 C4.20461424,4.62299934 4.29575399,4.71388163 4.32642501,4.83037649 C4.35709604,4.94687135 4.32252561,5.0708509 4.236,5.15466667 L3.05733333,6.33333333 L4.236,7.512 Z M7.764,5.15466667 C7.63384489,5.02432747 7.63399413,4.81315511 7.76433333,4.683 C7.89467253,4.55284489 8.10584489,4.55299413 8.236,4.68333333 L9.64933333,6.09733333 C9.7120278,6.15986951 9.74726252,6.24478183 9.74726252,6.33333333 C9.74726252,6.42188484 9.7120278,6.50679716 9.64933333,6.56933333 L8.236,7.98266667 C8.15242933,8.06942903 8.02854807,8.10435004 7.91196692,8.07400868 C7.79538577,8.04366732 7.70424602,7.95278503 7.67357499,7.83629018 C7.64290396,7.71979532 7.67747439,7.59581577 7.764,7.512 L8.94266667,6.33333333 L7.764,5.15466667 Z M6.95533333,5.34533333 L5.622,7.65466667 C5.52933142,7.81273789 5.32645098,7.86637624 5.16776855,7.77475821 C5.00908612,7.68314017 4.95410321,7.48061999 5.04466667,7.32133333 L6.378,5.012 C6.47005013,4.85257728 6.67390656,4.79795689 6.83333333,4.89 C6.99275605,4.98205013 7.04737645,5.18590656 6.95533333,5.34533333 Z" id="形状"></path>
</g>
<text id="算法" font-family="PingFangSC-Regular, PingFang SC" font-size="12" font-weight="normal" fill="#99A1A9">
<text id="算法" font-family="PingFangSC-Regular, 微软雅黑" font-size="12" font-weight="normal" fill="#99A1A9">
<tspan x="28" y="44">算法</tspan>
</text>
</g>
......@@ -101,7 +101,7 @@
<g id="形状-2备份-11" transform="translate(466.000000, 137.000000)" fill="#ACACAC" fill-rule="nonzero">
<path d="M0.666666666,3.33333333 L0.666666666,2.66666667 L11.3333333,2.66666667 L11.3333333,0.666666667 L0.666666666,0.666666667 L0.666666666,10 L11.3333333,10 L11.3333333,3.33333333 L0.666666666,3.33333333 Z M0.666666666,1.51212376e-13 L11.3333333,1.51212376e-13 C11.5101443,1.51212376e-13 11.6797136,0.0702378937 11.8047379,0.195262146 C11.9297621,0.320286398 12,0.489855674 12,0.666666667 L12,10 C12,10.176811 11.9297621,10.3463803 11.8047379,10.4714045 C11.6797136,10.5964288 11.5101443,10.6666667 11.3333333,10.6666667 L0.666666666,10.6666667 C0.489855673,10.6666667 0.320286398,10.5964288 0.195262146,10.4714045 C0.0702378933,10.3463803 0,10.176811 0,10 L0,0.666666667 C0,0.489855674 0.0702378933,0.320286398 0.195262146,0.195262146 C0.320286398,0.0702378937 0.489855673,1.51212376e-13 0.666666666,1.51212376e-13 Z M4.236,7.512 C4.3661551,7.6423392 4.36600585,7.85351156 4.23566666,7.98366666 C4.10532746,8.11382176 3.89415511,8.11367253 3.764,7.98333333 L2.35066667,6.56933333 C2.2879722,6.50679716 2.25273748,6.42188484 2.25273748,6.33333333 C2.25273748,6.24478183 2.2879722,6.15986951 2.35066667,6.09733333 L3.764,4.684 C3.84757067,4.59723764 3.97145193,4.56231662 4.08803308,4.59265798 C4.20461424,4.62299934 4.29575399,4.71388163 4.32642501,4.83037649 C4.35709604,4.94687135 4.32252561,5.0708509 4.236,5.15466667 L3.05733333,6.33333333 L4.236,7.512 Z M7.764,5.15466667 C7.63384489,5.02432747 7.63399413,4.81315511 7.76433333,4.683 C7.89467253,4.55284489 8.10584489,4.55299413 8.236,4.68333333 L9.64933333,6.09733333 C9.7120278,6.15986951 9.74726252,6.24478183 9.74726252,6.33333333 C9.74726252,6.42188484 9.7120278,6.50679716 9.64933333,6.56933333 L8.236,7.98266667 C8.15242933,8.06942903 8.02854807,8.10435004 7.91196692,8.07400868 C7.79538577,8.04366732 7.70424602,7.95278503 7.67357499,7.83629018 C7.64290396,7.71979532 7.67747439,7.59581577 7.764,7.512 L8.94266667,6.33333333 L7.764,5.15466667 Z M6.95533333,5.34533333 L5.622,7.65466667 C5.52933142,7.81273789 5.32645098,7.86637624 5.16776855,7.77475821 C5.00908612,7.68314017 4.95410321,7.48061999 5.04466667,7.32133333 L6.378,5.012 C6.47005013,4.85257728 6.67390656,4.79795689 6.83333333,4.89 C6.99275605,4.98205013 7.04737645,5.18590656 6.95533333,5.34533333 Z" id="形状"></path>
</g>
<text id="算法" font-family="PingFangSC-Regular, PingFang SC" font-size="12" font-weight="normal" fill="#99A1A9">
<text id="算法" font-family="PingFangSC-Regular, 微软雅黑" font-size="12" font-weight="normal" fill="#99A1A9">
<tspan x="482" y="147">算法</tspan>
</text>
<circle id="Oval-Copy-2复制备份-14" stroke="#C5CCD2" fill="#FFFFFF" cx="454" cy="132" r="5"></circle>
......@@ -113,7 +113,7 @@
<text id="处理器名称" font-family="PingFang-SC-Bold, PingFang SC" font-size="13" font-weight="bold" fill="#99A1A9">
<tspan x="12" y="22">处理器名称</tspan>
</text>
<text id="处理器" font-family="PingFangSC-Regular, PingFang SC" font-size="12" font-weight="normal" fill="#99A1A9">
<text id="处理器" font-family="PingFangSC-Regular, 微软雅黑" font-size="12" font-weight="normal" fill="#99A1A9">
<tspan x="28" y="44">处理器</tspan>
</text>
<g id="model备份-3" transform="translate(12.000000, 34.000000)" fill="#ACACAC" fill-rule="nonzero">
......
......@@ -48,7 +48,7 @@
<g id="page2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="任务流-导航收起" transform="translate(-647.000000, -297.000000)">
<g id="编组-9" transform="translate(651.000000, 299.000000)">
<text id="请从左侧拖入元素开始运行" font-family="PingFangSC-Regular, PingFang SC" font-size="14" font-weight="normal" fill="#99A1A9">
<text id="请从左侧拖入元素开始运行" font-family="PingFangSC-Regular, 微软雅黑" font-size="14" font-weight="normal" fill="#99A1A9">
<tspan x="223" y="349">左側のモジュールをドラッグアンドドロップしてください</tspan>
</text>
<g id="编组-8">
......@@ -63,7 +63,7 @@
<path d="M0.00398211327,2.32857083 L0.669189476,2.32857083 L0.669189476,10.3110592 L0.00398211327,10.3110592 L0.00398211327,2.32857083 Z M10.6472999,2.32857083 L11.3125073,2.32857083 L11.3125073,10.3110592 L10.6472999,10.3110592 L10.6472999,2.32857083 Z" id="形状"></path>
<path d="M10.6472999,10.3110592 L11.3125073,10.3110592 C11.3125073,11.596905 8.78072806,12.639285 5.6582447,12.639285 C2.53576134,12.639285 0.00398211327,11.596905 0.00398211327,10.3110592 L0.669189476,10.3110592 C0.669189476,11.0680652 2.86903023,11.9740776 5.6582447,11.9740776 C8.44745917,11.9740776 10.6472999,11.0680652 10.6472999,10.3110592 Z M10.6472999,10.3110592 L11.3125073,10.3110592 C11.3125073,11.596905 8.78072806,12.639285 5.6582447,12.639285 C2.53576134,12.639285 0.00398211327,11.596905 0.00398211327,10.3110592 L0.669189476,10.3110592 C0.669189476,11.0680652 2.86903023,11.9740776 5.6582447,11.9740776 C8.44745917,11.9740776 10.6472999,11.0680652 10.6472999,10.3110592 Z M10.6472999,7.65022974 L11.3125073,7.65022974 C11.3125073,8.93607557 8.78072806,9.9784555 5.6582447,9.9784555 C2.53576134,9.9784555 0.00398211327,8.93607557 0.00398211327,7.65022974 L0.669189476,7.65022974 C0.669189476,8.40723571 2.86903023,9.31324814 5.6582447,9.31324814 C8.44745917,9.31324814 10.6472999,8.40723571 10.6472999,7.65022974 Z M10.6472999,7.65022974 L11.3125073,7.65022974 C11.3125073,8.93607557 8.78072806,9.9784555 5.6582447,9.9784555 C2.53576134,9.9784555 0.00398211327,8.93607557 0.00398211327,7.65022974 L0.669189476,7.65022974 C0.669189476,8.40723571 2.86903023,9.31324814 5.6582447,9.31324814 C8.44745917,9.31324814 10.6472999,8.40723571 10.6472999,7.65022974 Z M10.6472999,4.98940028 L11.3125073,4.98940028 C11.3125073,6.27524612 8.78072806,7.31762605 5.6582447,7.31762605 C2.53576134,7.31762605 0.00398211327,6.27524612 0.00398211327,4.98940028 L0.669189476,4.98940028 C0.669189476,5.74640626 2.86903023,6.65241869 5.6582447,6.65241869 C8.44745917,6.65241869 10.6472999,5.74640626 10.6472999,4.98940028 L10.6472999,4.98940028 Z M10.6472999,4.98940028 L11.3125073,4.98940028 C11.3125073,6.27524612 8.78072806,7.31762605 5.6582447,7.31762605 C2.53576134,7.31762605 0.00398211327,6.27524612 0.00398211327,4.98940028 L0.669189476,4.98940028 C0.669189476,5.74640626 2.86903023,6.65241869 5.6582447,6.65241869 C8.44745917,6.65241869 10.6472999,5.74640626 10.6472999,4.98940028 L10.6472999,4.98940028 Z M5.6582447,3.99158924 C8.44745917,3.99158924 10.6472999,3.08557681 10.6472999,2.32857083 C10.6472999,1.57156485 8.44745917,0.665552426 5.6582447,0.665552426 C2.86903022,0.665552426 0.669189476,1.57156485 0.669189476,2.32857083 C0.669189476,3.08557681 2.86903023,3.99158924 5.6582447,3.99158924 L5.6582447,3.99158924 Z M5.6582447,4.6567966 C2.53576134,4.6567966 0.00398211327,3.61441667 0.00398211327,2.32857083 C0.00398211327,1.042725 2.53576134,0.000345063332 5.6582447,0.000345063332 C8.78072806,0.000345063332 11.3125073,1.042725 11.3125073,2.32857083 C11.3125073,3.61441667 8.78072806,4.6567966 5.6582447,4.6567966 L5.6582447,4.6567966 Z M9.15058335,4.6567966 C9.42612126,4.6567966 9.64948887,4.88016421 9.64948887,5.15570212 C9.64948887,5.43124004 9.42612126,5.65460765 9.15058335,5.65460765 C8.87504544,5.65460765 8.65167783,5.43124004 8.65167783,5.15570212 C8.65167783,4.88016421 8.87504544,4.6567966 9.15058335,4.6567966 Z M9.15058335,7.31762605 C9.42612126,7.31762605 9.64948887,7.54099366 9.64948887,7.81653158 C9.64948887,8.09206949 9.42612126,8.3154371 9.15058335,8.3154371 C8.87504544,8.3154371 8.65167783,8.09206949 8.65167783,7.81653158 C8.65167783,7.54099366 8.87504544,7.31762605 9.15058335,7.31762605 L9.15058335,7.31762605 Z M9.15058335,9.9784555 C9.42612126,9.9784555 9.64948887,10.2018231 9.64948887,10.477361 C9.64948887,10.7528989 9.42612126,10.9762665 9.15058335,10.9762665 C8.87504544,10.9762665 8.65167783,10.7528989 8.65167783,10.477361 C8.65167783,10.2018231 8.87504544,9.9784555 9.15058335,9.9784555 L9.15058335,9.9784555 Z" id="形状"></path>
</g>
<text id="数据集备份-15" font-family="PingFangSC-Regular, PingFang SC" font-size="12" font-weight="normal" fill="#99A1A9">
<text id="数据集备份-15" font-family="PingFangSC-Regular, 微软雅黑" font-size="12" font-weight="normal" fill="#99A1A9">
<tspan x="28" y="148">データセット</tspan>
</text>
<g id="编组-10备份" transform="translate(217.000000, 0.000000)">
......@@ -77,7 +77,7 @@
<g id="形状-2备份-9" transform="translate(12.000000, 34.000000)" fill="#ACACAC" fill-rule="nonzero">
<path d="M0.666666666,3.33333333 L0.666666666,2.66666667 L11.3333333,2.66666667 L11.3333333,0.666666667 L0.666666666,0.666666667 L0.666666666,10 L11.3333333,10 L11.3333333,3.33333333 L0.666666666,3.33333333 Z M0.666666666,1.51212376e-13 L11.3333333,1.51212376e-13 C11.5101443,1.51212376e-13 11.6797136,0.0702378937 11.8047379,0.195262146 C11.9297621,0.320286398 12,0.489855674 12,0.666666667 L12,10 C12,10.176811 11.9297621,10.3463803 11.8047379,10.4714045 C11.6797136,10.5964288 11.5101443,10.6666667 11.3333333,10.6666667 L0.666666666,10.6666667 C0.489855673,10.6666667 0.320286398,10.5964288 0.195262146,10.4714045 C0.0702378933,10.3463803 0,10.176811 0,10 L0,0.666666667 C0,0.489855674 0.0702378933,0.320286398 0.195262146,0.195262146 C0.320286398,0.0702378937 0.489855673,1.51212376e-13 0.666666666,1.51212376e-13 Z M4.236,7.512 C4.3661551,7.6423392 4.36600585,7.85351156 4.23566666,7.98366666 C4.10532746,8.11382176 3.89415511,8.11367253 3.764,7.98333333 L2.35066667,6.56933333 C2.2879722,6.50679716 2.25273748,6.42188484 2.25273748,6.33333333 C2.25273748,6.24478183 2.2879722,6.15986951 2.35066667,6.09733333 L3.764,4.684 C3.84757067,4.59723764 3.97145193,4.56231662 4.08803308,4.59265798 C4.20461424,4.62299934 4.29575399,4.71388163 4.32642501,4.83037649 C4.35709604,4.94687135 4.32252561,5.0708509 4.236,5.15466667 L3.05733333,6.33333333 L4.236,7.512 Z M7.764,5.15466667 C7.63384489,5.02432747 7.63399413,4.81315511 7.76433333,4.683 C7.89467253,4.55284489 8.10584489,4.55299413 8.236,4.68333333 L9.64933333,6.09733333 C9.7120278,6.15986951 9.74726252,6.24478183 9.74726252,6.33333333 C9.74726252,6.42188484 9.7120278,6.50679716 9.64933333,6.56933333 L8.236,7.98266667 C8.15242933,8.06942903 8.02854807,8.10435004 7.91196692,8.07400868 C7.79538577,8.04366732 7.70424602,7.95278503 7.67357499,7.83629018 C7.64290396,7.71979532 7.67747439,7.59581577 7.764,7.512 L8.94266667,6.33333333 L7.764,5.15466667 Z M6.95533333,5.34533333 L5.622,7.65466667 C5.52933142,7.81273789 5.32645098,7.86637624 5.16776855,7.77475821 C5.00908612,7.68314017 4.95410321,7.48061999 5.04466667,7.32133333 L6.378,5.012 C6.47005013,4.85257728 6.67390656,4.79795689 6.83333333,4.89 C6.99275605,4.98205013 7.04737645,5.18590656 6.95533333,5.34533333 Z" id="形状"></path>
</g>
<text id="算法" font-family="PingFangSC-Regular, PingFang SC" font-size="12" font-weight="normal" fill="#99A1A9">
<text id="算法" font-family="PingFangSC-Regular, 微软雅黑" font-size="12" font-weight="normal" fill="#99A1A9">
<tspan x="28" y="44">アルゴリズム</tspan>
</text>
</g>
......@@ -101,7 +101,7 @@
<g id="形状-2备份-11" transform="translate(466.000000, 137.000000)" fill="#ACACAC" fill-rule="nonzero">
<path d="M0.666666666,3.33333333 L0.666666666,2.66666667 L11.3333333,2.66666667 L11.3333333,0.666666667 L0.666666666,0.666666667 L0.666666666,10 L11.3333333,10 L11.3333333,3.33333333 L0.666666666,3.33333333 Z M0.666666666,1.51212376e-13 L11.3333333,1.51212376e-13 C11.5101443,1.51212376e-13 11.6797136,0.0702378937 11.8047379,0.195262146 C11.9297621,0.320286398 12,0.489855674 12,0.666666667 L12,10 C12,10.176811 11.9297621,10.3463803 11.8047379,10.4714045 C11.6797136,10.5964288 11.5101443,10.6666667 11.3333333,10.6666667 L0.666666666,10.6666667 C0.489855673,10.6666667 0.320286398,10.5964288 0.195262146,10.4714045 C0.0702378933,10.3463803 0,10.176811 0,10 L0,0.666666667 C0,0.489855674 0.0702378933,0.320286398 0.195262146,0.195262146 C0.320286398,0.0702378937 0.489855673,1.51212376e-13 0.666666666,1.51212376e-13 Z M4.236,7.512 C4.3661551,7.6423392 4.36600585,7.85351156 4.23566666,7.98366666 C4.10532746,8.11382176 3.89415511,8.11367253 3.764,7.98333333 L2.35066667,6.56933333 C2.2879722,6.50679716 2.25273748,6.42188484 2.25273748,6.33333333 C2.25273748,6.24478183 2.2879722,6.15986951 2.35066667,6.09733333 L3.764,4.684 C3.84757067,4.59723764 3.97145193,4.56231662 4.08803308,4.59265798 C4.20461424,4.62299934 4.29575399,4.71388163 4.32642501,4.83037649 C4.35709604,4.94687135 4.32252561,5.0708509 4.236,5.15466667 L3.05733333,6.33333333 L4.236,7.512 Z M7.764,5.15466667 C7.63384489,5.02432747 7.63399413,4.81315511 7.76433333,4.683 C7.89467253,4.55284489 8.10584489,4.55299413 8.236,4.68333333 L9.64933333,6.09733333 C9.7120278,6.15986951 9.74726252,6.24478183 9.74726252,6.33333333 C9.74726252,6.42188484 9.7120278,6.50679716 9.64933333,6.56933333 L8.236,7.98266667 C8.15242933,8.06942903 8.02854807,8.10435004 7.91196692,8.07400868 C7.79538577,8.04366732 7.70424602,7.95278503 7.67357499,7.83629018 C7.64290396,7.71979532 7.67747439,7.59581577 7.764,7.512 L8.94266667,6.33333333 L7.764,5.15466667 Z M6.95533333,5.34533333 L5.622,7.65466667 C5.52933142,7.81273789 5.32645098,7.86637624 5.16776855,7.77475821 C5.00908612,7.68314017 4.95410321,7.48061999 5.04466667,7.32133333 L6.378,5.012 C6.47005013,4.85257728 6.67390656,4.79795689 6.83333333,4.89 C6.99275605,4.98205013 7.04737645,5.18590656 6.95533333,5.34533333 Z" id="形状"></path>
</g>
<text id="算法" font-family="PingFangSC-Regular, PingFang SC" font-size="12" font-weight="normal" fill="#99A1A9">
<text id="算法" font-family="PingFangSC-Regular, 微软雅黑" font-size="12" font-weight="normal" fill="#99A1A9">
<tspan x="482" y="147">アルゴリズム</tspan>
</text>
<circle id="Oval-Copy-2复制备份-14" stroke="#C5CCD2" fill="#FFFFFF" cx="454" cy="132" r="5"></circle>
......@@ -113,7 +113,7 @@
<text id="处理器名称" font-family="PingFang-SC-Bold, PingFang SC" font-size="13" font-weight="bold" fill="#99A1A9">
<tspan x="12" y="22">プロセッサ名</tspan>
</text>
<text id="处理器" font-family="PingFangSC-Regular, PingFang SC" font-size="12" font-weight="normal" fill="#99A1A9">
<text id="处理器" font-family="PingFangSC-Regular, 微软雅黑" font-size="12" font-weight="normal" fill="#99A1A9">
<tspan x="28" y="44">プロセッサ</tspan>
</text>
<g id="model备份-3" transform="translate(12.000000, 34.000000)" fill="#ACACAC" fill-rule="nonzero">
......
......@@ -17,6 +17,7 @@ export const createParameter = data => axios(POST, FRONT + PARAMETER + '/create'
export const deleteParameter = data => axios(GET, FRONT + PARAMETER + '/delete', data)
export const editParameter = data => axios(POST, FRONT + PARAMETER + '/change', data)
export const detailParameter = data => axios(GET, FRONT + PARAMETER + '/query', data)
export const getTagByServiceType = data => axios(GET, FRONT + PARAMETER + '/service/query', data)
const TABLE = '/table'
export const getTable = data => axios(GET, FRONT + TABLE + '/query_list', data)
......@@ -34,3 +35,21 @@ export const addApp = data => axios(POST, FRONT + APPID + '/add', data)
const ACCOUNt = '/account'
export const getAccount = data => axios(GET, FRONT + ACCOUNt + '/query', data)
const DEVICE = '/device'
export const getDevice = data => axios(POST, FRONT + DEVICE + '/query_list', data)
export const getDeviceService = data => axios(GET, FRONT + DEVICE + '/service/query')
export const getTag = data => axios(GET, FRONT + DEVICE + '/tag/query_list')
export const getServiceParamter = data => axios(GET, FRONT + DEVICE + '/service/parameter/query', data)
export const setServiceParamter = data => axios(POST, FRONT + DEVICE + '/service/parameter/change', data)
export const deleteTag = data => axios(GET, FRONT + DEVICE + '/tag/delete', data)
export const addTag = data => axios(POST, FRONT + DEVICE + '/tag/add', data)
export const postServiceRequest = data => axios(POST, FRONT + DEVICE + '/service/direct', data)
export const postServiceCommand = data => axios(POST, FRONT + DEVICE + '/service/command', data)
export const addTemplate = data => axios(POST, FRONT + DEVICE + '/service/template/dispatch', data)
export const deleteTemplate = data => axios(POST, FRONT + DEVICE + '/service/template/revoke', data)
export const deleteDevice = data => axios(POST, FRONT + DEVICE + '/delete', data)
const SERVICE = '/service'
export const getService = data => axios(POST, FRONT + SERVICE + '/query_list', data)
export const getServiceDevice = data => axios(GET, FRONT + SERVICE + '/device/query', data)
......@@ -14,6 +14,7 @@ import formTable from './form/index.vue'
// import ajaxButton from './form/ajax-button.vue'
import seetaInput from './seeta-ui/seeta-input.vue'
import seetaButton from './seeta-ui/seeta-button.vue'
// import seetaCheckBox from './seeta-ui/seeta-checkbox.vue'
// import seetaCollapse from './seeta-ui/seeta-collapse.vue'
import seetaForm from './seeta-ui/seeta-form/form.vue'
import seetaFormItem from './seeta-ui/seeta-form/form-item.vue'
......@@ -30,6 +31,7 @@ import seetaCrumb from './seeta-ui/seeta-crumb.vue'
// import name from './list-filter/name.vue'
// import time from './list-filter/time.vue'
import puzzlevalidator from './PuzzleValidator'
// import nameFilter from './list-filter/name.vue'
import Vue from 'vue'
import datePicker from './calendar/index.vue'
......@@ -42,6 +44,8 @@ import datePicker from './calendar/index.vue'
// Vue.component('v-select', select)
Vue.component('v-textarea', textarea)
Vue.component('dropdown', dropdown)
// Vue.component('st-checkbox', seetaCheckBox)
// Vue.component('nameFilter', nameFilter)
// Vue.component('code-editor', codeEditor)
// Vue.component('tabs', tabs)
// Vue.component('data-empty', dataEmpty)
......
......@@ -7,7 +7,8 @@
:placeholder="placeholder",
@keyup.enter="search"
)
.iconfont.icon-search(@click="search")
i.el-input__icon.el-icon-search.icon-search(@click="search")
//- .iconfont.icon-search(@click="search")
</template>
<script lang="ts">
import { Vue, Prop, Component, Watch } from 'vue-property-decorator'
......@@ -23,26 +24,36 @@ export default class nameFilter extends Vue {
}
search() {
const routeQuery = this.$route.query
// 避免重复搜索
if (this.name === routeQuery.name) return
const query = {
...routeQuery,
name: this.name,
page_index: '1',
}
this.$router.replace({ query: _.omitBy(query, item => item === '') })
this.$emit('startSearch', this.name)
// const routeQuery = this.$route.query
// // 避免重复搜索
// if (this.name === routeQuery.name || this.name === '') return
// const query = {
// ...routeQuery,
// name: this.name,
// page_index: '1',
// }
// this.$router.replace({ query: _.omitBy(query, item => item === '') })
}
}
</script>
<style lang="sass" scoped>
.search
height: 32px
width: 240px
position: relative
display: inline-block
.search-input
width: 100%
padding-right: 35px
padding: 5.5px 35px 5.5px 12px
font-size: 14px
font-family: PingFangSC-Regular
color: #333333
letter-spacing: 0
&::-webkit-input-placeholder
font-family: PingFangSC-Regular
font-size: 14px
color: #999999
.icon-search
position: absolute
right: 0
......
......@@ -361,13 +361,13 @@ export default {
padding: 13px 20px
font-size: 16px
border-bottom: 1px solid $--dialog-header-border
font-family: PingFangSC-Regular, PingFang SC
font-family: PingFangSC-Regular, 微软雅黑
font-weight: 400
color: #3C3D40
line-height: 22px
.popup-body
font-size: 14px
font-family: PingFangSC-Regular, PingFang SC
font-family: PingFangSC-Regular, 微软雅黑
font-weight: 400
color: #666666
line-height: 20px
......
......@@ -53,7 +53,7 @@ export default {
::v-deep .el-form-item__label
padding: 0 20px 0 0
font-size: 14px
font-family: PingFangSC-Regular, PingFang SC
font-family: PingFangSC-Regular, 微软雅黑
font-weight: 400
color: #666666
</style>
......@@ -16,6 +16,7 @@ const getByteLen = item => {
}
export default {
getByteLen: getByteLen,
ipV4: /((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.(((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})|\*)){1,3}/,
// 实例名称校验
normName: (rule, value, cb) => {
// 支持中文、英文、日文、数字和特殊字符_-@(),长度限制4~30个字符,中文及日文算2个字符
......
......@@ -23,11 +23,12 @@ export default {
::v-deep input[type=text], ::v-deep input[type=password], ::v-deep input[type=number], ::v-deep textarea
font-size: 14px
color: #333
font-family: PingFangSC-Regular, PingFang SC
font-weight: 400
font-family: PingFangSC-Regular, 微软雅黑
letter-spacing: 0
&::placeholder
color: #999999
font-size: 14px
letter-spacing: 0
.el-textarea.el-input--small
::v-deep .el-textarea__inner
border-radius: 2px
......
......@@ -40,13 +40,13 @@ export default class seetaSelect extends Vue {
.el-select-dropdown
.el-select-dropdown__item
font-size: 14px
font-family: PingFangSC-Regular, PingFang SC
font-family: PingFangSC-Regular, 微软雅黑
font-weight: 400
color: #333333
.el-select-dropdown__item.selected
font-weight: normal
font-size: 14px
font-family: PingFangSC-Regular, PingFang SC
font-family: PingFangSC-Regular, 微软雅黑
color: #409EFF
.el-select__tags
.el-icon-close
......@@ -57,13 +57,13 @@ export default class seetaSelect extends Vue {
color: #999999 !important
.el-select__tags-text
font-size: 12px !important
font-family: PingFangSC-Regular, PingFang SC !important
font-family: PingFangSC-Regular, 微软雅黑 !important
font-weight: 400 !important
color: #666666 !important
line-height: 17px !important
.el-select
.el-input__inner
font-size: 14px !important
font-family: PingFangSC-Regular, PingFang SC !important
font-family: PingFangSC-Regular, 微软雅黑 !important
font-weight: 400 !important
</style>
......@@ -12,6 +12,74 @@
@filter-change="filterChange"
@sort-change="sortChange"
>
<el-table-column type="expand" v-if="doubleTable" class="expend-column">
<!-- eslint-disable-next-line -->
<template slot-scope="props">
<el-table
stripe
:data="props.row.child">
<template
v-for="col in childOptions">
<!-- 插槽 -->
<el-table-column
header-align="left"
align="left"
v-if="col.type === 'slot'"
:key="col.label"
:label="col.label"
:min-width="col.width? col.width : ''"
:column-key="col.filterKey"
:filters="handleFilters(col.filterList)"
:filter-multiple="false"
filter-placement="bottom"
:sortable="!!col.sortable">
<template slot-scope="scope">
<div
v-if="(col.slotName === 'status' || col.slotName === 'state' || col.slotName === 'api_status')&& col.animation &&col.animation(scope.row)"
class="status-icon-animation"
:style="{
background: col.statusColor && col.statusColor(scope.row)
}">
</div>
<div
v-else-if="col.slotName === 'status' || col.slotName === 'state' ||col.slotName === 'api_status'"
class="status-icon"
:style="{
background: col.statusColor && col.statusColor(scope.row)
}">
</div>
<div class="any-slot">
<slot :name="col.slotName" v-bind="scope.row"></slot>
</div>
</template>
</el-table-column>
<el-table-column
v-else-if="col.type === 'check' || col.type === 'selection'"
:key="col.label"
type="selection"
width="37"
:reserve-selection="true"
:selectable="selectable(col)">
</el-table-column>
<!-- 普通列 -->
<el-table-column
header-align="left"
align="left"
v-else-if="!(typeof col.render === 'function')"
:key="col.label"
:label="col.label"
:prop="col.render"
:min-width="col.width? col.width : ''"
:column-key="col.filterKey"
:filters="handleFilters(col.filterList)"
:filter-multiple="false"
filter-placement="bottom"
:sortable="!!col.sortable">
</el-table-column>
</template>
</el-table>
</template>
</el-table-column>
<template
v-for="col in options">
<!-- 多选框 -->
......@@ -133,12 +201,16 @@ export default class seetaTableIndex extends Vue {
}
// 传入遮罩控制
@Prop({ type: Boolean, default: false }) outerLoading
// 是否开启嵌套表格
@Prop({ type: Boolean, default: false }) doubleTable
// 列表参数
@Prop({ type: Array, default: () => [] }) options
// 子表格列表参数
@Prop({ type: Array, default: () => [] }) childOptions
@Prop({ type: Boolean, default: true }) stripe
// 数据加载函数
@Prop({ type: Function, default: () => { return {} } }) loadFunction
@Prop({ type: Number, default: 10 }) pageSize
@Prop({ type: Number, default: 30 }) pageSize
@Prop({ type: Number, default: 1 }) pageIndex
// 手动传入数据
@Prop({ type: Object, default: () => {} }) data
......@@ -158,6 +230,7 @@ export default class seetaTableIndex extends Vue {
@Prop({ type: String, default: 'total, prev, pager, next, sizes, jumper' }) pageLayout
isLoading: boolean = false
tableData: {}[] = []
childTableData: {}[] = []
total: number = 0
// currentPage: number = 1
// currentSize: number = 10
......@@ -227,11 +300,15 @@ export default class seetaTableIndex extends Vue {
this.currentFilters = {}
}, 100)
}
clickCollapse() {
this.getTableHeight()
}
// 计算列表高度
getTableHeight() {
this.$nextTick(() => {
this.tableHeight = this.pagination ? this.refTableBox.getBoundingClientRect().height - 66 : this.refTableBox.getBoundingClientRect().height - 25
// console.log(this.tableHeight)
if (this.refTableBox) {
this.tableHeight = this.pagination ? this.refTableBox.getBoundingClientRect().height - 66 : this.refTableBox.getBoundingClientRect().height - 25
}
})
}
/**
......@@ -257,6 +334,7 @@ export default class seetaTableIndex extends Vue {
dataChange(val) {
if (!val) return
this.tableData = val.list
this.childTableData = val.list.map(item => item.child)
if (val.total || val.total === 0) {
this.total = val.total
}
......@@ -330,12 +408,14 @@ export default class seetaTableIndex extends Vue {
@import "@/styles/theme.sass"
.table-box
height: 100%
overflow: auto
overflow: hidden
background: #fff
position: relative
.el-table
color: $--color-text-primary
font-size: 14px
::v-deep.el-table__expanded-cell
padding: 0 0
::v-deep .el-table__header
font-size: 14px
font-family: PingFang-SC-Bold, PingFang-SC
......@@ -384,6 +464,8 @@ export default class seetaTableIndex extends Vue {
opacity: 0.6
transform: scale(1)
::v-deep .el-table__row
.status-icon + .any-slot
display: inline-block
.status-icon, .status-icon-animation
width: 6px
height: 6px
......@@ -414,7 +496,7 @@ export default class seetaTableIndex extends Vue {
text-align: left
padding-left: 30px
font-size: 14px
font-family: PingFangSC-Regular, PingFang SC
font-family: PingFangSC-Regular, 微软雅黑
font-weight: 400
color: #333333
line-height: 20px
......@@ -445,7 +527,7 @@ export default class seetaTableIndex extends Vue {
padding: 2px 5px
color: #333
font-size: 14px
font-family: PingFangSC-Regular, PingFang SC
font-family: PingFangSC-Regular, 微软雅黑
::v-deep .el-pagination__total
font-size: 14px
color: $--color-text-primary
......@@ -467,7 +549,7 @@ export default class seetaTableIndex extends Vue {
background-color: #F5F7FA !important
.el-select-dropdown__item
font-size: 14px
font-family: PingFangSC-Regular, PingFang SC
font-family: PingFangSC-Regular, 微软雅黑
font-weight: 400
.el-select-dropdown__item, .selected
font-weight: normal !important
......
......@@ -32,7 +32,7 @@ export default class seetaTabs extends Vue {
margin: 0 0 14px
::v-deep .el-tabs__item
font-size: 14px
font-family: PingFangSC-Regular, PingFang SC
font-family: PingFangSC-Regular, 微软雅黑
font-weight: 400
&.is-active
color: #409EFF
......
......@@ -35,6 +35,16 @@ export default [
name: 'device',
meta: { title: '设备列表' },
component: () => import('@views/DeviceList')
}, {
path: '/device-detail',
name: 'device-detail',
meta: { title: '设备详情' },
component: () => import('@views/DeviceList/detail.vue')
}, {
path: '/device-service',
name: 'device-service',
meta: { title: '设备服务' },
component: () => import('@views/DeviceList/deviceService/deviceServiceIndex')
}]
},
{
......
......@@ -3,7 +3,10 @@ import browserStorage from '@/services/local-storage'
const state = () => ({
lang: browserStorage.getItem('lang') || 'zh-CN',
routerStatus: 0,
currentProduct: {}
currentProduct: {},
currentDevice: '',
currentService: {},
currentTagIndex: 0,
})
const mutations = {
......@@ -16,7 +19,18 @@ const mutations = {
},
changeCurrentProduct(state, item) {
state.currentProduct = JSON.parse(JSON.stringify(item))
}
},
changeCurrentDevice(state, item) {
state.currentDevice = item
},
changeCurrentService(state, item) {
state.currentService = JSON.parse(JSON.stringify(item))
},
changeCurrentTagIndex(state, item) {
state.currentTagIndex = item
sessionStorage.setItem('currentTagIndex', item)
},
}
const actions = {
......@@ -26,7 +40,10 @@ const actions = {
const getters = {
lang: state => state.lang,
routerStatus: state => state.routerStatus,
currentProduct: state => state.currentProduct
currentProduct: state => state.currentProduct,
currentDevice: state => state.currentDevice,
currentService: state => state.currentService,
currentTagIndex: state => state.currentTagIndex,
}
export default {
......
......@@ -85,5 +85,5 @@ body, html
#raw-input::-webkit-input-placeholder
font-size: 14px
color: #999
font-family: PingFangSC-Regular, PingFang SC
font-family: PingFangSC-Regular, 微软雅黑
font-weight: 400
......@@ -33,7 +33,7 @@
background-color: #FFF
margin-top: 14px
display: flex
font-family: PingFangSC-Regular, PingFang SC
font-family: PingFangSC-Regular, 微软雅黑
font-weight: 400
// align-items: center
align-items: flex-start
......@@ -47,7 +47,7 @@
vertical-align: middle
.el-input__inner::placeholder
font-size: 14px
font-family: PingFangSC-Regular, PingFang SC
font-family: PingFangSC-Regular, 微软雅黑
font-weight: 400
line-height: 14px
color:#999999
......@@ -56,7 +56,7 @@
display: inline-block
height: 20px
font-size: 14px
font-family: PingFangSC-Regular, PingFang SC
font-family: PingFangSC-Regular, 微软雅黑
font-weight: 400
color: #666666
line-height: 20px
......@@ -88,7 +88,7 @@
width: 56px
height: 18px
font-size: 14px
font-family: PingFangSC-Regular, PingFang SC
font-family: PingFangSC-Regular, 微软雅黑
font-weight: 400
color: #FFFFFF
i.iconfont::before
......@@ -103,10 +103,15 @@
height: 100%
.el-range-input
font-size: 14px
font-family: PingFangSC-Regular, PingFang SC
font-family: PingFangSC-Regular, 微软雅黑
font-weight: 400
.el-date-editor .el-range__close-icon
line-height: 24px
.el-select__input
border: none
padding: 0
appearance: none
background-color: transparent
// 新建页公共样式
.common-create
display: flex
......@@ -181,7 +186,7 @@
color: #409EFF
.operate
font-size: 14px
font-family: PingFangSC-Regular, PingFang SC
font-family: PingFangSC-Regular, 微软雅黑
font-weight: 400
color: #409EFF
line-height: 20px
......@@ -192,3 +197,9 @@
// 搜索栏禁止输入校验规则之外的字符
.error-border .el-input__inner
border: 1px solid red !important
.mySuccess
width: 122px !important
min-width: 122px
height: 40px
background: #FFFFFF
box-shadow: 0 0 8px 0 rgba(37,38,94,0.20)
......@@ -10,7 +10,7 @@
font-size: 12px
white-space: nowrap
text-align: center
font-family: PingFangSC-Regular, PingFang SC
font-family: PingFangSC-Regular, 微软雅黑
font-weight: 400
line-height: 17px
height: 28px
......
......@@ -6,7 +6,7 @@ export function rTime(date) {
}
// 转换时间格式 精确到分钟
export function rTimeMin(item) {
const json_date = moment(new Date(item)).format('YYYY-MM-DD kk:mm')
const json_date = moment(new Date(item)).format('YYYY-MM-DD HH:mm:ss')
return json_date
// const y = date.getFullYear()
// let m = date.getMonth() + 1
......@@ -62,7 +62,27 @@ export function isArrayEqual(value1 = [], value2 = []) {
}
return false
}
// 复制内容到粘贴板的实现
export function copyText(item) {
if (!item) {
return
}
const transfer = document.createElement('input')
document.body.appendChild(transfer)
transfer.value = item // 这里表示想要复制的内容
transfer.focus()
transfer.select()
if (document.execCommand('copy')) {
document.execCommand('copy')
}
transfer.blur()
this.$message({
message: '复制成功',
type: 'success',
customClass: 'mySuccess',
})
document.body.removeChild(transfer)
}
export function calculateByte(base64) {
if (base64.indexOf('base64,') !== -1) {
base64 = base64.substring(base64.indexOf('base64,') + 7)
......
<template>
<div class="data-list-common flex column main-content flex-1">
<div class="header">
<span class="title">{{'设备列表'}}</span>
</div>
<div class="page-content">
<div class="table-list">
<div class="list-content">
<st-table
ref="vTable"
:options="definitions"
:data="{
list: tokenList,
total: total,
}"
:outerLoading="loadingStatus"
:pagination="false"
>
<div slot='codeSlot' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="row.deviceid" placement="top">
<span>{{ simplify(row.deviceid, 3) }}</span>
</el-tooltip>
<i class="iconfont icon-fuzhi icon-fuzhi-text" @click="copyText(row.deviceid)"></i>
</div>
<div slot='status' slot-scope="row" class="status">
<span class="circleStatus" :style="{color: getStatusColor(row.state)}">{{ getStatusText(row.state) }}</span>
</div>
<div slot='ipSlot' slot-scope="row" class="ipSlot">
<el-tooltip class="item" effect="dark" :content="row.ip" placement="top">
<span >{{ simplify(row.ip, 4) }}</span>
</el-tooltip>
</div>
<div slot='structureSlot' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="row.structure" placement="top">
<span>{{ simplify(row.structure, 3) }}</span>
</el-tooltip>
</div>
<div slot='registerTimeSlot' slot-scope="row">
<span>{{ (row.register_date) }}</span>
</div>
<div slot='tagsSlot' slot-scope="row">
<div class="tagsItem">
<el-tooltip class="item" effect="dark" :content="row.tags.join(',')" placement="top" style="display: inline-block">
<div>
<template v-for="(item, index) in row.tags">
<el-tag class="label label-primary table-label" :key="index" :disable-transitions="false" closable @close="handleClose(row, item)">{{simplify(item, 3)}}</el-tag>
</template>
<span v-if="row.tags.length > 10">共: {{row.tags.length}} 条</span>
<el-input
class="input-new-tag"
v-if="inputVisible"
v-model="inputValue"
ref="saveTagInput"
size="small"
@keyup.enter.native="handleInputConfirm(row)"
@blur="handleInputConfirm(row)"
>
</el-input>
<el-button v-else class="button-new-tag" size="small" @click="showInput">+ 添加标签</el-button>
</div>
</el-tooltip>
</div>
</div>
<div slot='servicesSlot' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="getServiceName(row.services)" placement="top">
<!-- 必须要套一层 -->
<div>
<template v-for="(item, index) in row.services">
<span v-if="[0, 1, 2].indexOf(index) !== -1" :key="index" class="service-item">{{ simplify(item.name, 4) }}</span>
</template>
<span v-if="(row.services && row.services.length) > 10">共: {{(row.services && row.services.length) ? row.services.length : 0}} 条</span>
</div>
</el-tooltip>
</div>
<div slot='systemSlot' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="row.system" placement="top">
<span>{{ simplify(row.system, 3) }}</span>
</el-tooltip>
</div>
<div slot='operate' slot-scope="row">
<span class="operate-text operate-delete" @click="deleteDevice(row.id)">{{ '删除 '}}</span>
</div>
</st-table>
<p class="table-title">{{'包含服务'}}</p>
<st-table
ref="serviceTable"
:options="serviceDefinitions"
:data="{
list: serviceTokenList,
total: servicTotal,
}"
:outerLoading="serviceLoadingStatus"
:pagination="false"
>
<div slot='nameSlot' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="row.name" placement="top">
<span>{{ simplify(row.name, 8) }}</span>
</el-tooltip>
</div>
<div slot='portSlot' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="row.port + ''" placement="top">
<span>{{ simplify(row.port, 6) }}</span>
</el-tooltip>
</div>
<div slot='codeSlot' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="row.potuid" placement="top">
<span>{{ simplify(row.potuid, 6) }}</span>
</el-tooltip>
<i class="iconfont icon-fuzhi icon-fuzhi-text" @click="copyText(row.potuid)"></i>
</div>
<div slot='descSlot' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="row.description" placement="top">
<span>{{ simplify(row.description, 10) }}</span>
</el-tooltip>
</div>
<div slot='operate' slot-scope="row">
<span class="operate-text" @click="seeServiceParams(row)">{{ '查看参数' }}</span>
<span class="operate-text" @click="sendReq(row)">{{ '发送请求' }}</span>
<span class="operate-text" @click="sendOrder(row)">{{ '发送指令' }}</span>
</div>
</st-table>
</div>
</div>
</div>
</div>
</template>
<script>
import browserStorage from '@/services/local-storage'
import Dialog from '@/helpers/dialog'
import validate from '@/components/seeta-ui/seeta-form/validator'
import { rTimeMin, copyText } from '@/utils/system.js'
import { getServiceDevice, deleteTag, addTag, deleteDevice } from '@/axios'
export default {
data() {
return {
// 当前页
pi: 0,
// 当前页size
ps: 10,
// 控制遮罩
loadingStatus: false,
serviceLoadingStatus: false,
// 搜索栏折叠
isCollapse: true,
time2: '',
// 表格数据
tokenList: [
],
inputVisible: false,
inputValue: '',
serviceTokenList: [
],
total: 1,
// 编辑和添加表单
form: {
},
serviceDefinitions: [
{
label: '服务',
type: 'slot',
slotName: 'nameSlot',
}, {
label: '编号',
type: 'slot',
slotName: 'codeSlot'
}, {
label: '端口',
type: 'slot',
slotName: 'portSlot'
}, {
label: '描述',
type: 'slot',
slotName: 'descSlot'
}, {
label: '操作',
type: 'slot',
slotName: 'operate',
width: 120
},
],
definitions: [
{
label: '编号',
type: 'slot',
slotName: 'codeSlot',
width: 100
}, {
label: '状态',
type: 'slot',
slotName: 'status',
statusColor: item => {
switch (item.state) {
case 1:
return '#67C23A'
case 2:
return '#F56C6C'
default:
return '#999999'
}
},
width: 90
}, {
label: '架构',
type: 'slot',
slotName: 'structureSlot'
}, {
label: '系统',
type: 'slot',
slotName: 'systemSlot'
}, {
label: 'IP',
type: 'slot',
slotName: 'ipSlot'
}, {
label: '注册时间',
type: 'slot',
slotName: 'registerTimeSlot',
width: 180
}, {
label: '标签',
type: 'slot',
slotName: 'tagsSlot',
width: 190
}, {
label: '服务',
type: 'slot',
slotName: 'servicesSlot',
width: 120
}, {
label: '操作',
type: 'slot',
slotName: 'operate',
},
],
/* 搜索栏条件 */
search: {
checkList: []
},
tagList: [{ label: '标签一', value: 0 }, { label: '标签二', value: 1 }, { label: '标签三', value: 2 }, { label: '标签四', value: 3 }],
serviceList: [{ label: '标签一', value: 0 }, { label: '标签二', value: 1 }, { label: '标签三', value: 2 }, { label: '标签四', value: 3 }],
currentDeviceId: '',
servicTotal: 0
}
},
computed: {
getServiceName() {
return item => {
return item.map(t1 => t1.name).join()
}
},
// 获取设备状态颜色
getStatusColor() {
return item => {
switch (item) {
case 1:
return '#67C23A'
case 2:
return '#F56C6C'
default:
return '#999999'
}
}
},
// 获取设备状态文字
getStatusText() {
return item => {
switch (item) {
case 1:
return '在线'
case 2:
return '异常'
default:
return '离线'
}
}
},
// 精简文字
simplify() {
return (item, length) => {
if (item && item.length > length) {
return item.substring(0, length) + '...'
}
return item
}
}
},
methods: {
rTimeMin,
copyText,
setDeviceServiceStoreInfo(deviceInfo, serviceInfo, routerTarget, tagIndex) {
this.$store.commit('changeCurrentDevice', deviceInfo)
this.$store.commit('changeCurrentService', serviceInfo)
if (tagIndex !== undefined) {
this.$store.commit('changeCurrentTagIndex', tagIndex)
}
this.$router.push({ name: routerTarget })
},
seeServiceParams(row) {
this.setDeviceServiceStoreInfo(row.deviceId, row, 'device-service', 0)
},
sendReq(row) {
this.setDeviceServiceStoreInfo(row.deviceId, row, 'device-service', 1)
},
sendOrder(row) {
this.setDeviceServiceStoreInfo(row.deviceId, row, 'device-service', 2)
},
async handleClose(row, tag) {
const res = await deleteTag({ name: tag })
this.getData()
},
showInput() {
this.inputVisible = true
this.$nextTick(_ => {
this.$refs.saveTagInput.$refs.input.focus()
})
},
async handleInputConfirm(row) {
const inputValue = this.inputValue
if (inputValue) {
const res = await addTag({
id: row.id,
tags: [inputValue]
})
this.getData()
}
this.inputVisible = false
this.inputValue = ''
},
collapseSearch() {
this.isCollapse = !this.isCollapse
this.$refs.vTable.clickCollapse()
this.$nextTick(() => {
const icon = [...document.getElementsByClassName('el-date-editor')]
icon.forEach(item => {
const img = document.createElement('img')
img.style.width = '14px'
img.style.height = '14px'
img.src = require('@assets/images/icon-rili.png')
item.appendChild(img)
})
})
},
reset() {
this.search = {
checkList: []
}
},
// 跳转到设备详情页面
detail(id) {
},
async deleteDevice(id) {
const confirmDelete = await Dialog.confirm('提示', { message: '确认删除设备?删除设备时,也会删除此设备上的所有服务,还会取消相应的参数模板和服务配置的参数。' })
if (!confirmDelete) return
const res = await deleteDevice({ deviceid: this.currentDeviceId })
if (res) {
this.$message({
message: '删除成功',
type: 'success'
})
}
},
async getData() {
const res = await getServiceDevice({ deviceid: this.currentDeviceId })
if (res && res.data && res.data.device) {
this.tokenList = [JSON.parse(JSON.stringify(res.data.device))]
this.serviceTokenList = JSON.parse(JSON.stringify(res.data.device.services))
this.serviceTokenList.forEach(item => {
if (this.tokenList && this.tokenList.length) {
item.deviceId = this.tokenList[0].deviceid
}
})
this.total = 1
this.servicTotal = res.data.device.services.length
} else {
this.tokenList = []
this.total = 0
this.serviceTokenList = []
this.servicTotal = 0
}
}
},
watch: {
// 监听route的改变进行pi ,ps的改变
'$route.query': {
handler(newName, oldName) {
},
deep: true,
}
},
mounted() {
if (this.$store.getters.currentDevice !== '') {
sessionStorage.setItem('currentDevice', this.$store.getters.currentDevice)
}
this.currentDeviceId = sessionStorage.getItem('currentDevice')
this.getData()
},
destroyed() {
},
components: {
}
}
</script>
<style lang="sass" scoped>
.service-item
margin-right: 10px
.page-nav
font-family: PingFangSC-Regular
font-size: 14px
color: #666666
letter-spacing: 0
padding: 26px 20px 20px
.search-title
margin-right: 10px
.clickable
cursor: pointer
.no-wrap
white-space: nowrap
.inline-div
display: inline-block
.circleStatus
margin-left: 6px
.icon-fuzhi-text
margin-left: 6px
color: #409EFF
cursor: pointer
.search-item
text-align: left
.search-item-margin
margin-right: 20px
.search-item:not(.search-item:nth-child(1))
margin-top: 14px
.collapse-btn
font-family: PingFangSC-Regular
font-size: 14px
color: #409EFF
.collapse-text
margin-right: 5px
.search-fields
height: 164px
width: 100%
display: flex !important
flex-direction: row
justify-content: space-between
.search-fields-collapse
max-height: 23px
.flex-left
display: flex
flex-direction: column
justify-content: space-between
.flex-right-nav
margin-left: -88px
display: flex
justify-content: space-between
flex-direction: column
.flex-right-content
display: flex
justify-content: flex-end
.check-title
font-family: PingFangSC-Regular
font-size: 14px
color: #333333
letter-spacing: 0
.operate-text
font-family: PingFangSC-Regular
font-size: 14px
color: #409EFF
margin-right: 20px
cursor: pointer
.operate-delete
color: rgb(245, 108, 108)
::v-deep .el-checkbox
margin-right: 15px
.el-checkbox__input
width: 14px
height: 14px
top: -1px
margin-right: 10px
.el-checkbox__label
padding-left: 0px
::v-deep .el-range-separator
font-family: PingFangSC-Regular
font-size: 14px
color: #333333
letter-spacing: 0
::v-deep .el-range-input
font-family: PingFangSC-Regular
font-size: 14px
color: #333333
letter-spacing: 0
&::placeholder
font-family: PingFangSC-Regular
font-size: 14px
color: #999999
letter-spacing: 0
::v-deep
& .el-table__expand-column .cell
padding: 0 20px !important
& .table-box .el-table th .cell, .table-box .el-table .el-table__body tr .cell
padding-left: 40px
& .el-table__expanded-cell .cell
padding-left: 48px !important
.input-new-tag, .button-new-tag
width: 90px
height: 28px
vertical-align: bottom
margin-top: 5px
.tagsItem
display: inline-block
white-space: normal
.table-label
width: 78px
height: 28px
margin: 5px 5px 0 0
.table-box
height: auto
::v-deep .el-table
max-height: fit-content !important
.el-table__body-wrapper.is-scrolling-none
max-height: fit-content !important
.table-title
text-align: left
font-family: PingFang-SC-Bold
font-size: 14px
color: #333333
margin: 14px 0
font-weight: bold
</style>
<template>
<div class="box">
<div class="wrapper">
<div class="content">
<div class="content-top-info">
<div class="list-item">
<span class="list-item-title">{{'服务编号:'}}</span>
<div class="list-item-content">
<span>{{currentService.potuid}}</span>
</div>
</div>
<div class="list-item">
<span class="list-item-title ak-sk">{{'AK/SK:'}}</span>
<div class="list-item-content">
<div>
<span>{{'AppKey:'}}</span>
<st-input width="240px" class="list-item-input" :value="currentService.appid" show-password></st-input>
</div>
<div>
<span>{{'Secret:'}}</span>
<st-input width="240px" class="list-item-input" :value="currentService.secretkey" show-password></st-input>
</div>
<!-- <div class="list-item-icon">
<i class="el-icon-view blue-text"></i>
</div> -->
</div>
</div>
<div class="list-item">
<span class="list-item-title param-template-text">{{'参数模板:'}}</span>
<div class="list-item-content select-tag">
<div class="tags">
<vuedraggable
class="wrapper"
:list="dynamicTags"
@end="endSort"
>
<transition-group>
<template v-for="(item) in dynamicTags" class="item">
<el-tag el-tag closable :key="item" @close="handleClose(item)">{{item}}</el-tag>
</template>
</transition-group>
</vuedraggable>
<!-- <template v-for="(item, index) in dynamicTags">
<el-tooltip :key="index" class="item" effect="dark" :content="item" placement="top" style="display: inline-block">
<div>
<el-tag>{{item.length > 4 ? item.slice(0, 3) + '...' : item}}</el-tag>
</div>
</el-tooltip>
</template> -->
<!-- <el-input
class="input-new-tag"
v-if="inputVisible"
v-model="inputValue"
ref="saveTagInput"
size="small"
@keyup.enter.native="handleInputConfirm"
@blur="handleInputConfirm"
>
</el-input> -->
<div class="tag-select">
<el-cascader
:show-all-levels="false"
:options="options"
clearable
v-if="inputVisible"
v-model="tagItem"
:props="{ checkStrictly: true, multiple: true }"
@visible-change="changeCascaderStatus"
>
</el-cascader>
<!-- <st-select
:options="options"
size="small"
150px"
clearable
v-if="inputVisible"
v-model="tagItem"
@change="addTag"
>
</st-select> -->
<el-button v-else class="button-new-tag" size="small" @click="showInput">+ 添加标签</el-button>
</div>
</div>
</div>
</div>
</div>
<div class="content-table">
<st-table
ref="vTable"
:options="definitions"
:data="{
list: tokenList,
total: total,
}"
:key="num"
:outerLoading="loadingStatus"
:pagination="false"
>
<div slot='fieldSlot' slot-scope="scope">
<template v-if="!scope.deleted">
<div v-if="!(scope.field && scope.field.ifEdit)" @click="changeStatus(scope, scope.index, 'field', true, 'text', scope.type.editEnable)" :class="{'pointer': scope.configurable !== 'noEdit'}">{{scope.field ? scope.field.value : ''}}</div>
<st-input ref="myInput" @change="v => { updateScope(scope, scope.index, v, 'field') }"
@blur="changeStatus(scope, scope.index, 'field', false, 'text', scope.type.editEnable)" @keyup.enter.native="changeStatus(scope, scope.index, 'field', false, 'text', scope.type.editEnable)" v-model="currentInput" v-else class="field-input"></st-input>
</template>
</div>
<div slot='typeSlot' slot-scope="scope">
<template v-if="!scope.deleted">
<div v-if="!(scope.type && scope.type.ifEdit)" @click="changeStatus(scope, scope.index, 'type', true, 'select', scope.type.editEnable)" :class="{'pointer': scope.type.editEnable}">{{scope.type ? scope.type.value : ''}}</div>
<st-select
:options="tagOptions"
size="small"
style="heigth: 50px;width: 200px"
v-model="scope.type.value"
v-else
@visible-change="status => { changeTypeStatus(scope.type, status) }"
@change="v => { changeTypeValue(v, scope.index) }"
>
</st-select>
</template>
</div>
<div slot='valueSlot' slot-scope="row">
<template v-if="!row.deleted">
<template v-if="row.value && row.value.valueType === 'text'">
<div v-if="!row.value.ifEdit" @click="changeStatus(row, row.index, 'value', true, 'text', row.value.editEnable)" class='pointer'>{{row.value.value}}</div>
<st-input v-else ref="myInput" @change="v => { updateScope(row, row.index, v, 'value') }" @blur="changeStatus(row, row.index, 'value', false, 'text', row.value.editEnable)"
@keyup.enter.native="changeStatus(row, row.index, 'value', false, 'text', row.value.editEnable)" v-model="currentInput" class="field-input"></st-input>
</template>
<template v-else-if="row.value && row.value.valueType === 'a'">
<a href="javascript:;" class="link-text" @click="linkToTable(row.value.value)" v-if="row.value.operate === 'text'">{{row.value.value}}</a>
<st-select
:options="tableOptions"
size="small"
style="heigth: 32px;width: 200px"
v-model="row.value.value"
v-else
@change="v => { updateScope(row, row.index, v, 'value') }"
@visible-change="status => { changeTableSelect(row.value, status) }"
>
</st-select>
<i class="el-icon-edit link-text i-margin-left" @click="changeToTable(row.value)" v-if="row.value.operate === 'text'"></i>
</template>
<template v-else-if="row.value && row.value.valueType === 'img'">
<p class="preview-text" v-if="row.value.value">
<span @click="choiceImg(row)" type="primary" style="cursor: pointer">{{getBlobSize(row.value.value)}}</span>
<input type="file" :ref="'selectFile' + row.index" @change="event => handleUpload(event, row.value, row, row.index)" style="display:none">
</p>
<p v-else>
<span @click="choiceImgNone(row)" type="primary" class="select-file-none">{{'Select File'}}</span>
<input type="file" :ref="'selectFile' + row.index + 'none'" @change="event => handleUpload(event, row.value, row, row.index)" style="display:none">
</p>
<span v-if='!ifBlobPreview(row.value.value) && row.value.value'>{{'(不可预览)'}}</span>
<el-image
class="preview-img"
v-if='ifBlobPreview(row.value.value)'
style="width: 42px; height: 28px"
:src="row.value.value"
:preview-src-list="getBlobimgUrlList(row.value.value)">
</el-image>
</template>
</template>
</div>
<div slot='operate' slot-scope="row">
<template v-if="!row.needBack && !row.needDelete">
<span>{{ '-' }}</span>
</template>
<template v-else>
<span v-if="row.needBack" class="operate-text span-margin-right" @click="backRow(row.index)">{{ '撤回' }}</span>
<span v-if="row.needDelete" class="operate-text operate-text-delete" @click="deleteRow(row.index)">{{ '删除' }}</span>
</template>
</div>
</st-table>
<div class="add" @click="addRow">
+ 添加
</div>
</div>
</div>
</div>
<div class="operate-area">
<el-divider></el-divider>
<div class="operate-bottom">
<st-button @click="cancleAll">取消</st-button>
<st-button @click="saveAll" class="operate-bottom-btn" type="primary">保存</st-button>
</div>
</div>
</div>
</template>
<script>
import { rTimeMin, copyText } from '@/utils/system.js'
import Dialog from '@/helpers/dialog'
import { getServiceParamter, getServiceDevice, setServiceParamter, getTagByServiceType, deleteTemplate, addTemplate, getTable } from '@/axios'
import { fileToBase64 } from '@/utils/typeConversion'
import vuedraggable from 'vuedraggable'
export default {
components: {
vuedraggable
},
computed: {
// 计算blob大小
getBlobSize() {
return item => {
return '24字节'
}
},
getParameterObjType() {
return item => {
if (JSON.stringify(item) === 'null') {
return 'null'
} else {
return typeof item
}
}
},
// 是否可预览
ifBlobPreview() {
return item => {
if (item.indexOf('data:image/jpeg;base64,') !== -1) {
return true
}
return false
}
},
// 获取图片封面
getBlobimgUrl() {
return item => {
return 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg'
}
},
// 获取图片列表
getBlobimgUrlList() {
return item => {
return [
item
]
}
},
// 获取设备状态颜色
getStatusColor() {
return item => {
switch (item) {
case 'online':
return '#67C23A'
case 'offline':
return '#999999'
default:
return '#F56C6C'
}
}
},
// 获取设备状态文字
getStatusText() {
return item => {
switch (item) {
case 'online':
return '在线'
case 'offline':
return '离线'
default:
return '异常'
}
}
},
// 精简文字
simplify() {
return (item, length) => {
if (item && item.length > length) {
return item.substring(0, length) + '...'
}
return item
}
}
},
data() {
return {
tagItem: '',
tagOptions: [{ label: 'blob', value: 'blob' }, { label: 'number', value: 'number' }, { label: 'string', value: 'string' }, { label: 'table', value: 'table' }],
dynamicTags: [],
inputVisible: false,
inputValue: [],
// tokenList: [
// { p1: { value: '小2', ifEdit: false }, p2: { value: '小2', ifEdit: false }, p3: { value: 'xxx', valueType: 'img', ifEdit: false }, index: 0, configurable: 'edit', editing: false },
// { p1: { value: '小3', ifEdit: false }, p2: { value: '小3', ifEdit: false }, p3: { value: 'fein_fe', valueType: 'a', ifEdit: false }, index: 1, configurable: 'edit', editing: false },
// { p1: { value: '小4', ifEdit: false }, p2: { value: '小4', ifEdit: false }, p3: { value: '122', valueType: 'text', ifEdit: false }, index: 2, configurable: 'edit', editing: false },
// ],
tokenList: [],
tokenListCopy: [],
deleteTokenListObj: {},
total: 0,
loadingStatus: false,
currentInput: '',
activeTab: 'getParams',
num: 0,
tabs: [
{
label: '查看参数',
name: 'getParams',
},
{
label: '发送请求',
name: 'sendRequest',
},
{
label: '发送指令',
name: 'sendOrder',
},
],
// definitions: [
// {
// label: '字段',
// type: 'slot',
// slotName: 'paramsSlot',
// }, {
// label: '类型',
// type: 'slot',
// slotName: 'typeSlot',
// }, {
// label: '值',
// type: 'slot',
// slotName: 'valueSlot'
// }, {
// label: '操作',
// type: 'slot',
// slotName: 'operate',
// },
// ],
imgUrl: 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg',
imgSrcList: [
'https://fuss10.elemecdn.com/8/27/f01c15bb73e1ef3793e64e6b7bbccjpeg.jpeg',
'https://fuss10.elemecdn.com/1/8e/aeffeb4de74e2fde4bd74fc7b4486jpeg.jpeg'
],
options: [],
definitions: [
{
label: '字段',
type: 'slot',
slotName: 'fieldSlot',
}, {
label: '类型',
type: 'slot',
slotName: 'typeSlot',
}, {
label: '值',
type: 'slot',
slotName: 'valueSlot',
}, {
label: '操作',
type: 'slot',
slotName: 'operate',
},
],
currentService: {},
// 存储撤回信息
backData: {},
// 存储表格信息
tableInfoList: [],
}
},
methods: {
rTimeMin,
changeToTable(row) {
row.operate = 'select'
this.$forceUpdate()
},
choiceImg(row) {
this.$refs['selectFile' + row.index].dispatchEvent(new MouseEvent('click'))
},
choiceImgNone(row) {
this.$refs['selectFile' + row.index + 'none'].dispatchEvent(new MouseEvent('click'))
},
async getTagByService() {
const targetObj = {}
const res = await getTagByServiceType({ service_name: this.currentService.name })
if (res && res.data.datas.length) {
res.data.datas.forEach(item => {
if (item.base === '') {
if (!targetObj[item.name]) {
targetObj[item.name] = {}
targetObj[item.name].value = []
}
targetObj[item.name].disabled = false
} else {
if (!targetObj[item.base]) {
targetObj[item.base] = {}
targetObj[item.base].disabled = true
targetObj[item.base].value = []
}
targetObj[item.base].value.push(item.name)
}
})
for (const i in targetObj) {
if (this.dynamicTags.indexOf(i) !== -1) {
targetObj[i].disabled = true
}
this.dynamicTags.forEach(n => {
const index = targetObj[i].value.indexOf(n)
if (index !== -1) {
targetObj[i].value.splice(index, 1)
}
})
}
const result = []
for (const j in targetObj) {
const item = {}
item.value = j
item.label = j
item.disabled = targetObj[j].disabled
if (targetObj[j].value.length) {
item.children = targetObj[j].value.map(item => {
return {
value: item,
label: item
}
})
}
result.push(item)
}
this.options = JSON.parse(JSON.stringify(result))
} else {
this.options = []
}
},
async handleUpload(event, row, scope, index) {
row.value = await fileToBase64(event.target.files[0])
// scope.editing = true
this.$set(this.tokenList, index, scope)
this.$set(this.tokenList[index], 'editing', true)
},
async endSort(evt) {
const res = await addTemplate({
templates: JSON.parse(JSON.stringify(this.dynamicTags)),
pots: [this.currentService.potuid]
})
this.getData()
},
async handleClose(tag) {
// this.dynamicTags.splice(this.dynamicTags.indexOf(tag), 1)
const res = await deleteTemplate({
templates: [tag],
pots: [this.currentService.potuid]
})
this.getData()
},
// 切换表格项内容
changeStatus(row, index, item, status, type, enable) {
// 不允许编辑的条目
if (!enable) {
return null
}
if (type === 'text') {
if (status) {
this.$set(this, 'currentInput', row[item].value)
} else {
row[item].value = this.currentInput
}
}
row[item].ifEdit = status
this.$set(this.tokenList, index, row)
this.$nextTick(() => {
this.$refs.myInput && this.$refs.myInput.$children[0].focus()
})
},
linkToTable(name) {
const currentTable = this.tableInfoList.filter(item => {
if (item.name === name) {
return true
}
})
this.$router.push({ path: '/data/edit', query: { name: name, columns: (currentTable[0].columns + '') } })
},
async changeCascaderStatus(status) {
if (!status) {
const target = this.tagItem.map(item => {
return item[item.length - 1]
})
this.dynamicTags = this.dynamicTags.concat(target)
const res = await addTemplate({
templates: JSON.parse(JSON.stringify(this.dynamicTags)),
pots: [this.currentService.potuid]
})
this.getData()
this.tagItem = ''
this.inputVisible = false
}
},
updateScope(row, index, value, property) {
const rowObject = { field: row.field.value, type: row.type.value, value: row.value.value }
rowObject[property] = value
const copyObject = { field: this.tokenListCopy[index].field.value, type: this.tokenListCopy[index].type.value, value: this.tokenListCopy[index].value.value + '' }
if (JSON.stringify(rowObject) === JSON.stringify(copyObject)) {
row.editing = false
} else {
row.editing = true
}
this.$set(this.tokenList, index, row)
},
showInput() {
this.inputVisible = true
this.getTagByService()
},
handleInputConfirm() {
const inputValue = this.inputValue
if (inputValue) {
this.dynamicTags.push(inputValue)
}
this.inputVisible = false
this.inputValue = ''
},
backRow(index) {
const row = this.tokenListCopy[index]
switch (row.type.value) {
case 'blob':
row.value.value = this.backParameter.binary[row.field.value]
break
case 'table':
row.value.value = this.backParameter.table[row.field.value]
break
default:
row.value.value = this.backParameter.scalars[row.field.value]
break
}
row.isBack = true
this.$set(this.tokenList, index, JSON.parse(JSON.stringify(row)))
},
disableInput() {
return false
},
async deleteRow(index) {
const confirmDelete = await Dialog.confirm('提示', { message: '确认删除?' })
if (!confirmDelete) return
this.tokenList[index].value.value = null
switch (this.tokenList[index].type.value) {
case 'blob':
this.deleteTokenListObj.binary[this.tokenList[index].field.value] = null
break
case 'table':
this.deleteTokenListObj.table[this.tokenList[index].field.value] = null
break
default:
this.deleteTokenListObj.scalars[this.tokenList[index].field.value] = null
break
}
this.tokenList.splice(index, 1)
this.tokenList.forEach((item, index) => {
item.index = index
})
},
addRow() {
const newRow = { field: { value: '', editEnable: true, ifEdit: false }, type: { value: 'string', editEnable: true, ifEdit: false }, value: { value: '', valueType: 'text', editEnable: true, ifEdit: false }, index: this.tokenList.length, configurable: 'add', editing: false, needDelete: true, isNew: true }
this.tokenList.push(newRow)
this.tokenListCopy = JSON.parse(JSON.stringify(this.tokenList))
},
async cancleAll() {
this.getData()
},
async getTableOptions() {
const res = await getTable({ pages: 0, pagesize: 10000000000 })
if (res && res.data && res.data.code === 0) {
this.tableOptions = res.data.data.tables.map(item => {
return {
label: item.name,
value: item.name,
}
})
this.tableInfoList = res.data.data.tables.map(item => {
return {
name: item.name,
columns: item.columns
}
})
}
},
filterFinalParameter(target, item) {
switch (item.type.value) {
case 'blob':
target.binary[item.field.value] = item.value.value
break
case 'table':
target.table[item.field.value] = item.value.value
break
default:
target.scalars[item.field.value] = item.value.value
break
}
},
async saveAll() {
const resultParameters = { binary: {}, scalars: {}, table: {} }
this.tokenList.forEach(item => {
if (item.editing && !item.isBack && !item.ifSelf && !item.isNew) {
this.filterFinalParameter(resultParameters, item)
} else if (item.isNew && !item.ifSelf) {
this.filterFinalParameter(resultParameters, item)
}
// self_parameter放在最后处理,覆盖掉parameter中的重名字段
if (item.ifSelf) {
this.filterFinalParameter(resultParameters, item)
}
})
for (const i in this.deleteTokenListObj.binary) {
resultParameters.binary[i] = null
}
for (const i in this.deleteTokenListObj.scalars) {
resultParameters.scalars[i] = null
}
for (const i in this.deleteTokenListObj.table) {
resultParameters.table[i] = null
}
const res = await setServiceParamter({
potuid: this.currentService.potuid,
appid: this.currentService.appid,
secretkey: this.currentService.secretkey,
parameters: resultParameters
})
this.getData()
this.getDeviceInfo()
},
changeTableSelect(row, status) {
if (!status) {
row.operate = 'text'
this.$forceUpdate()
}
},
changeTypeStatus(row, status) {
if (!status) {
row.ifEdit = false
this.$forceUpdate()
}
},
changeTypeValue(v, index) {
if (v === 'blob') {
this.$set(this.tokenList[index].value, 'valueType', 'img')
} else if (v === 'table') {
this.$set(this.tokenList[index].value, 'valueType', 'a')
this.$set(this.tokenList[index].value, 'operate', 'text')
} else {
this.$set(this.tokenList[index].value, 'valueType', 'text')
}
this.$set(this.tokenList[index].value, 'value', '')
this.$set(this.tokenList[index], 'editing', true)
},
handleSelfParameter(selfParam) {
if (!selfParam || JSON.stringify(selfParam) === '{}') {
return {}
}
const result = {}
result.selfBinaryObj = selfParam.binary ? selfParam.binary : {}
result.selfScalarsObj = selfParam.scalars ? selfParam.scalars : {}
result.selfTableObj = selfParam.table ? selfParam.table : {}
return result
},
handleOperateBtn(data) {
data.forEach(item => {
let ifDelete = false
if (item.ifSelf) {
if (item.field.value in this.backParameter.binary) {
item.needBack = true
ifDelete = true
}
if (item.field.value in this.backParameter.scalars) {
item.needBack = true
ifDelete = true
}
if (item.field.value in this.backParameter.table) {
item.needBack = true
ifDelete = true
}
if (!ifDelete) {
item.needDelete = true
}
}
})
},
// 查找需要撤回的数据
contrastParametr(data) {
if (!data.self_param || JSON.stringify(data.self_param) === '{}') {
return null
}
if (data.parameters && data.parameters.binary && data.self_param && data.self_param.binary) {
for (const i in data.parameters.binary) {
for (const j in data.self_param.binary) {
if (i === j) {
this.backParameter.binary[i] = data.parameters.binary[i]
}
}
}
}
if (data.parameters && data.parameters.scalars && data.self_param && data.self_param.scalars) {
for (const i in data.parameters.scalars) {
for (const j in data.self_param.scalars) {
if (i === j) {
this.backParameter.scalars[i] = data.parameters.scalars[i]
}
}
}
}
if (data.parameters && data.parameters.table && data.self_param && data.self_param.table) {
for (const i in data.parameters.table) {
for (const j in data.self_param.table) {
if (i === j) {
this.backParameter.table[i] = data.parameters.table[i]
}
}
}
}
},
async getDeviceInfo() {
const res = await getServiceDevice({ deviceid: this.currentService.deviceId })
// if (res && res.data) {
// res.data.device.services.forEach(item => {
// if(item.potuid === this.current.potuid) {
// sessionStorage.setItem('currentService', JSON.parse(JSON.stringify(item)))
// this.currentService = JSON.parse(JSON.stringify(item))
// }
// })
// }
},
async getData() {
let countIndex = 0
this.tokenList = []
this.deleteTokenListObj = {
binary: {},
table: {},
scalars: {}
}
this.backData = {}
this.backParameter = {
binary: {},
scalars: {},
table: {},
}
const res = await getServiceParamter({ potuid: this.currentService.potuid })
if (res && res.data && res.data.parameters) {
this.contrastParametr(res.data)
const binaryObj = res.data.parameters.binary
const scalarsObj = res.data.parameters.scalars
const tableObj = res.data.parameters.table
const selfParam = this.handleSelfParameter(JSON.parse(JSON.stringify(res.data.self_param)))
this.dynamicTags = JSON.parse(JSON.stringify(res.data.templates))
for (const key in binaryObj) {
this.tokenList.push({ field: { value: key, editEnable: false, ifEdit: false }, type: { value: 'blob', editEnable: false, ifEdit: false }, value: { value: binaryObj[key], valueType: 'img' }, index: countIndex, configurable: 'noEdit', editing: false })
countIndex++
}
for (const key in scalarsObj) {
this.tokenList.push({ field: { value: key, editEnable: false, ifEdit: false }, type: { value: this.getParameterObjType(scalarsObj[key]), editEnable: false, ifEdit: false }, value: { value: scalarsObj[key], valueType: 'text', editEnable: true, ifEdit: false }, index: countIndex, configurable: 'noEdit', editing: false })
countIndex++
}
for (const key in tableObj) {
this.tokenList.push({ field: { value: key, editEnable: false, ifEdit: false }, type: { value: 'table', editEnable: false, ifEdit: false }, value: { value: tableObj[key], valueType: 'a', operate: 'text' }, index: countIndex, configurable: 'noEdit', editing: false })
countIndex++
}
for (const key in selfParam.selfBinaryObj) {
this.tokenList.push({ field: { value: key, editEnable: false, ifEdit: false }, type: { value: 'blob', editEnable: false, ifEdit: false }, value: { value: selfParam.selfBinaryObj[key], valueType: 'img' }, index: countIndex, configurable: 'noEdit', editing: false, ifSelf: true })
countIndex++
}
for (const key in selfParam.selfScalarsObj) {
this.tokenList.push({ field: { value: key, editEnable: false, ifEdit: false }, type: { value: this.getParameterObjType(selfParam.selfScalarsObj[key]), editEnable: false, ifEdit: false }, value: { value: selfParam.selfScalarsObj[key], valueType: 'text', editEnable: true, ifEdit: false }, index: countIndex, configurable: 'noEdit', editing: false, ifSelf: true })
countIndex++
}
for (const key in selfParam.selfTableObj) {
this.tokenList.push({ field: { value: key, editEnable: false, ifEdit: false }, type: { value: 'table', editEnable: false, ifEdit: false }, value: { value: selfParam.selfTableObj[key], valueType: 'a', operate: 'text' }, index: countIndex, configurable: 'noEdit', editing: false, ifSelf: true })
countIndex++
}
} else {
this.tokenList = []
this.total = 0
}
this.handleOperateBtn(this.tokenList)
this.tokenListCopy = JSON.parse(JSON.stringify(this.tokenList))
},
},
mounted() {
if (JSON.stringify(this.$store.getters.currentService) !== '{}') {
sessionStorage.setItem('currentService', JSON.stringify(this.$store.getters.currentService))
}
this.currentService = JSON.parse(sessionStorage.getItem('currentService'))
this.getData()
this.getTableOptions()
}
}
</script>
<style lang="sass" scoped>
.select-file-none
display: inline-block
width: 75px
height: 26px
cursor: pointer
background: rgb(221, 221, 221)
text-align: center
line-height: 26px
.i-margin-left
margin-left: 5px
cursor: pointer
.span-margin-right
margin-right: 5px
.tag-select
// height: 32px
width: 220px
text-align: left
::v-deep.el-cascader
height: 32px
.el-input
height: 32px
.el-input__inner
height: 32px
margin-bottom: 11px
.el-input__suffix
line-height: 32px
.el-input__icon.el-icon-arrow-down
line-height: 32px
.index-max
height: 100%
width: 100%
position: absolute
left: 0
top: 0
opacity: 0
::v-deep .el-table__body-wrapper.is-scrolling-none
max-height: 224px !important
min-height: 100px
.table-box
::v-deep .el-table
max-height: none !important
.list-item:nth-child(1)
margin-top: 10px
.list-item:nth-child(2) .list-item-content
display: flex
.list-item
display: flex
margin-bottom: 10px
.el-tag
margin: 0 5px 5px 0
.tags .el-tag + .el-tag
margin-left: 0
.list-item-title
margin-right: 20px
min-width: 70px
font-family: PingFangSC-Regular
font-size: 14px
color: #666666
letter-spacing: 0
.list-item-content
max-height: 74px
overflow: auto
font-family: PingFangSC-Regular
font-size: 14px
color: #333333
letter-spacing: 0
.tags
display: flex
flex-wrap: wrap
.select-tag
max-height: none
overflow: visible
.list-item-input
margin-right: 20px
.list-item-icon
display: flex
align-items: center
& > i
cursor: pointer
.operate-area
margin-top: 5px
flex: 1 0 0
overflow: visible
height: 60px
.operate-bottom
height: calc(100% - 1px)
display: flex
justify-content: flex-end
align-items: center
.el-divider
margin: 0 0
width: calc( 100% + 40px )
position: relative
left: -20px
.add
cursor: pointer
margin-top: 3px
width: 100%
height: 32px
line-height: 32px
border: 1px dashed #D7DAE0
border-radius: 2px
&:hover
background-color: #ecf5ff
color: #409EFF
.box
height: 100%
display: flex
flex-direction: column
justify-content: space-between
min-height: 563px
.wrapper
height: calc(100% - 60px)
display: flex
flex-direction: column
.tags
.el-tag + .el-tag
margin-left: 10px
.button-new-tag
margin-left: 10px
height: 32px
line-height: 30px
padding-top: 0
padding-bottom: 0
.input-new-tag
width: 90px
margin-left: 10px
vertical-align: bottom
.blue-text
color: #409EFF
.link-text, .operate-text
font-family: PingFangSC-Regular
font-size: 14px
color: #409EFF
.operate-text
cursor: pointer
.operate-text-none
color: #333333
.operate-text-delete
color: #F56C6C
.preview-text
position: relative
line-height: 28px
display: inline-block
.preview-img
vertical-align: bottom
margin-left: 10px
::v-deep .any-slot
width: 100%
height: 100%
div
min-height: 20px
.pointer
cursor: pointer
.field-input
width: 200px !important
height: 28px
::v-deep .el-input__inner
height: 28px
.field-select
width: 200px !important
height: 28px
.ak-sk
line-height: 32px
.param-template-text
line-height: 32px
::v-deep .el-tooltip
text-align: left
</style>
<template>
<div class="box">
<div class="wrapper">
<div class="content">
<div class="content-item">
<span class="content-item-title">{{'服务参数:'}}</span>
<div class="content-table">
<st-table
ref="vTable"
:options="definitions"
:data="{
list: tokenList,
total: total,
}"
:outerLoading="loadingStatus"
:pagination="false"
>
<div slot='nameSlot' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="row.name" placement="top">
<span>{{ simplify(row.name, 16) }}</span>
</el-tooltip>
</div>
<div slot='potuidSlot' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="row.potuid" placement="top">
<span>{{ simplify(row.potuid, 8) }}</span>
</el-tooltip>
</div>
<div slot='portSlot' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="row.port + ''" placement="top">
<span>{{ simplify(row.port, 6) }}</span>
</el-tooltip>
</div>
<div slot='description' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="row.description" placement="top">
<span>{{ simplify(row.description, 16) }}</span>
</el-tooltip>
</div>
<div slot='operate'>
<span class="operate-text">{{ '-'}}</span>
</div>
</st-table>
</div>
</div>
<div class="content-item">
<span class="content-item-title">{{'指令:'}}</span>
<st-input type="textarea" placeholder="请输入Json" class="content-item-one" v-model="commandContent"></st-input>
</div>
</div>
<st-button type="primary" width="80px" class="sendBtn" :loading="buttonLoading" @click="send">{{'发送'}}</st-button>
</div>
</div>
</template>
<script>
import { rTimeMin, copyText } from '@/utils/system.js'
import { postServiceCommand } from '@/axios'
export default {
computed: {
// 获取设备状态颜色
getStatusColor() {
return item => {
switch (item) {
case 'online':
return '#67C23A'
case 'offline':
return '#999999'
default:
return '#F56C6C'
}
}
},
// 获取设备状态文字
getStatusText() {
return item => {
switch (item) {
case 'online':
return '在线'
case 'offline':
return '离线'
default:
return '异常'
}
}
},
// 精简文字
simplify() {
return (item, length) => {
if (item && item.length > length) {
return item.substring(0, length) + '...'
}
return item
}
}
},
data() {
return {
commandContent: '',
buttonLoading: false,
dynamicTags: ['标签一', '标签二', '标签三'],
inputVisible: false,
inputValue: '',
tokenList: [],
total: 0,
loadingStatus: false,
activeTab: 'getParams',
tabs: [
{
label: '查看参数',
name: 'getParams',
},
{
label: '发送请求',
name: 'sendRequest',
},
{
label: '发送指令',
name: 'sendOrder',
},
],
definitions: [
{
label: '服务',
type: 'slot',
slotName: 'nameSlot',
}, {
label: '编号',
type: 'slot',
slotName: 'potuidSlot',
}, {
label: '端口',
type: 'slot',
slotName: 'portSlot',
}, {
label: '描述',
type: 'slot',
slotName: 'description'
}, {
label: '操作',
type: 'slot',
slotName: 'operate'
}
],
}
},
mounted() {
this.getData()
},
methods: {
rTimeMin,
async send() {
const currentService = JSON.parse(sessionStorage.getItem('currentService'))
this.buttonLoading = true
const res = await postServiceCommand({
pots: [currentService.potuid],
command: JSON.parse(this.commandContent)
})
this.buttonLoading = false
if (res && res.data) {
// this.resValue = res.data
}
},
async getData() {
const currentService = JSON.parse(sessionStorage.getItem('currentService'))
this.tokenList = [{
name: currentService.name,
potuid: currentService.potuid,
port: currentService.port,
description: currentService.description,
}]
this.total = 1
},
handleClose(tag) {
this.dynamicTags.splice(this.dynamicTags.indexOf(tag), 1)
},
showInput() {
this.inputVisible = true
this.$nextTick(_ => {
this.$refs.saveTagInput.$refs.input.focus()
})
},
handleInputConfirm() {
const inputValue = this.inputValue
if (inputValue) {
this.dynamicTags.push(inputValue)
}
this.inputVisible = false
this.inputValue = ''
}
}
}
</script>
<style lang="sass" scoped>
::v-deep .el-table__body-wrapper.is-scrolling-none
max-height: 224px !important
.table-box
::v-deep .el-table
max-height: none !important
.box
height: 100%
display: flex
flex-direction: column
justify-content: space-between
min-height: 563px
.wrapper
height: calc(100% - 60px)
display: flex
flex-direction: column
.content-item
margin-bottom: 24px
display: flex
.content-item-one
width: 609px !important
height: 100px
::v-deep.el-textarea__inner
font-size: 14px
color: #333
font-family: PingFangSC-Regular, PingFang SC
font-weight: 400
.content-item-title
margin: auto 0
width: 108px
.content-table
width: calc(100% - 108px)
.blue-text
color: #409EFF
.sendBtn
margin-left: 108px
</style>
<template>
<div class="box">
<div class="wrapper">
<div class="content">
<div class="content-item">
<span class="content-item-title service-params">{{'服务参数:'}}</span>
<div class="content-table">
<st-table
ref="vTable"
:options="definitions"
:data="{
list: tokenList,
total: total,
}"
:outerLoading="loadingStatus"
:pagination="false"
>
<div slot='nameSlot' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="row.name" placement="top">
<span>{{ simplify(row.name, 16) }}</span>
</el-tooltip>
</div>
<div slot='potuidSlot' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="row.potuid" placement="top">
<span>{{ simplify(row.potuid, 8) }}</span>
</el-tooltip>
</div>
<div slot='portSlot' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="row.port + ''" placement="top">
<span>{{ simplify(row.port, 6) }}</span>
</el-tooltip>
</div>
<div slot='description' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="row.description" placement="top">
<span>{{ simplify(row.description, 16) }}</span>
</el-tooltip>
</div>
<div slot='operate'>
<span class="operate-text">{{ '-'}}</span>
</div>
</st-table>
</div>
</div>
<div class="content-item">
<span class="content-item-title">{{'请求:'}}</span>
<st-select
size="small"
width="200px"
class="content-select"
:options="requestList"
v-model="requestType"
>
</st-select>
<st-input width="400px" placeholder="输入URL" class="content-item-url" v-model="requestUrl"></st-input>
<st-button type="primary" width="80px" @click="send" :loading="buttonLoading">{{'发送'}}</st-button>
</div>
<div class="content-item">
<span class="content-item-title">{{'Header:'}}</span>
<div class="content-table-header">
<st-table
class="headerTable"
ref="headerTable"
:options="headDefinitions"
:data="{
list: headTokenList,
}"
:pagination="false"
>
<div slot='keySlot' slot-scope="scope">
<template>
<div v-if="!(scope.key && scope.key.ifEdit)" @click="changeStatus(scope, scope.index, 'key', true)" class="pointer">{{scope.key ? scope.key.value : ''}}</div>
<st-input ref="myInput" @change="updateScope(scope, scope.index)" @blur="changeStatus(scope, scope.index, 'key', false)" @keyup.enter.native="changeStatus(scope, scope.index, 'key', false)" v-model="currentInput" v-else class="field-input"></st-input>
</template>
</div>
<div slot='valueSlot' slot-scope="scope">
<template>
<div v-if="!(scope.value && scope.value.ifEdit)" @click="changeStatus(scope, scope.index, 'value', true)" class="pointer">{{scope.value ? scope.value.value : ''}}</div>
<st-input ref="myInput" @change="updateScope(scope, scope.index)" @blur="changeStatus(scope, scope.index, 'value', false)" @valueup.enter.native="changeStatus(scope, scope.index, 'value', false)" v-model="currentInput" v-else class="field-input"></st-input>
</template>
</div>
</st-table>
<div class="add" @click="addRow">
+ 添加
</div>
</div>
</div>
<div class="content-item">
<span class="content-item-title">{{'Body:'}}</span>
<st-input v-model="bodyValue" type="textarea" placeholder="请输入" class="content-item-body"></st-input>
</div>
<div class="content-item">
<span class="content-item-title">{{'Response:'}}</span>
<st-input v-model="resValue" type="textarea" placeholder="请输入" class="content-item-body"></st-input>
</div>
</div>
</div>
</div>
</template>
<script>
import { rTimeMin, copyText } from '@/utils/system.js'
import { postServiceRequest } from '@/axios'
export default {
computed: {
// 获取设备状态颜色
getStatusColor() {
return item => {
switch (item) {
case 'online':
return '#67C23A'
case 'offline':
return '#999999'
default:
return '#F56C6C'
}
}
},
// 获取设备状态文字
getStatusText() {
return item => {
switch (item) {
case 'online':
return '在线'
case 'offline':
return '离线'
default:
return '异常'
}
}
},
// 精简文字
simplify() {
return (item, length) => {
if (item && item.length > length) {
return item.substring(0, length) + '...'
}
return item
}
}
},
mounted() {
this.getData()
},
data() {
return {
bodyValue: '',
resValue: '',
currentInput: '',
dynamicTags: ['标签一', '标签二', '标签三'],
inputVisible: false,
inputValue: '',
tokenList: [],
headDefinitions: [
{
label: '键',
type: 'slot',
slotName: 'keySlot'
},
{
label: '值',
type: 'slot',
slotName: 'valueSlot'
}
],
// headTokenList: [
// { key: { value: 'A', ifEdit: false }, value: { value: 'B', ifEdit: false } },
// { key: { value: 'C', ifEdit: false }, value: { value: 'D', ifEdit: false } },
// { key: { value: 'E', ifEdit: false }, value: { value: 'F', ifEdit: false } },
// { key: { value: 'E', ifEdit: false }, value: { value: 'F', ifEdit: false } },
// { key: { value: 'E', ifEdit: false }, value: { value: 'F', ifEdit: false } },
// { key: { value: 'E', ifEdit: false }, value: { value: 'F', ifEdit: false } },
// { key: { value: 'E', ifEdit: false }, value: { value: 'F', ifEdit: false } },
// { key: { value: 'E', ifEdit: false }, value: { value: 'F', ifEdit: false } },
// ],
headTokenList: [],
total: 0,
loadingStatus: false,
activeTab: 'getParams',
tabs: [
{
label: '查看参数',
name: 'getParams',
},
{
label: '发送请求',
name: 'sendRequest',
},
{
label: '发送指令',
name: 'sendOrder',
},
],
definitions: [
{
label: '服务',
type: 'slot',
slotName: 'nameSlot',
}, {
label: '编号',
type: 'slot',
slotName: 'potuidSlot',
}, {
label: '端口',
type: 'slot',
slotName: 'portSlot',
}, {
label: '描述',
type: 'slot',
slotName: 'description'
}, {
label: '操作',
type: 'slot',
slotName: 'operate',
},
],
requestList: [
{ label: 'GET', value: 'GET' },
{ label: 'POST', value: 'POST' },
],
requestType: '',
requestUrl: '',
buttonLoading: false
}
},
methods: {
rTimeMin,
async send() {
this.buttonLoading = true
const currentService = JSON.parse(sessionStorage.getItem('currentService'))
const headers = this.headTokenList.map(item => {
return {
keyname: item.key.value,
keyvalue: item.value.value.trim()
}
})
let body
try {
body = JSON.parse(this.bodyValue)
} catch (e) {
this.$message.error('请输入JSON格式的Body数据')
this.buttonLoading = false
return null
}
const res = await postServiceRequest({
potuid: currentService.potuid,
method: this.requestType,
url: this.requestUrl,
headers: headers,
body: body
})
if (res && res.data) {
this.resValue = JSON.stringify(res.data)
}
this.buttonLoading = false
},
handleClose(tag) {
this.dynamicTags.splice(this.dynamicTags.indexOf(tag), 1)
},
showInput() {
this.inputVisible = true
this.$nextTick(_ => {
this.$refs.saveTagInput.$refs.input.focus()
})
},
handleInputConfirm() {
const inputValue = this.inputValue
if (inputValue) {
this.dynamicTags.push(inputValue)
}
this.inputVisible = false
this.inputValue = ''
},
// 切换表格项内容
changeStatus(row, index, item, status) {
if (status) {
this.$set(this, 'currentInput', row[item].value)
} else {
row[item].value = this.currentInput
}
row[item].ifEdit = status
this.$set(this.headTokenList, index, row)
this.$nextTick(() => {
this.$refs.myInput && this.$refs.myInput.$children[0].focus()
})
},
updateScope(row, index) {
row.editing = true
this.$set(this.headTokenList, index, row)
},
addRow() {
const newRow = { key: { value: '', ifEdit: false }, value: { value: '', ifEdit: false } }
this.headTokenList.push(newRow)
},
async getData() {
const currentService = JSON.parse(sessionStorage.getItem('currentService'))
this.tokenList = [{
name: currentService.name,
potuid: currentService.potuid,
port: currentService.port,
description: currentService.description,
}]
this.total = 1
}
}
}
</script>
<style lang="sass" scoped>
.service-params
::v-deep .el-table__body-wrapper.is-scrolling-none
max-height: 224px !important
.table-box
height: auto
::v-deep .el-table
max-height: none !important
.box
height: 100%
display: flex
flex-direction: column
justify-content: space-between
min-height: 563px
.wrapper
height: calc(100% - 60px)
display: flex
flex-direction: column
.content-item
margin-bottom: 24px
display: flex
.content-table-header
width: 610px
.content-select
margin-right: 10px
.content-item-url
margin-right: 10px
width: 400px !important
height: 32px
.content-item-body
width: 609px !important
height: 100px
::v-deep.el-textarea__inner
font-size: 14px
color: #333
font-family: PingFangSC-Regular, PingFang SC
font-weight: 400
.content-item-title
margin: 0 0
width: 108px
.content-table
width: calc(100% - 108px)
.blue-text
color: #409EFF
.sendBtn
margin-left: 108px
.field-input
width: 200px !important
height: 28px
::v-deep .el-input__inner
height: 28px
.headerTable
::v-deep.el-table__row
height: 48px
.add
cursor: pointer
margin-top: 16px
width: 100%
height: 32px
line-height: 32px
border: 1px dashed #D7DAE0
border-radius: 2px
&:hover
background-color: #ecf5ff
color: #409EFF
.pointer
min-height: 28px
min-width: 80px
</style>
<template>
<div class="data-list-common flex column main-content flex-1">
<div class="header">
<span class="title">{{'设备列表'}}</span>
</div>
<div class="page-nav">
<div class="page-nav-title">
<span>{{$store.getters.currentService.serviceName}}</span>
</div>
<st-table
ref="vTable"
:options="definitions"
:data="{
list: tokenList,
total: total,
}"
:outerLoading="loadingStatus"
:pagination="false"
>
<div slot='codeSlot' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="row.deviceid" placement="top">
<span>{{ simplify(row.deviceid, 3) }}</span>
</el-tooltip>
<i class="iconfont icon-fuzhi icon-fuzhi-text" @click="copyText(row.deviceid)"></i>
</div>
<div slot='status' slot-scope="row" class="status">
<span class="circleStatus" :style="{color: getStatusColor(row.state)}">{{ getStatusText(row.state) }}</span>
</div>
<div slot='structureSlot' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="row.structure" placement="top">
<span>{{ simplify(row.structure, 6) }}</span>
</el-tooltip>
</div>
<div slot='registerTimeSlot' slot-scope="row">
<span>{{ (row.register_date) }}</span>
</div>
<div slot='tagsSlot' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="row.tags ? row.tags.join('、') : ''" placement="top">
<!-- 必须要套一层 -->
<div>
<template v-for="(item, index) in row.tags">
<el-tag v-if="[0, 1].indexOf(index) !== -1" :key="index" class="label label-primary">{{ simplify(item, 3) }}</el-tag>
</template>
<span v-if="(row.tags && row.tags.length) > 10">共: {{(row.tags && row.tags.length) ? row.tags.length : 0}} 条</span>
</div>
</el-tooltip>
</div>
<div slot='servicesSlot' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="getServiceName(row.services)" placement="top">
<!-- 必须要套一层 -->
<div>
<template v-for="(item, index) in row.services">
<span v-if="[0, 1, 2].indexOf(index) !== -1" :key="index" class="service-item">{{ simplify(item.name, 4) }}</span>
</template>
<span v-if="(row.services && row.services.length) > 10">共: {{(row.services && row.services.length) ? row.services.length : 0}} 条</span>
</div>
</el-tooltip>
</div>
<div slot='systemSlot' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="row.system" placement="top">
<span>{{ simplify(row.system, 6) }}</span>
</el-tooltip>
</div>
<div slot='operate' slot-scope="row">
<span class="operate-text" @click="detail(row.deviceid)">{{'详情'}}</span>
</div>
</st-table>
</div>
<div class="page-content">
<div class="table-list">
<st-tabs :tabs="tabs" v-model="activeTab" @tab-click="changeTab">
<template v-slot:[activeTab]>
<components :is="activeTab" ref="dataTable"></components>
</template>
</st-tabs>
</div>
</div>
</div>
</template>
<script>
import getParams from './components/GetParams.vue'
import sendRequest from './components/SendRequest.vue'
import sendOrder from './components/SendOrder.vue'
import { rTimeMin, copyText } from '@/utils/system.js'
import { getService, getServiceDevice } from '@/axios'
export default {
components: {
getParams,
sendRequest,
sendOrder
},
computed: {
getServiceName() {
return item => {
return item.map(t1 => t1.name).join()
}
},
// 获取设备状态颜色
getStatusColor() {
return item => {
switch (item) {
case 1:
return '#67C23A'
case 2:
return '#F56C6C'
default:
return '#999999'
}
}
},
// 获取设备状态文字
getStatusText() {
return item => {
switch (item) {
case 1:
return '在线'
case 2:
return '异常'
default:
return '离线'
}
}
},
// 精简文字
simplify() {
return (item, length) => {
if (item && item.length > length) {
return item.substring(0, length) + '...'
}
return item
}
}
},
data() {
return {
tokenList: [
],
total: 0,
loadingStatus: false,
activeTab: 'getParams',
tabs: [
{
label: '查看参数',
name: 'getParams',
},
{
label: '发送请求',
name: 'sendRequest',
},
{
label: '发送指令',
name: 'sendOrder',
},
],
definitions: [
{
label: '编号',
type: 'slot',
slotName: 'codeSlot',
}, {
label: '状态',
type: 'slot',
slotName: 'status',
statusColor: item => {
switch (item.state) {
case 1:
return '#67C23A'
case 2:
return '#F56C6C'
default:
return '#999999'
}
}
}, {
label: '架构',
type: 'slot',
slotName: 'structureSlot'
}, {
label: '系统',
type: 'slot',
slotName: 'systemSlot'
}, {
label: 'IP',
render: 'ip'
}, {
label: '注册时间',
type: 'slot',
slotName: 'registerTimeSlot',
width: 145
}, {
label: '标签',
type: 'slot',
slotName: 'tagsSlot',
width: 95
}, {
label: '服务',
type: 'slot',
slotName: 'servicesSlot',
width: 95
}, {
label: '操作',
type: 'slot',
slotName: 'operate',
},
],
currentDeviceId: '',
}
},
methods: {
rTimeMin,
copyText,
changeTab() {
let tagIndex = 0
if (this.activeTab) {
switch (this.activeTab) {
case 'getParams':
tagIndex = 0
break
case 'sendRequest':
tagIndex = 1
break
case 'sendOrder':
tagIndex = 2
break
}
}
this.$store.commit('changeCurrentTagIndex', tagIndex)
},
async getServiceParams() {
const res = await getServiceParams(this.serviceId)
},
async getData() {
const res = await getServiceDevice({ deviceid: this.currentDeviceId })
if (res && res.data && res.data.device) {
this.tokenList = [JSON.parse(JSON.stringify(res.data.device))]
this.total = 1
} else {
this.tokenList = []
this.total = 0
}
},
// 跳转到设备详情页面
detail(deviceid) {
this.$store.commit('changeCurrentDevice', deviceid)
this.$router.push({ name: 'device-detail' })
},
},
mounted() {
if (this.$store.getters.currentDevice !== '') {
sessionStorage.setItem('currentDevice', this.$store.getters.currentDevice)
}
if (sessionStorage.getItem('currentTagIndex')) {
this.$store.commit('changeCurrentTagIndex', +sessionStorage.getItem('currentTagIndex'))
}
this.currentTagIndex = +sessionStorage.getItem('currentTagIndex')
switch (this.currentTagIndex) {
case 0:
this.activeTab = 'getParams'
break
case 1:
this.activeTab = 'sendRequest'
break
case 2:
this.activeTab = 'sendOrder'
break
}
this.currentDeviceId = sessionStorage.getItem('currentDevice')
this.getData()
},
}
</script>
<style lang="sass" scoped>
.service-item
margin-right: 20px
.circleStatus
margin-left: 6px
.icon-fuzhi-text
margin-left: 6px
color: #409EFF
cursor: pointer
.operate-text
font-family: PingFangSC-Regular
font-size: 14px
color: #409EFF
margin-right: 20px
cursor: pointer
.page-nav
flex-direction: column
.table-box
width: 100%
::v-deep .el-table
max-height: fit-content !important
.page-nav-title
text-align: left
margin-bottom: 10px
font-family: PingFangSC-Regular, 微软雅黑
font-size: 14px
color: #333
font-weight: bold
.page-content
padding-bottom: 0px
margin-top: 22px
flex: 1 0 0
overflow-y: visible
overflow-x: hidden
.page-nav
::v-deep.el-table__body-wrapper
max-height: none !important
::v-deep.pagination
margin-top: 0
margin-bottom: 0
.table-list
flex: 1 0 0 !important
overflow: visible !important
.el-tabs
height: 100%
display: -webkit-box
display: -ms-flexbox
display: flex
-webkit-box-orient: vertical
-webkit-box-direction: normal
-ms-flex-direction: column
flex-direction: column
::v-deep.el-tabs__content
flex: 1 0 0
overflow: visible
.el-tab-pane
height: 100%
overflow: visible
</style>
<template>
<div>
<div class="data-list-common flex column main-content flex-1">
<div class="header">
<span class="title">{{'设备列表'}}</span>
</div>
<div class="page-nav">
<div class="search-fields" :class="{'search-fields-collapse': isCollapse}">
<div class="flex-left">
<div class="search-item">
<span class="search-title">状态:</span>
<el-checkbox-group :max="1" v-model="search.checkList" class="inline-div" @change="handleChangeSearch">
<el-checkbox :label="1" class="check-title">在线</el-checkbox>
<el-checkbox :label="0" class="check-title">离线</el-checkbox>
<el-checkbox :label="2" class="check-title">异常</el-checkbox>
</el-checkbox-group>
</div>
<div v-if="!isCollapse">
<div class="search-item">
<span class="search-title">架构:</span>
<st-input :width="'240px'" class="search-item-margin" v-model="search.structure" @change="handleChangeSearch"></st-input>
<span class="search-title">系统:</span>
<st-input :width="'240px'" class="search-item-margin" v-model="search.system" @change="handleChangeSearch"></st-input>
<span class="search-title">IP:</span>
<st-input :width="'240px'" :class="{'error-border': ifBorder}" v-model="search.ip" @change="handleIpChangeSearch"></st-input>
</div>
<div class="search-item no-wrap">
<span class="search-title">注册时间:</span>
<el-date-picker
class="date-picker search-item-margin"
unlink-panels
:default-time="['00:00:00', '23:59:59']"
type="datetimerange"
format="yyyy-MM-dd HH:mm"
value-format="yyyy-MM-dd HH:mm:ss"
size="small"
style="padding-top:2px"
prefix-icon=' '
range-separator="至"
start-placeholder="选择时间"
v-model="search.registerTime"
end-placeholder="选择时间"
suffix-icon="el-icon-date"
@change="handleChangeSearch"
>
</el-date-picker>
<span class="search-title">上线时间:</span>
<el-date-picker
v-model="search.onlineTime"
class="date-picker search-item-margin"
unlink-panels
:default-time="['00:00:00', '23:59:59']"
type="datetimerange"
format="yyyy-MM-dd HH:mm"
value-format="yyyy-MM-dd HH:mm:ss"
size="small"
style="padding-top:2px"
prefix-icon=' '
range-separator="至"
start-placeholder="选择时间"
end-placeholder="选择时间"
@change="handleChangeSearch"
>
</el-date-picker>
</div>
<div class="search-item">
<span class="search-title">标签:</span>
<st-select
size="small"
width="240px"
class="contents"
multiple
filterable
:options="tagList"
v-model="search.tags"
@change="handleChangeSearch"
clearable
>
</st-select>
<span class="search-title">服务:</span>
<st-select
size="small"
width="240px"
class="contents"
multiple
filterable
:options="serviceList"
v-model="search.services"
@change="handleChangeSearch"
clearable
>
</st-select>
</div>
</div>
</div>
<div class="flex-right-nav">
<span class="collapse-btn" :class="{'middle-collapse-btn': isCollapse}">
<span class="collapse-text">{{isCollapse ? '展开' : '收起筛选'}}</span>
<i :class="isCollapse ? 'el-icon-arrow-right' : 'el-icon-arrow-up'" class="clickable" @click="collapseSearch"></i>
</span>
<st-button v-if="!isCollapse" @click="reset">重置</st-button>
</div>
</div>
</div>
<div class="page-content">
<!-- <div class="content-header flex-right-content">
<nameFilter
placeholder="请输入搜索内容"
@startSearch="startSearch">
</nameFilter>
</div> -->
<div class="table-list">
<div class="list-content">
<st-table
ref="vTable"
:options="definitions"
:data="{
list: tokenList,
total: total,
}"
:outerLoading="loadingStatus"
:doubleTable="true"
:childOptions="childDefinitions"
>
<div slot='codeSlot' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="row.deviceid" placement="top">
<span>{{ simplify(row.deviceid, 3) }}</span>
</el-tooltip>
<i class="iconfont icon-fuzhi icon-fuzhi-text" @click="copyText(row.deviceid)"></i>
</div>
<div slot='status' slot-scope="row" class="status">
<span class="circleStatus" :style="{color: getStatusColor(row.state)}">{{ getStatusText(row.state) }}</span>
</div>
<div slot='structureSlot' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="row.structure" placement="top">
<span>{{ simplify(row.structure, 6) }}</span>
</el-tooltip>
</div>
<div slot='registerTimeSlot' slot-scope="row">
<span>{{ (row.register_date) }}</span>
</div>
<div slot='tagsSlot' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="row.tags ? row.tags.join('、') : ''" placement="top">
<!-- 必须要套一层 -->
<div>
<template v-for="(item, index) in row.tags">
<el-tag v-if="[0, 1].indexOf(index) !== -1" :key="index" class="label label-primary tag-label">{{ simplify(item, 4) }}</el-tag>
</template>
<span v-if="(row.tags && row.tags.length) > 10">共: {{(row.tags && row.tags.length) ? row.tags.length : 0}} 条</span>
</div>
</el-tooltip>
</div>
<div slot='servicesSlot' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="getServiceName(row.services)" placement="top">
<!-- 必须要套一层 -->
<div>
<template v-for="(item, index) in row.services">
<span v-if="[0, 1, 2].indexOf(index) !== -1" :key="index" class="service-item">{{ simplify(item.name, 4) }}</span>
</template>
<span v-if="(row.services && row.services.length) > 10">共: {{(row.services && row.services.length) ? row.services.length : 0}} 条</span>
</div>
</el-tooltip>
</div>
<div slot='systemSlot' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="row.system" placement="top">
<span>{{ simplify(row.system, 7) }}</span>
</el-tooltip>
</div>
<div slot='operate' slot-scope="row">
<span class="operate-text" @click="detail(row.deviceid)">{{ '详情 '}}</span>
</div>
<!-- eslint-disable-next-line -->
<div slot='childServiceSlot' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="row.structure" placement="top">
<span>{{ simplify(row.name, 7) }}</span>
</el-tooltip>
</div>
<div slot='childCodeSlot' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="row.potuid" placement="top">
<span>{{ simplify(row.potuid, 15) }}</span>
</el-tooltip>
</div>
<div slot='portSlot' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="row.port + ''" placement="top">
<span>{{ simplify(row.port, 6) }}</span>
</el-tooltip>
</div>
<div slot='descSlot' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="row.description" placement="top">
<span>{{ simplify(row.description, 15) }}</span>
</el-tooltip>
</div>
<div slot='childOperate' slot-scope="row">
<span class="operate-text" @click="seeServiceParams(row)">{{ '查看参数' }}</span>
<span class="operate-text" @click="sendReq(row)">{{ '发送请求' }}</span>
<span class="operate-text" @click="sendOrder(row)">{{ '发送指令' }}</span>
</div>
</st-table>
</div>
</div>
</div>
</div>
</template>
<script>
import browserStorage from '@/services/local-storage'
import Dialog from '@/helpers/dialog'
import validate from '@/components/seeta-ui/seeta-form/validator'
import { rTimeMin, copyText } from '@/utils/system.js'
import { getDevice, getDeviceService, getTag } from '@/axios'
export default {
data() {
return {
ifBorder: false,
// 当前页
pi: 0,
// 当前页size
ps: 10,
// 控制遮罩
loadingStatus: false,
// 搜索栏折叠
isCollapse: true,
time2: '',
// 表格数据
tokenList: [
],
total: 0,
// 编辑和添加表单
form: {
},
childDefinitions: [
{
label: '服务',
type: 'slot',
slotName: 'childServiceSlot'
}, {
label: '编号',
type: 'slot',
slotName: 'childCodeSlot'
}, {
label: '端口',
type: 'slot',
slotName: 'portSlot'
}, {
label: '描述',
type: 'slot',
slotName: 'descSlot'
}, {
label: '操作',
type: 'slot',
slotName: 'childOperate',
width: 120
},
],
definitions: [
{
label: '序号',
render: 'id',
}, {
label: '编号',
type: 'slot',
slotName: 'codeSlot'
}, {
label: '状态',
type: 'slot',
slotName: 'status',
statusColor: item => {
switch (item.state) {
case 1:
return '#67C23A'
case 2:
return '#F56C6C'
default:
return '#999999'
}
}
}, {
label: '架构',
type: 'slot',
slotName: 'structureSlot'
}, {
label: '系统',
type: 'slot',
slotName: 'systemSlot'
}, {
label: 'IP',
render: 'ip',
width: 95
}, {
label: '注册时间',
type: 'slot',
slotName: 'registerTimeSlot',
width: 140
}, {
label: '标签',
type: 'slot',
slotName: 'tagsSlot'
}, {
label: '服务',
type: 'slot',
slotName: 'servicesSlot',
width: 90
}, {
label: '操作',
type: 'slot',
slotName: 'operate',
},
],
/* 搜索栏条件 */
search: {
checkList: []
},
tagList: [{ label: '标签一', value: 0 }, { label: '标签二', value: 1 }, { label: '标签三', value: 2 }, { label: '标签四', value: 3 }],
serviceList: [{ label: '标签一', value: 0 }, { label: '标签二', value: 1 }, { label: '标签三', value: 2 }, { label: '标签四', value: 3 }],
}
},
computed: {
getServiceName() {
return item => {
return item.map(t1 => t1.name).join()
}
},
// 获取设备状态颜色
getStatusColor() {
return item => {
switch (item) {
case 1:
return '#67C23A'
case 2:
return '#F56C6C'
default:
return '#999999'
}
}
},
// 获取设备状态文字
getStatusText() {
return item => {
switch (item) {
case 1:
return '在线'
case 2:
return '异常'
default:
return '离线'
}
}
},
// 精简文字
simplify() {
return (item, length) => {
if (item && item.length > length) {
return item.substring(0, length) + '...'
}
return item
}
}
},
methods: {
rTimeMin,
copyText,
handleChangeSearch() {
this.getData()
},
handleIpChangeSearch(v) {
// 校验IPv4地址 同时兼容xxx.* xxx.xxx.* xxx.xxx.xxx.*
const ipReg = validate.ipV4
if ((v.match(ipReg) && v.match(ipReg)[0] === v) || v === '') {
this.ifBorder = false
this.getData()
} else {
this.ifBorder = true
}
},
startSearch(value) {
this.getData()
},
setDeviceServiceStoreInfo(deviceInfo, serviceInfo, routerTarget, tagIndex) {
this.$store.commit('changeCurrentDevice', deviceInfo)
this.$store.commit('changeCurrentService', serviceInfo)
if (tagIndex !== undefined) {
this.$store.commit('changeCurrentTagIndex', tagIndex)
}
this.$router.push({ name: routerTarget })
},
seeServiceParams(row) {
this.setDeviceServiceStoreInfo(row.deviceId, row, 'device-service', 0)
},
sendReq(row) {
this.setDeviceServiceStoreInfo(row.deviceId, row, 'device-service', 1)
},
sendOrder(row) {
this.setDeviceServiceStoreInfo(row.deviceId, row, 'device-service', 2)
},
collapseSearch() {
this.isCollapse = !this.isCollapse
this.$refs.vTable.clickCollapse()
this.$nextTick(() => {
const icon = [...document.getElementsByClassName('el-date-editor')]
icon.forEach(item => {
const img = document.createElement('img')
img.style.width = '14px'
img.style.height = '14px'
img.src = require('@assets/images/icon-rili.png')
item.appendChild(img)
})
})
},
reset() {
this.search = {
checkList: []
}
this.getData()
},
// 跳转到设备详情页面
detail(deviceid) {
this.$store.commit('changeCurrentDevice', deviceid)
this.$router.push({ name: 'device-detail' })
},
async getData() {
const res = await getDevice({
state: this.search.checkList ? this.search.checkList[0] : '',
pages: this.pi,
pagesize: this.ps,
structure: this.search.structure,
system: this.search.system,
register_date: this.search.registerTime && this.search.registerTime.length ? this.search.registerTime[0] : '',
register_end_date: this.search.registerTime && this.search.registerTime.length ? this.search.registerTime[1] : '',
online_date: this.search.onlineTime && this.search.onlineTime.length ? this.search.onlineTime[0] : '',
online_end_date: this.search.onlineTime && this.search.onlineTime.length ? this.search.onlineTime[1] : '',
tag: this.search.tags,
service: this.search.services,
ip: this.search.ip
})
if (res && res.data) {
this.tokenList = JSON.parse(JSON.stringify(res.data.data.devices))
this.tokenList.forEach(item => {
item.services.forEach(s1 => {
s1.deviceId = item.deviceid
})
item.child = JSON.parse(JSON.stringify(item.services))
})
this.total = res.data.data.total
} else {
this.tokenList = []
this.total = 0
}
},
async getService() {
const res = await getDeviceService()
if (res) {
this.serviceList = res.data.services.map(item => {
return {
label: item,
value: item
}
})
}
},
async getTag() {
const res = await getTag()
if (res) {
this.tagList = res.data.tags.map(item => {
return {
label: item,
value: item
}
})
}
}
},
watch: {
// 监听route的改变进行pi ,ps的改变
'$route.query': {
handler(newName, oldName) {
this.pi = newName.page_index - 1
this.ps = newName.page_size
this.getData()
},
deep: true,
}
}
},
mounted() {
this.getData()
this.getService()
this.getTag()
},
destroyed() {
},
// components: {
// nameFilter: () => import(/* webpackChunkName: "container" */ '@/components/list-filter/name.vue'),
// }
}
</script>
<style lang="sass" scoped>
.tag-label
display: block
margin-bottom: 5px
.service-item
margin-right: 20px
.cell
::v-deep .any-slot
display: inline-block
.page-nav
font-family: PingFangSC-Regular
font-size: 14px
color: #666666
letter-spacing: 0
padding: 26px 20px 20px
.search-title
margin-right: 10px
.clickable
cursor: pointer
.no-wrap
white-space: nowrap
.inline-div
display: inline-block
.circleStatus
margin-left: 6px
.icon-fuzhi-text
margin-left: 6px
color: #409EFF
cursor: pointer
.search-item
text-align: left
.search-item-margin
margin-right: 20px
.search-item:not(.search-item:nth-child(1))
margin-top: 14px
.collapse-btn
font-family: PingFangSC-Regular
font-size: 14px
color: #409EFF
.collapse-text
margin-right: 5px
.search-fields
height: 164px
width: 100%
display: flex !important
flex-direction: row
justify-content: space-between
.search-fields-collapse
max-height: 23px
.flex-left
display: flex
flex-direction: column
justify-content: space-between
.flex-right-nav
margin-left: -88px
display: flex
justify-content: space-between
flex-direction: column
.flex-right-content
display: flex
justify-content: flex-end
.check-title
font-family: PingFangSC-Regular
font-size: 14px
color: #333333
letter-spacing: 0
.operate-text
font-family: PingFangSC-Regular
font-size: 14px
color: #409EFF
margin-right: 20px
cursor: pointer
::v-deep .el-checkbox
margin-right: 15px
.el-checkbox__input
width: 14px
height: 14px
top: -1px
margin-right: 10px
.el-checkbox__label
padding-left: 0px
::v-deep .el-range-separator
font-family: PingFangSC-Regular
font-size: 14px
color: #333333
letter-spacing: 0
::v-deep .el-range-input
font-family: PingFangSC-Regular
font-size: 14px
color: #333333
letter-spacing: 0
&::placeholder
font-family: PingFangSC-Regular
font-size: 14px
color: #999999
letter-spacing: 0
::v-deep
& .el-table__expand-column .cell
padding: 0 20px !important
& .table-box .el-table th .cell, .table-box .el-table .el-table__body tr .cell
padding-left: 0
& .el-table__expanded-cell .cell
padding-left: 48px !important
.table-box
height: 100%
::v-deep .el-table
.cell
text-overflow: initial
</style>
......@@ -225,9 +225,6 @@ export default {
const binaryObj = {}
const tableObj = {}
for (let i = 0; i < scalarsArr.length; i++) {
scalarsObj[scalarsArr[i].field] = scalarsArr[i].value === null ? null : (scalarsArr[i].type === 'number' ? Number(scalarsArr[i].value) : String(scalarsArr[i].value))
}
for (let j = 0; j < binaryArr.length; j++) {
binaryObj[binaryArr[j].field] = binaryArr[j].value
}
for (let k = 0; k < tableArr.length; k++) {
......
......@@ -441,12 +441,9 @@ export default {
color: #666
background: rgba(0, 0, 0, 0)
height: 32px
.updated
::v-deep input[type=text], ::v-deep input[type=password], ::v-deep input[type=number], ::v-deep textarea
color: #F56C6C !important
::v-deep thead
font-size: 14px
font-family: PingFang-SC-Bold, PingFang-SC
font-weight: bold
color: #333333
line-height: 20px
......
<template>
<div>
<div class="data-list-common flex column main-content flex-1">
<div class="header">
<span class="title">{{'服务列表'}}</span>
</div>
<div class="page-nav">
<div class="search-fields" :class="{'search-fields-collapse': isCollapse}">
<div class="flex-left">
<div class="search-item">
<span class="search-title">状态:</span>
<el-checkbox-group v-model="search.checkList" class="inline-div" @change="handleChangeSearch">
<el-checkbox :label="1" class="check-title">在线</el-checkbox>
<el-checkbox :label="0" class="check-title">离线</el-checkbox>
<el-checkbox :label="2" class="check-title">异常</el-checkbox>
</el-checkbox-group>
</div>
<div v-if="!isCollapse">
<div class="search-item">
<span class="search-title">架构:</span>
<st-input :width="'240px'" class="search-item-margin" v-model="search.structure" @change="handleChangeSearch"></st-input>
<span class="search-title">系统:</span>
<st-input :width="'240px'" class="search-item-margin" v-model="search.system" @change="handleChangeSearch"></st-input>
<span class="search-title">IP:</span>
<st-input :width="'240px'" :class="{'error-border': ifBorder}" v-model="search.ip" @change="handleIpChangeSearch"></st-input>
</div>
<div class="search-item no-wrap">
<span class="search-title">注册时间:</span>
<el-date-picker
class="date-picker search-item-margin"
unlink-panels
:default-time="['00:00:00', '23:59:59']"
type="datetimerange"
format="yyyy-MM-dd HH:mm"
value-format="yyyy-MM-dd HH:mm:ss"
size="small"
style="padding-top:2px"
prefix-icon=' '
range-separator="至"
start-placeholder="选择时间"
v-model="search.registerTime"
end-placeholder="选择时间"
suffix-icon="el-icon-date"
@change="handleChangeSearch"
>
</el-date-picker>
<span class="search-title">上线时间:</span>
<el-date-picker
v-model="search.onlineTime"
class="date-picker search-item-margin"
unlink-panels
:default-time="['00:00:00', '23:59:59']"
type="datetimerange"
format="yyyy-MM-dd HH:mm"
value-format="yyyy-MM-dd HH:mm:ss"
size="small"
style="padding-top:2px"
prefix-icon=' '
range-separator="至"
start-placeholder="选择时间"
end-placeholder="选择时间"
@change="handleChangeSearch"
>
</el-date-picker>
</div>
<div class="search-item">
<span class="search-title">标签:</span>
<st-select
size="small"
width="240px"
class="contents"
multiple
filterable
:options="tagList"
v-model="search.tags"
@change="handleChangeSearch"
clearable
>
</st-select>
<span class="search-title">服务:</span>
<st-select
size="small"
width="240px"
class="contents"
multiple
filterable
:options="serviceList"
v-model="search.services"
@change="handleChangeSearch"
clearable
>
</st-select>
</div>
</div>
</div>
<div class="flex-right-nav">
<span class="collapse-btn" :class="{'middle-collapse-btn': isCollapse}">
<span class="collapse-text">{{isCollapse ? '展开' : '收起筛选'}}</span>
<i :class="isCollapse ? 'el-icon-arrow-right' : 'el-icon-arrow-up'" class="clickable" @click="collapseSearch"></i>
</span>
<st-button v-if="!isCollapse" @click="reset">重置</st-button>
</div>
</div>
</div>
<div class="page-content">
<!-- <div class="content-header flex-right-content">
<nameFilter
placeholder="请输入搜索内容"
@startSearch="startSearch">
</nameFilter>
</div> -->
<div class="table-list">
<div class="list-content">
<st-table
ref="vTable"
:options="definitions"
:data="{
list: tokenList,
total: total,
}"
:outerLoading="loadingStatus"
:doubleTable="false"
>
<div slot='codeSlot' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="row.potuid" placement="top">
<span>{{ simplify(row.potuid, 3) }}</span>
</el-tooltip>
<i class="iconfont icon-fuzhi icon-fuzhi-text" @click="copyText(row.potuid)"></i>
</div>
<div slot='status' slot-scope="row">
<span class="circleStatus" :style="{color: getStatusColor(row.state)}">{{ getStatusText(row.state) }}</span>
</div>
<div slot='structureSlot' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="row.structure" placement="top">
<span>{{ simplify(row.structure, 3) }}</span>
</el-tooltip>
</div>
<div slot='registerTimeSlot' slot-scope="row">
<span>{{ (row.register_date) }}</span>
</div>
<div slot='tagsSlot' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="row.tags ? row.tags.join('、') : ''" placement="top">
<!-- 必须要套一层 -->
<div>
<template v-for="(item, index) in row.tags">
<el-tag v-if="[0, 1].indexOf(index) !== -1" :key="index" class="label label-primary tag-label">{{ simplify(item, 4) }}</el-tag>
</template>
<span v-if="(row.tags && row.tags.length) > 10">共: {{(row.tags && row.tags.length) ? row.tags.length : 0}} 条</span>
</div>
</el-tooltip>
</div>
<div slot='servicesSlot' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="row.name" placement="top">
<span>{{row.name.length > 4 ? row.name.slice(0, 3) + '...' : row.name}}</span>
</el-tooltip>
</div>
<div slot='ipSlot' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="row.ip" placement="top">
<span>{{ simplify(row.ip, 3) }}</span>
</el-tooltip>
</div>
<div slot='systemSlot' slot-scope="row">
<el-tooltip class="item" effect="dark" :content="row.system" placement="top">
<span>{{ simplify(row.system, 3) }}</span>
</el-tooltip>
</div>
<div slot='operate' slot-scope="row">
<span class="operate-text" @click="detail(row.id)">{{ '详情 '}}</span>
<span class="operate-text" @click="seeServiceParams(row)">{{ '查看参数' }}</span>
<span class="operate-text" @click="sendReq(row)">{{ '发送请求' }}</span>
<span class="operate-text" @click="sendOrder(row)">{{ '发送指令' }}</span>
</div>
</st-table>
</div>
</div>
</div>
</div>
</template>
<script>
import browserStorage from '@/services/local-storage'
import Dialog from '@/helpers/dialog'
import validate from '@/components/seeta-ui/seeta-form/validator'
import { rTimeMin, copyText } from '@/utils/system.js'
import { getService, getDeviceService, getTag } from '@/axios'
export default {
data() {
return {
ifBorder: false,
// 当前页
pi: 0,
// 当前页size
ps: 10,
// 控制遮罩
loadingStatus: false,
// 搜索栏折叠
isCollapse: true,
time2: '',
// 表格数据
tokenList: [
{ name: '小1', code: '110123124325', child: { service: '11', code: '123', port: '1234', desc: '这是服务1' } },
],
total: 1,
// 编辑和添加表单
form: {
},
childDefinitions: [
{
label: '服务',
type: 'slot',
slotName: 'childServiceSlot'
}, {
label: '编号',
type: 'slot',
slotName: 'childCodeSlot'
}, {
label: '端口',
type: 'slot',
slotName: 'portSlot'
}, {
label: '描述',
type: 'slot',
slotName: 'descSlot'
}, {
label: '操作',
type: 'slot',
slotName: 'childOperate',
width: 120
},
],
definitions: [
{
label: '序号',
render: 'id',
}, {
label: '服务',
type: 'slot',
slotName: 'servicesSlot'
}, {
label: '编号',
type: 'slot',
slotName: 'codeSlot'
}, {
label: '状态',
type: 'slot',
slotName: 'status',
statusColor: item => {
switch (item.state) {
case 1:
return '#67C23A'
case 2:
return '#F56C6C'
default:
return '#999999'
}
}
}, {
label: '架构',
type: 'slot',
slotName: 'structureSlot'
}, {
label: '系统',
type: 'slot',
slotName: 'systemSlot'
}, {
label: 'IP',
type: 'slot',
slotName: 'ipSlot'
}, {
label: '注册时间',
type: 'slot',
slotName: 'registerTimeSlot',
width: 190
}, {
label: '标签',
type: 'slot',
slotName: 'tagsSlot',
width: 130
}, {
label: '操作',
type: 'slot',
slotName: 'operate',
width: 310
},
],
/* 搜索栏条件 */
search: {
checkList: []
},
tagList: [{ label: '标签一', value: 0 }, { label: '标签二', value: 1 }, { label: '标签三', value: 2 }, { label: '标签四', value: 3 }],
serviceList: [{ label: '标签一', value: 0 }, { label: '标签二', value: 1 }, { label: '标签三', value: 2 }, { label: '标签四', value: 3 }],
}
},
computed: {
getServiceName() {
return item => {
return item.map(t1 => t1.name).join()
}
},
// 获取设备状态颜色
getStatusColor() {
return item => {
switch (item) {
case 1:
return '#67C23A'
case 2:
return '#F56C6C'
default:
return '#999999'
}
}
},
// 获取设备状态文字
getStatusText() {
return item => {
switch (item) {
case 1:
return '在线'
case 2:
return '异常'
default:
return '离线'
}
}
},
// 精简文字
simplify() {
return (item, length) => {
if (item && item.length > length) {
return item.substring(0, length) + '...'
}
return item
}
}
},
methods: {
rTimeMin,
copyText,
handleChangeSearch() {
this.getData()
},
handleIpChangeSearch(v) {
// 校验IPv4地址 同时兼容xxx.* xxx.xxx.* xxx.xxx.xxx.*
const ipReg = validate.ipV4
if ((v.match(ipReg) && v.match(ipReg)[0] === v) || v === '') {
this.ifBorder = false
this.getData()
} else {
this.ifBorder = true
}
},
startSearch(value) {
this.getData()
},
async getData() {
const res = await getService({
state: this.search.checkList,
pages: this.pi,
pagesize: this.ps,
structure: this.search.structure,
system: this.search.system,
register_date: this.search.registerTime && this.search.registerTime.length ? this.search.registerTime[0] : '',
online_date: this.search.onlineTime && this.search.onlineTime.length ? this.search.onlineTime[0] : '',
register_end_date: this.search.registerTime && this.search.registerTime.length ? this.search.registerTime[1] : '',
online_end_date: this.search.onlineTime && this.search.onlineTime.length ? this.search.onlineTime[1] : '',
tag: this.search.tags,
service: this.search.services,
ip: this.search.ip
})
if (res && res.data) {
this.tokenList = JSON.parse(JSON.stringify(res.data.data.services))
this.total = res.data.data.total
} else {
this.tokenList = []
this.total = 0
}
},
async getServiceList() {
const res = await getDeviceService()
if (res) {
this.serviceList = res.data.services.map(item => {
return {
label: item,
value: item
}
})
}
},
async getTag() {
const res = await getTag()
if (res) {
this.tagList = res.data.tags.map(item => {
return {
label: item,
value: item
}
})
}
},
setDeviceServiceStoreInfo(deviceInfo, serviceInfo, routerTarget, tagIndex) {
this.$store.commit('changeCurrentDevice', deviceInfo)
this.$store.commit('changeCurrentService', serviceInfo)
if (tagIndex !== undefined) {
this.$store.commit('changeCurrentTagIndex', tagIndex)
}
this.$router.push({ name: routerTarget })
},
seeServiceParams(row) {
this.setDeviceServiceStoreInfo(row.deviceid, row, 'device-service', 0)
},
sendReq(row) {
this.setDeviceServiceStoreInfo(row.deviceid, row, 'device-service', 1)
},
sendOrder(row) {
this.setDeviceServiceStoreInfo(row.deviceid, row, 'device-service', 2)
},
collapseSearch() {
this.isCollapse = !this.isCollapse
this.$refs.vTable.clickCollapse()
this.$nextTick(() => {
const icon = [...document.getElementsByClassName('el-date-editor')]
icon.forEach(item => {
const img = document.createElement('img')
img.style.width = '14px'
img.style.height = '14px'
img.src = require('@assets/images/icon-rili.png')
item.appendChild(img)
})
})
},
reset() {
this.search = {
checkList: []
}
this.getData()
},
// 跳转到设备详情页面
detail(deviceid) {
this.$store.commit('changeCurrentDevice', deviceid)
this.$router.push({ name: 'device-detail' })
},
},
watch: {
// 监听route的改变进行pi ,ps的改变
'$route.query': {
handler(newName, oldName) {
this.pi = newName.page_index - 1
this.ps = newName.page_size
this.getData()
},
deep: true,
}
},
mounted() {
this.getData()
this.getServiceList()
this.getTag()
},
destroyed() {
},
components: {
// nameFilter: () => import(/* webpackChunkName: "container" */ '@/components/list-filter/name.vue'),
}
}
</script>
<style lang="sass" scoped>
.tag-label
display: block
margin-bottom: 5px
.page-nav
font-family: PingFangSC-Regular
font-size: 14px
color: #666666
letter-spacing: 0
padding: 26px 20px 20px
.search-title
margin-right: 10px
.clickable
cursor: pointer
.no-wrap
white-space: nowrap
.inline-div
display: inline-block
.circleStatus
margin-left: 6px
.icon-fuzhi-text
margin-left: 6px
color: #409EFF
cursor: pointer
.search-item
text-align: left
.search-item-margin
margin-right: 20px
.search-item:not(.search-item:nth-child(1))
margin-top: 14px
.collapse-btn
font-family: PingFangSC-Regular
font-size: 14px
color: #409EFF
.collapse-text
margin-right: 5px
.search-fields
height: 164px
width: 100%
display: flex !important
flex-direction: row
justify-content: space-between
.search-fields-collapse
max-height: 23px
.flex-left
display: flex
flex-direction: column
justify-content: space-between
.flex-right-nav
margin-left: -88px
display: flex
justify-content: space-between
flex-direction: column
.flex-right-content
display: flex
justify-content: flex-end
.check-title
font-family: PingFangSC-Regular
font-size: 14px
color: #333333
letter-spacing: 0
.operate-text
font-family: PingFangSC-Regular
font-size: 14px
color: #409EFF
margin-right: 20px
cursor: pointer
::v-deep .el-checkbox
margin-right: 15px
.el-checkbox__input
width: 14px
height: 14px
top: -1px
margin-right: 10px
.el-checkbox__label
padding-left: 0px
::v-deep .el-range-separator
font-family: PingFangSC-Regular
font-size: 14px
color: #333333
letter-spacing: 0
::v-deep .el-range-input
font-family: PingFangSC-Regular
font-size: 14px
color: #333333
letter-spacing: 0
&::placeholder
font-family: PingFangSC-Regular
font-size: 14px
color: #999999
letter-spacing: 0
::v-deep
& .el-table__expand-column .cell
padding: 0 20px !important
& .table-box .el-table th .cell, .table-box .el-table .el-table__body tr .cell
padding-left: 40px
& .el-table__expanded-cell .cell
padding-left: 48px !important
.table-box
height: 100%
::v-deep .el-table
.cell
text-overflow: initial
</style>
......@@ -78,7 +78,6 @@
</template>
<script>
import { usersApi, codeApi } from '@/http'
export default {
data() {
const validatePassword = (rule, value, callback) => {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!