summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorshizhendong <[email protected]>2019-11-12 14:55:56 +0800
committershizhendong <[email protected]>2019-11-12 14:55:56 +0800
commit7a0faf97dea9d47a2ff39771596dc81d5d091354 (patch)
tree1afa87e93d854cb330b6cc616f9561e5caa8d705
parent697e81c4d95c78ba087a85a9beb8a58417b5a3e9 (diff)
1.分配节点添加IP校验
2.修改选中问题
-rw-r--r--nezha-admin/src/main/resources/mapper/node/NodeGroupInfoDao.xml4
-rw-r--r--nezha-admin/src/main/resources/templates/js/modules/common/nodeRel.js411
-rw-r--r--nezha-admin/src/main/resources/templates/js/modules/node/nodeGroup.js5
-rw-r--r--nezha-admin/src/main/resources/templates/modules/common/nodeRel.html210
-rw-r--r--nezha-admin/src/main/resources/templates/modules/node/nodeGroup.html1
5 files changed, 481 insertions, 150 deletions
diff --git a/nezha-admin/src/main/resources/mapper/node/NodeGroupInfoDao.xml b/nezha-admin/src/main/resources/mapper/node/NodeGroupInfoDao.xml
index b1025719..e85dea34 100644
--- a/nezha-admin/src/main/resources/mapper/node/NodeGroupInfoDao.xml
+++ b/nezha-admin/src/main/resources/mapper/node/NodeGroupInfoDao.xml
@@ -18,9 +18,9 @@
<select id="assList" resultType="com.nis.modules.node.entity.NodeInfoEntity">
- SELECT t.name,t.host_name,t.ip,t.uuid,t.type,t.tag FROM
+ SELECT t.name,t.host_name,t.ip,t.ip_long,t.uuid,t.type,t.tag FROM
(
- SELECT ni.name,ni.host_name,ni.ip,ni.uuid,ni.type,ni.tag FROM system_node_rel snr
+ SELECT ni.name,ni.host_name,ni.ip,ni.ip_long,ni.uuid,ni.type,ni.tag FROM system_node_rel snr
LEFT JOIN node_info ni ON snr.uuid = ni.uuid
WHERE snr.system_id = #{params.systemId} AND snr.del_flag = 0 AND ni.state != 3
diff --git a/nezha-admin/src/main/resources/templates/js/modules/common/nodeRel.js b/nezha-admin/src/main/resources/templates/js/modules/common/nodeRel.js
index 5e0f4d51..ecafe914 100644
--- a/nezha-admin/src/main/resources/templates/js/modules/common/nodeRel.js
+++ b/nezha-admin/src/main/resources/templates/js/modules/common/nodeRel.js
@@ -1,4 +1,8 @@
<script>
+Vue.use(window.vuelidate.default);
+var required = window.validators.required;
+var ipAddress = window.validators.ipAddress;
+
//分配节点组件
var nodeRelComponent = Vue.extend({
template: "#nodeRelTemplate", //位于/modules/common/nodeRel.html
@@ -42,61 +46,140 @@ var nodeRelComponent = Vue.extend({
return rowData["state"]=='1'?"在线":"<span style='color:#aaa;'>下线</span>";
}}
],
+ selectedIPEndSizeValidation: false, // IPEnd 比 IPStart 小 提示标识 selected
+ selectableIPEndSizeValidation: false, // IPEnd 比 IPStart 小 提示标识 selectable
+ selectedUuids: [], // 选中的uuids selected
+ selectableUuids: [] // 选中的uuids selectable
+ }
+ },
+ validations: {
+ selectedIPStart: {
+ ipAddress, required
+ },
+ selectedIPEnd: {
+ ipAddress, required
+ },
+ selectableIPStart: {
+ ipAddress, required
+ },
+ selectableIPEnd: {
+ ipAddress, required
}
},
methods: {
- check: function(event, tr) { //节点列表的点击事件
- if (!tr) {
- var tr = event.currentTarget; //绑定了点击事件的tr
- }
- //列表中的checkbox是否打钩控制
- if ($(tr).find(".r-checkbox").hasClass("checkbox_false_full")) {
- $(tr).find(".r-checkbox").removeClass("checkbox_false_full").addClass("checkbox_true_full");
- $(tr).addClass("success");
- } else if ($(tr).find(".r-checkbox").hasClass("checkbox_true_full")) {
- $(tr).find(".r-checkbox").removeClass("checkbox_true_full").addClass("checkbox_false_full");
- $(tr).removeClass("success");
+ check: function(node, flag) { //节点列表的点击事件
+ var temp = this;
+ var uuid = node.uuid;
+ // 判断是否选中
+ if (!node.checkedBox1) {
+ if (flag == 'selected') {
+ // 在选中数组中添加
+ this.selectedUuids.push(uuid);
+ // 选中
+ this.selectedNodes.some(function (item, index) {
+ if (item.uuid == uuid) {
+ temp.$set(item, 'checkedBox1', true);
+ temp.selectedNodes.splice(index, 1, item);
+ return true;
+ }
+ });
+ } else {
+ // 在选中数组中添加
+ this.selectableUuids.push(uuid);
+ // 选中
+ this.selectableNodes.some(function (item, index) {
+ if (item.uuid == uuid) {
+ temp.$set(item, 'checkedBox1', true);
+ temp.selectableNodes.splice(index, 1, item);
+ return true;
+ }
+ });
+ }
+ } else {
+ if (flag == 'selected') {
+ // 在选中数组中删除
+ this.selectedUuids.splice(this.selectedUuids.indexOf(uuid),1);
+ // 取消选中
+ this.selectedNodes.some(function (item, index) {
+ if (item.uuid == uuid) {
+ temp.$set(item, 'checkedBox1', false);
+ temp.selectedNodes.splice(index, 1, item);
+ return true;
+ }
+ });
+ } else {
+ // 在选中数组中删除
+ this.selectableUuids.splice(this.selectableUuids.indexOf(uuid),1);
+ // 取消选中
+ this.selectableNodes.some(function (item, index) {
+ if (item.uuid == uuid) {
+ temp.$set(item, 'checkedBox1', false);
+ temp.selectableNodes.splice(index, 1, item);
+ return true;
+ }
+ });
+ }
}
- //已选数量控制
+ // 计算选中数量和总数量
this.countControll();
- //tr背景色、全选框控制
- if ($(tr).parent().find(".success").length == 0) {
- $(tr).parent().prev().find(".r-checkbox").removeClass("checkbox_false_part").removeClass("checkbox_true_part").addClass("checkbox_false_full");
- } else if ($(tr).parent().find(".success").length < $(tr).parent().find("tr").length) {
- $(tr).parent().prev().find(".r-checkbox").removeClass("checkbox_false_full").removeClass("checkbox_true_part").addClass("checkbox_false_part");
- } else if ($(tr).parent().find(".success").length == $(tr).parent().find("tr").length) {
- $(tr).parent().prev().find(".r-checkbox").removeClass("checkbox_false_full").removeClass("checkbox_false_part").addClass("checkbox_true_part");
- }
},
- checkAll: function(event) {
- //全选框控制
+ checkAll: function(event, flag) {
+ var temp = this;
+ // 全选
if (!$(event.currentTarget).hasClass("checkbox_true_part")) {
- $(event.currentTarget).removeClass("checkbox_false_full").removeClass("checkbox_false_part").addClass("checkbox_true_part");
- $(event.currentTarget).parent().parent().parent().next().find("tr").removeClass("success").addClass("success");
- $(event.currentTarget).parent().parent().parent().next().find(".r-checkbox").removeClass("checkbox_false_full").removeClass("checkbox_true_full").addClass("checkbox_true_full");
- } else {
- $(event.currentTarget).removeClass("checkbox_true_part").addClass("checkbox_false_full");
- $(event.currentTarget).parent().parent().parent().next().find("tr").removeClass("success");
- $(event.currentTarget).parent().parent().parent().next().find(".r-checkbox").removeClass("checkbox_true_full").addClass("checkbox_false_full");
+ if (flag == 'selected') {
+ // 先置空
+ this.selectedUuids = [];
+ // 全选 添加uuids
+ this.selectedNodes.forEach(function (item) {
+ temp.$set(item, 'checkedBox1', true);
+ temp.selectedUuids.push(item.uuid);
+ })
+ } else {
+ // 先置空
+ this.selectableUuids = [];
+ // 全选 添加uuids
+ this.selectableNodes.forEach(function (item) {
+ temp.$set(item, 'checkedBox1', true);
+ temp.selectableUuids.push(item.uuid);
+ })
+ }
+ } else { // 全不选
+ if (flag == 'selected') {
+ // 置空
+ this.selectedUuids = [];
+ // 取消全选
+ this.selectedNodes.forEach(function (item) {
+ temp.$set(item, 'checkedBox1', false);
+ })
+ } else {
+ // 置空
+ this.selectableUuids = [];
+ // 取消全选
+ this.selectableNodes.forEach(function (item) {
+ temp.$set(item, 'checkedBox1', false);
+ })
+ }
}
- //已选数量控制
+ // 计算选中数量和总数量
this.countControll();
},
- countControll: function() { //更新已选数量和总数
- this.selectedCount = $("#selected-box").find(".success").length;
- this.selectableCount = $("#selectable-box").find(".success").length;
+ countControll: function() { // 更新已选数量和总数
+ this.selectedCount = this.selectedUuids.length;
+ this.selectableCount = this.selectableUuids.length;
this.selectedTotalCount = this.selectedNodes.length;
this.selectableTotalCount = this.selectableNodes.length;
},
- nodeRelChange: function(flag, event) { //节点分配状态更改
- if (flag == 0) { //取消分配
- var willChangeNodeDom = $("#selected-box").find(".success"); //所有将要改变的节点
+ nodeRelChange: function(flag, event) { // 节点分配状态更改
+ if (flag == 0) { // 取消分配
var addToSelectableNodes = [];
- for (var i = 0; i < willChangeNodeDom.length; i++) {
- var uuid = $(willChangeNodeDom[i]).attr("uuid");
+ for (var i = 0; i < this.selectedUuids.length; i++) {
+ var uuid = this.selectedUuids[i];
for (var j = this.selectedNodes.length-1; j >= 0; j--) {
if (this.selectedNodes[j].uuid == uuid) {
var addToSelectableNode = this.selectedNodes[j];
+ // 取消分配后取消选中状态
+ addToSelectableNode.checkedBox1 = false;
if (addToSelectableNode.newNode) {
for (var k = this.selectedNodesAdd.length-1; k >= 0; k--) {
if (this.selectedNodesAdd[k] == addToSelectableNode.uuid) {
@@ -120,18 +203,22 @@ var nodeRelComponent = Vue.extend({
}
}
}
+ // 重置selectuuids
+ this.selectedUuids = [];
+
this.selectableNodes = addToSelectableNodes.concat(this.selectableNodes);
this.tempSelectableNodes = addToSelectableNodes.concat(this.tempSelectableNodes);
this.sortRow(0, this.selectableNodes);
this.sortRow(1, this.tempSelectableNodes);
- } else if (flag == 1) { //分配
- var willChangeNodeDom = $("#selectable-box").find(".success"); //所有将要改变的节点
+ } else if (flag == 1) { // 可分配
var addToSelectedNodes = [];
- for (var i = 0; i < willChangeNodeDom.length; i++) {
- var uuid = $(willChangeNodeDom[i]).attr("uuid");
+ for (var i = 0; i < this.selectableUuids.length; i++) {
+ var uuid = this.selectableUuids[i];
for (var j = this.selectableNodes.length-1; j >= 0; j--) {
if (this.selectableNodes[j].uuid == uuid) {
var addToSelectedNode = this.selectableNodes[j];
+ // 分配过去取消选中
+ addToSelectedNode.checkedBox1 = false;
if (addToSelectedNode.newNode) {
for (var k = this.selectableNodesAdd.length-1; k >= 0; k--) {
if (this.selectableNodesAdd[k] == addToSelectedNode.uuid) {
@@ -155,19 +242,17 @@ var nodeRelComponent = Vue.extend({
}
}
}
+ // 重置selectableUuids
+ this.selectableUuids = [];
+
this.selectedNodes = addToSelectedNodes.concat(this.selectedNodes);
this.tempSelectedNodes = addToSelectedNodes.concat(this.tempSelectedNodes);
this.sortRow(2, this.selectedNodes);
this.sortRow(3, this.tempSelectedNodes);
}
- $(".checkbox_true_part").removeClass("checkbox_true_part").addClass("checkbox_false_full");
- $(".checkbox_false_part").removeClass("checkbox_false_part").addClass("checkbox_false_full");
- $(".checkbox_true_full").removeClass("checkbox_true_full").addClass("checkbox_false_full");
- $(".success").removeClass("success");
-
- //已选数量和总数量控制
+ // 已选数量和总数量控制
this.countControll();
- //将数据传递给父组件
+ // 将数据传递给父组件
this.$emit("node-change", [this.selectedNodesAdd, this.selectableNodesAdd, this.tempSelectedNodes.length]);
},
inputTouch: function(position, event) { //搜索框点击事件
@@ -189,24 +274,33 @@ var nodeRelComponent = Vue.extend({
}
}
},
- searchIp: function(event) { //ip搜索
- //TODO 校验
+ searchIp: function(event) { // ip搜索
var matchNodes = [];
- if ($(event.currentTarget).parent().parent().parent().find("#selected-box").length > 0) { //已分配
- //搜索
+ if ($(event.currentTarget).parent().parent().parent().find("#selected-box").length > 0) { // 已分配
+ // 搜索
var input = $(event.currentTarget).parent().parent().find("[active=true]");
- if (input.length > 1) { //范围搜索
+ if (input.length > 1) { // 范围搜索
+ // 校验IP
+ if (!this.validateSelectedStartAndEndIP()) {
+ this.showSelectedIPStartWarningMsg();
+ this.showSelectedIPEndWarningMsg();
+ return;
+ }
var ipStart = $(input[0]).val();
var ipEnd = $(input[1]).val();
var ipStartLong = ipToNumber(ipStart);
var ipEndLong = ipToNumber(ipEnd);
+ if (ipStartLong > ipEndLong) {
+ this.selectedIPEndSizeValidation = true;
+ return;
+ }
this.selectedNodes = [];
for (var i = 0; i < this.tempSelectedNodes.length; i++) {
if (ipStartLong <= this.tempSelectedNodes[i].ipLong && ipEndLong >= this.tempSelectedNodes[i].ipLong) {
this.selectedNodes.push(this.tempSelectedNodes[i]);
}
}
- } else if (input.length == 1) { //精确搜索
+ } else if (input.length == 1) { // 精确搜索
if (!this.selectedIP) {
this.selectedNodes = this.tempSelectedNodes;
} else {
@@ -218,21 +312,40 @@ var nodeRelComponent = Vue.extend({
}
}
}
- } else if ($(event.currentTarget).parent().parent().parent().find("#selectable-box").length > 0) { //已分配
- //搜索
+ // 更新 selectedUuid 选中的依旧选中
+ var temp = this;
+ this.selectedUuids = [];
+ this.selectedNodes.forEach(function (item) {
+ if (item.checkedBox1) { // 搜索之后当前选中状态
+ temp.$set(item, 'checkedBox1', true);
+ temp.selectedUuids.push(item.uuid);
+ }
+ })
+ } else if ($(event.currentTarget).parent().parent().parent().find("#selectable-box").length > 0) { // 可分配
+ // 搜索
var input = $(event.currentTarget).parent().parent().find("[active=true]");
- if (input.length > 1) { //范围搜索
+ if (input.length > 1) { // 范围搜索
+ // 校验IP
+ if (!this.validateSelectableStartAndEndIP()) {
+ this.showSelectableIPStartWarningMsg();
+ this.showSelectableIPEndWarningMsg();
+ return;
+ }
var ipStart = $(input[0]).val();
var ipEnd = $(input[1]).val();
var ipStartLong = ipToNumber(ipStart);
var ipEndLong = ipToNumber(ipEnd);
+ if (ipStartLong > ipEndLong) {
+ this.selectableIPEndSizeValidation = true;
+ return;
+ }
this.selectableNodes = [];
for (var i = 0; i < this.tempSelectableNodes.length; i++) {
if (ipStartLong <= this.tempSelectableNodes[i].ipLong && ipEndLong >= this.tempSelectableNodes[i].ipLong) {
this.selectableNodes.push(this.tempSelectableNodes[i]);
}
}
- } else if (input.length == 1) { //精确搜索
+ } else if (input.length == 1) { // 精确搜索
if (!this.selectableIP) {
this.selectableNodes = this.tempSelectableNodes;
} else {
@@ -244,29 +357,73 @@ var nodeRelComponent = Vue.extend({
}
}
}
+ // 更新 selectedUuid 选中的依旧选中
+ var temp = this;
+ this.selectableUuids = [];
+ this.selectableNodes.forEach(function (item) {
+ if (item.checkedBox1) { // 搜索之后当前选中状态
+ temp.$set(item, 'checkedBox1', true);
+ temp.selectableUuids.push(item.uuid);
+ }
+ })
}
- //已选数量和总数量控制
- this.countControll();
+
+ // 已选数量和总数量控制
+ this.$nextTick(()=>{
+ this.countControll();
+ });
},
searchReset: function(event) { //搜索条件重置
if ($(event.currentTarget).parent().parent().parent().find("#selected-box").length > 0) { //已分配
this.selectedIP = '';
this.selectedIPStart = '';
this.selectedIPEnd = '';
+
+ this.selectedIPEndSizeValidation = this.selectedRange = false;
+
+ this.$v.selectedIPStart.$reset();
+ this.$v.selectedIPEnd.$reset();
+ this.$v.selectedIP.$reset();
} else {
this.selectableIP = '';
this.selectableIPStart = '';
this.selectableIPEnd = '';
+
+ this.selectableIPEndSizeValidation = this.selectableRange = false;
+
+ this.$v.selectableIPStart.$reset();
+ this.$v.selectableIPEnd.$reset();
+ this.$v.selectableIP.$reset();
}
},
nodeReset: function() { //重置此次操作
this.tempSelectedNodes = this.selectedNodes = JSON.parse(JSON.stringify(this.initSelectedNodes));
this.tempSelectableNodes = this.selectableNodes = JSON.parse(JSON.stringify(this.initSelectableNodes));
+
+ var temp = this;
+ // 以前选中的恢复选中
+ this.selectedNodes.forEach(function (item, index) {
+ if (temp.selectedUuids.indexOf(item.uuid) != -1) {
+ temp.$set(item, 'checkedBox1', true);
+ }
+ })
+ // 以前选中的恢复选中
+ this.selectableNodes.forEach(function (item, index) {
+ if (temp.selectableUuids.indexOf(item.uuid) != -1) {
+ temp.$set(item, 'checkedBox1', true);
+ }
+ })
+
this.selectedNodesAdd = [];
this.selectableNodesAdd = [];
this.$emit("node-change", [this.selectedNodesAdd, this.selectableNodesAdd, this.tempSelectedNodes.length]);
this.countControll();
},
+ resetSelectedCount: function() {
+ // 重置选中数量
+ this.selectedUuids = [];
+ this.selectableUuids = [];
+ },
sortRow: function(flag, nodes) { //列表重新排序,将新增的项置顶
var newNodes = [];
for (var i = nodes.length-1; i >= 0; i--) {
@@ -284,6 +441,120 @@ var nodeRelComponent = Vue.extend({
} else if (flag == 3) {
this.tempSelectedNodes = newNodes.concat(nodes);
}
+ },
+ validateSelectedStartAndEndIP: function() {
+ this.$v.selectedIPStart.$touch();
+ this.$v.selectedIPEnd.$touch();
+ return !this.$v.selectedIPStart.$error && !this.$v.selectedIPEnd.$error && this.selectedIPEndSizeValidation;
+ },
+ validateSelectedIP: function() {
+ this.$v.selectedIP.$touch();
+ return !this.$v.selectedIP.$error;
+ },
+ validateSelectableStartAndEndIP: function() {
+ this.$v.selectableIPStart.$touch();
+ this.$v.selectableIPEnd.$touch();
+ return !this.$v.selectableIPStart.$error && !this.$v.selectableIPEnd.$error && this.selectableIPEndSizeValidation;
+ },
+ validateSelectableIP: function() {
+ this.$v.selectableIP.$touch();
+ return !this.$v.selectableIP.$error;
+ },
+ showSelectedIPStartWarningMsg: function() {
+ if(this.$v.selectedIPStart.$anyError){
+ var msg = '';
+ if (this.$v.selectedIPStart.$dirty&&!this.$v.selectedIPStart.required) {
+ msg = "<div class=\"form-control_error-msg\"><@spring.message 'validate.common.required'/></div>"
+ }
+ if (this.$v.selectedIPStart.$dirty&&!this.$v.selectedIPStart.ipAddress) {
+ msg = "<div class=\"form-control_error-msg\"><@spring.message 'validate.node.ipFormat'/></div>"
+ }
+ layer.tips(msg, "#selectedIPStart",{
+ tips:[1, "white"],
+ tipsMore:true
+ });
+ }
+ },
+ showSelectedIPEndWarningMsg: function() {
+ if (this.$v.selectedIPEnd.$anyError || !this.selectedIPEndSizeValidation) {
+ var msg = '';
+ if (this.$v.selectedIPEnd.$dirty&&!this.$v.selectedIPEnd.required) {
+ msg = "<div class=\"form-control_error-msg\"><@spring.message 'validate.common.required'/></div>"
+ }
+ if (this.$v.selectedIPEnd.$dirty&&!this.$v.selectedIPEnd.ipAddress) {
+ msg = "<div class=\"form-control_error-msg\"><@spring.message 'validate.node.ipFormat'/></div>"
+ }
+ if (msg == '' && !this.selectedIPEndSizeValidation) {
+ msg = "<div class=\"form-control_error-msg\"><@spring.message 'validate.common.IpEndLessThanIpStart'/></div>"
+ }
+ layer.tips(msg, "#selectedIPEnd",{
+ tips:[1, "white"],
+ tipsMore:true
+ });
+ }
+ },
+ showSelectedIPWarningMsg: function() {
+ if (this.$v.selectedIP.$anyError) {
+ var msg = '';
+ if (this.$v.selectedIP.$dirty&&!this.$v.selectedIP.required) {
+ msg = "<div class=\"form-control_error-msg\"><@spring.message 'validate.common.required'/></div>"
+ }
+ if (this.$v.selectedIP.$dirty&&!this.$v.selectedIP.ipAddress) {
+ msg = "<div class=\"form-control_error-msg\"><@spring.message 'validate.node.ipFormat'/></div>"
+ }
+ layer.tips(msg, "#selectedIP",{
+ tips:[1, "white"],
+ tipsMore:true
+ });
+ }
+ },
+ showSelectableIPStartWarningMsg: function() {
+ if(this.$v.selectableIPStart.$anyError){
+ var msg = '';
+ if (this.$v.selectableIPStart.$dirty&&!this.$v.selectableIPStart.required) {
+ msg = "<div class=\"form-control_error-msg\"><@spring.message 'validate.common.required'/></div>"
+ }
+ if (this.$v.selectableIPStart.$dirty&&!this.$v.selectableIPStart.ipAddress) {
+ msg = "<div class=\"form-control_error-msg\"><@spring.message 'validate.node.ipFormat'/></div>"
+ }
+ layer.tips(msg, "#selectableIPStart",{
+ tips:[1, "white"],
+ tipsMore:true
+ });
+ }
+ },
+ showSelectableIPEndWarningMsg: function() {
+ if (this.$v.selectableIPEnd.$anyError || !this.selectableIPEndSizeValidation) {
+ var msg = '';
+ if (this.$v.selectableIPEnd.$dirty&&!this.$v.selectableIPEnd.required) {
+ msg = "<div class=\"form-control_error-msg\"><@spring.message 'validate.common.required'/></div>"
+ }
+ if (this.$v.selectableIPEnd.$dirty&&!this.$v.selectableIPEnd.ipAddress) {
+ msg = "<div class=\"form-control_error-msg\"><@spring.message 'validate.node.ipFormat'/></div>"
+ }
+ if (msg == '' && !this.selectableIPEndSizeValidation) {
+ msg = "<div class=\"form-control_error-msg\"><@spring.message 'validate.common.IpEndLessThanIpStart'/></div>"
+ }
+ layer.tips(msg, "#selectableIPEnd",{
+ tips:[1, "white"],
+ tipsMore:true
+ });
+ }
+ },
+ showSelectableIPWarningMsg: function() {
+ if (this.$v.selectableIP.$anyError) {
+ var msg = '';
+ if (this.$v.selectableIP.$dirty&&!this.$v.selectableIP.required) {
+ msg = "<div class=\"form-control_error-msg\"><@spring.message 'validate.common.required'/></div>"
+ }
+ if (this.$v.selectableIP.$dirty&&!this.$v.selectableIP.ipAddress) {
+ msg = "<div class=\"form-control_error-msg\"><@spring.message 'validate.node.ipFormat'/></div>"
+ }
+ layer.tips(msg, "#selectableIP",{
+ tips:[1, "white"],
+ tipsMore:true
+ });
+ }
}
},
mounted: function() {
@@ -300,6 +571,24 @@ var nodeRelComponent = Vue.extend({
initSelectableNodes: function(n, o) {
this.tempSelectableNodes = this.selectableNodes = JSON.parse(JSON.stringify(n));
this.selectableTotalCount = n.length;
+ },
+ selectedIPEnd: function(n, o) {
+ var ipStartLong = ipToNumber(this.selectedIPStart);
+ var ipEndLong = ipToNumber(n);
+ if (ipEndLong >= ipStartLong) {
+ this.selectedIPEndSizeValidation = true;
+ }else {
+ this.selectedIPEndSizeValidation = false;
+ }
+ },
+ selectableIPEnd: function(n, o) {
+ var ipStartLong = ipToNumber(this.selectableIPStart);
+ var ipEndLong = ipToNumber(n);
+ if (ipEndLong >= ipStartLong) {
+ this.selectableIPEndSizeValidation = true;
+ }else {
+ this.selectableIPEndSizeValidation = false;
+ }
}
}
})
diff --git a/nezha-admin/src/main/resources/templates/js/modules/node/nodeGroup.js b/nezha-admin/src/main/resources/templates/js/modules/node/nodeGroup.js
index 7a177487..2b269e3e 100644
--- a/nezha-admin/src/main/resources/templates/js/modules/node/nodeGroup.js
+++ b/nezha-admin/src/main/resources/templates/js/modules/node/nodeGroup.js
@@ -402,6 +402,9 @@ var vue = new Vue({
}
});
+ // 重置子组件选中数量
+ this.$refs.nodeRel.resetSelectedCount();
+
layer.open({
area: ['740px', '100%'],
shade: 0.01,
@@ -428,6 +431,8 @@ var vue = new Vue({
form.append("id", vue.selectedNodeGroup.id);
form.append("addUuids", vue.addUuids);
form.append("removeUuids", vue.removeUuids);
+ console.log(vue.addUuids)
+ console.log(vue.removeUuids)
$.ajax({
type: "POST",
url: baseURL + "nodegroup/assignNode",
diff --git a/nezha-admin/src/main/resources/templates/modules/common/nodeRel.html b/nezha-admin/src/main/resources/templates/modules/common/nodeRel.html
index 187ff706..8d1dbb9f 100644
--- a/nezha-admin/src/main/resources/templates/modules/common/nodeRel.html
+++ b/nezha-admin/src/main/resources/templates/modules/common/nodeRel.html
@@ -1,89 +1,125 @@
<script type="text/x-template" id="nodeRelTemplate">
- <div>
- <div class="box">
- <div class="title">已分配</div>
- <div class="tools">
- <div class="form-group">
- <input :active="selectedRange + ''" @click="inputTouch(0, $event)" v-model="selectedIPStart" type="text" class="form-control input-medium" placeholder="IPStart">
- <span class="conn-symbol">-</span>
- <input :active="selectedRange + ''" @click="inputTouch(0, $event)" v-model="selectedIPEnd" type="text" class="form-control input-medium" placeholder="IPEnd">
- </div>
- <div class="form-group">
- <input :active="!selectedRange + ''" @click="inputTouch(1, $event)" v-model="selectedIP" type="text" class="form-control input-medium" placeholder="IP">
- </div>
- <div class="btn-groups">
- <a @click="searchIp" class="btn btn-default" title="<@spring.message 'common.search'/>"><i class="fa fa-search"></i></a>
- <a @click="searchReset" class="btn btn-default" title="<@spring.message 'common.reset'/>"><i class="fa fa-refresh"></i></a>
- </div>
- </div>
- <div style="clear:both"></div>
- <div id="selected-box" class="node-box" :style="'height:' + height + 'px'">
- <table class="r-table">
- <thead>
- <tr>
- <th max-width="47px"></th>
- <th width="30px"><span class="r-checkbox checkbox_false_full" id="selected-checkall" @click="checkAll"/></th>
- <th width="120px" class="r-tab-th">IP</th>
- <th class="r-tab-th">类型</th>
- <th class="r-tab-th">状态</th>
- </tr>
- </thead>
- <tbody>
- <template v-for="(selected,index) in selectedNodes">
- <tr :class="{'new-node': selected.newNode}" class="selected" @click="check" :uuid="selected.uuid" :id="'selected-' + selected.uuid" :iplong="selected.ipLong">
- <td>{{index+1}}</td>
- <td><span class="r-checkbox checkbox_false_full"></span></td>
- <td v-for="(item) in colModel" v-html="typeof item.formatter == 'undefined' || item.formatter == null ? selected[item.field] : item.formatter(selected)"></td>
- </tr>
- </template>
- </tbody>
- </table>
- </div>
- <div class="box_counter">已选&nbsp;&nbsp;<span>{{selectedCount}}</span>&nbsp;/&nbsp;{{selectedTotalCount}}</div>
- </div>
- <div class="box">
- <div class="title">可分配</div>
- <div class="tools">
- <div class="form-group">
- <input :active="selectableRange + ''" @click="inputTouch(0, $event)" v-model="selectableIPStart" type="text" class="form-control input-medium" placeholder="IPStart">
- <span class="conn-symbol">-</span>
- <input :active="selectableRange + ''" @click="inputTouch(0, $event)" v-model="selectableIPEnd" type="text" class="form-control input-medium" placeholder="IPEnd">
- </div>
- <div class="form-group">
- <input :active="!selectableRange + ''" @click="inputTouch(1, $event)" v-model="selectableIP" type="text" class="form-control input-medium" placeholder="IP">
- </div>
- <div class="btn-groups">
- <a @click="searchIp" class="btn btn-default" title="<@spring.message 'common.search'/>"><i class="fa fa-search"></i></a>
- <a @click="searchReset" class="btn btn-default" title="<@spring.message 'common.reset'/>"><i class="fa fa-refresh"></i></a>
- </div>
- </div>
- <div style="clear:both"></div>
- <div id="selectable-box" class="node-box" :style="'height:' + height + 'px'">
- <table class="r-table">
- <thead>
- <tr>
- <th max-width="47px"></th>
- <th width="30px"><span class="r-checkbox checkbox_false_full" id="selectable-checkall" @click="checkAll"/></th>
- <th class="r-tab-th">IP</th>
- <th class="r-tab-th">类型</th>
- <th class="r-tab-th">状态</th>
- </tr>
- </thead>
- <tbody>
- <template v-for="(selectable,index) in selectableNodes">
- <tr :class="{'new-node': selectable.newNode}" class="selectable" @click="check" :uuid="selectable.uuid" :id="'selectable-' + selectable.uuid" :iplong="selectable.ipLong">
- <td>{{index+1}}</td>
- <td><span class="r-checkbox checkbox_false_full"></span></td>
- <td v-for="(item) in colModel" v-html="typeof item.formatter == 'undefined' || item.formatter == null ? selectable[item.field] : item.formatter(selectable)"></td>
- </tr>
- </template>
- </tbody>
- </table>
- </div>
- <div class="box_counter">已选&nbsp;&nbsp;<span>{{selectableCount}}</span>&nbsp;/&nbsp;{{selectableTotalCount}}</div>
- </div>
- <span class="box_toright myicon-right1" @click="nodeRelChange(0)"></span>
- <span class="box_toleft myicon-left1" @click="nodeRelChange(1)"></span>
- <span class="box_reset myicon-reset" @click="nodeReset"></span>
- </div>
+ <div>
+ <!--已分配-->
+ <div class="box">
+ <div class="title"><@spring.message 'common.alreadyAssign'/></div>
+ <div class="tools">
+ <div class="form-group">
+ <input :active="selectedRange + ''" @click="inputTouch(0, $event)" v-model="$v.selectedIPStart.$model"
+ type="text" class="form-control input-medium" placeholder="IPStart" id="selectedIPStart"
+ :class="{'form-control--error': $v.selectedIPStart.$dirty && (!$v.selectedIPStart.required || !$v.selectedIPStart.ipAddress)}">
+ <span class="conn-symbol">-</span>
+ <input :active="selectedRange + ''" @click="inputTouch(0, $event)" v-model="$v.selectedIPEnd.$model"
+ type="text" class="form-control input-medium" placeholder="IPEnd" id="selectedIPEnd"
+ :class="{'form-control--error': $v.selectedIPEnd.$dirty && (!$v.selectedIPEnd.required || !$v.selectedIPEnd.ipAddress || !selectedIPEndSizeValidation)}">
+ </div>
+ <div class="form-group">
+ <input :active="!selectedRange + ''" @click="inputTouch(1, $event)" v-model="selectedIP" type="text"
+ class="form-control input-medium" placeholder="IP" id="selectedIP">
+ </div>
+ <div class="btn-groups">
+ <a @click="searchIp" class="btn btn-default" title="<@spring.message 'common.search'/>"><i
+ class="fa fa-search"></i></a>
+ <a @click="searchReset" class="btn btn-default" title="<@spring.message 'common.reset'/>"><i
+ class="fa fa-refresh"></i></a>
+ </div>
+ </div>
+ <div style="clear:both"></div>
+ <div id="selected-box" class="node-box" :style="'height:' + height + 'px'">
+ <table class="r-table">
+ <thead>
+ <tr>
+ <th max-width="47px"></th>
+ <th width="30px">
+ <span class="r-checkbox checkbox_false_full" :class="[selectedUuids.length == 0 ? 'checkbox_false_full' : (selectedUuids.length < selectedNodes.length ? 'checkbox_false_part' : (selectedUuids.length == selectedNodes.length ? 'checkbox_true_part' : ''))]" id="selected-checkall"
+ @click="checkAll($event, 'selected')"/></th>
+ <th width="120px" class="r-tab-th">IP</th>
+ <th class="r-tab-th"><@spring.message 'node.type'/></th>
+ <th class="r-tab-th"><@spring.message 'common.status'/></th>
+ </tr>
+ </thead>
+ <tbody>
+ <template v-for="(selected,index) in selectedNodes">
+ <tr :class="[{'new-node': selected.newNode},selected.checkedBox1 == true ? 'success' : '']" class="selected" @click="check(selected,'selected')"
+ :uuid="selected.uuid" :id="'selected-' + selected.uuid" :iplong="selected.ipLong">
+ <td>{{index+1}}</td>
+ <td><span class="r-checkbox" :class="selected.checkedBox1 == true ? 'checkbox_true_full' : 'checkbox_false_full'"></span></td>
+ <td v-for="(item) in colModel"
+ v-html="typeof item.formatter == 'undefined' || item.formatter == null ? selected[item.field] : item.formatter(selected)"></td>
+ </tr>
+ </template>
+ </tbody>
+ </table>
+ </div>
+
+ <!--已选/ 计数-->
+ <div class="box_counter"><@spring.message 'common.selected'/>&nbsp;&nbsp;<span>{{selectedCount}}</span>&nbsp;/&nbsp;{{selectedTotalCount}}
+ </div>
+ </div>
+
+
+
+
+
+ <!--可分配-->
+ <div class="box">
+ <div class="title"><@spring.message 'common.readyAssign'/></div>
+ <div class="tools">
+ <div class="form-group">
+ <input :active="selectableRange + ''" @click="inputTouch(0, $event)" v-model="$v.selectableIPStart.$model"
+ type="text" class="form-control input-medium" placeholder="IPStart" id="selectableIPStart"
+ :class="{'form-control--error': $v.selectableIPStart.$dirty && (!$v.selectableIPStart.required || !$v.selectableIPStart.ipAddress)}">
+ <span class="conn-symbol">-</span>
+ <input :active="selectableRange + ''" @click="inputTouch(0, $event)" v-model="$v.selectableIPEnd.$model"
+ type="text" class="form-control input-medium" placeholder="IPEnd" id="selectableIPEnd"
+ :class="{'form-control--error': $v.selectableIPEnd.$dirty && (!$v.selectableIPEnd.required || !$v.selectableIPEnd.ipAddress || !selectableIPEndSizeValidation)}">
+ </div>
+ <div class="form-group">
+ <input :active="!selectableRange + ''" @click="inputTouch(1, $event)" v-model="selectableIP"
+ type="text" class="form-control input-medium" placeholder="IP" id="selectableIP">
+ </div>
+ <div class="btn-groups">
+ <a @click="searchIp" class="btn btn-default" title="<@spring.message 'common.search'/>"><i
+ class="fa fa-search"></i></a>
+ <a @click="searchReset" class="btn btn-default" title="<@spring.message 'common.reset'/>"><i
+ class="fa fa-refresh"></i></a>
+ </div>
+ </div>
+ <div style="clear:both"></div>
+ <div id="selectable-box" class="node-box" :style="'height:' + height + 'px'">
+ <table class="r-table">
+ <thead>
+ <tr>
+ <th max-width="47px"></th>
+ <th width="30px"><span class="r-checkbox checkbox_false_full" :class="[selectableUuids.length == 0 ? 'checkbox_false_full' : (selectableUuids.length < selectableNodes.length ? 'checkbox_false_part' : (selectableUuids.length == selectableNodes.length ? 'checkbox_true_part' : ''))]" id="selectable-checkall"
+ @click="checkAll($event, 'selectable')"/></th>
+ <th class="r-tab-th">IP</th>
+ <th class="r-tab-th"><@spring.message 'node.type'/></th>
+ <th class="r-tab-th"><@spring.message 'common.status'/></th>
+ </tr>
+ </thead>
+ <tbody>
+ <template v-for="(selectable,index) in selectableNodes">
+ <tr :class="[{'new-node': selectable.newNode},selectable.checkedBox1 == true ? 'success' : '']" class="selectable" @click="check(selectable,'selectable')"
+ :uuid="selectable.uuid" :id="'selectable-' + selectable.uuid" :iplong="selectable.ipLong">
+ <td>{{index+1}}</td>
+ <td><span class="r-checkbox" :class="selectable.checkedBox1 == true ? 'checkbox_true_full' : 'checkbox_false_full'"></span></td>
+ <td v-for="(item) in colModel"
+ v-html="typeof item.formatter == 'undefined' || item.formatter == null ? selectable[item.field] : item.formatter(selectable)"></td>
+ </tr>
+ </template>
+ </tbody>
+ </table>
+ </div>
+
+ <!--已选/ 计数-->
+ <div class="box_counter"><@spring.message 'common.selected'/>&nbsp;&nbsp;<span>{{selectableCount}}</span>&nbsp;/&nbsp;{{selectableTotalCount}}
+ </div>
+ </div>
+
+
+ <span class="box_toright myicon-right1" @click="nodeRelChange(0)"></span>
+ <span class="box_toleft myicon-left1" @click="nodeRelChange(1)"></span>
+ <span class="box_reset myicon-reset" @click="nodeReset"></span>
+ </div>
</script> \ No newline at end of file
diff --git a/nezha-admin/src/main/resources/templates/modules/node/nodeGroup.html b/nezha-admin/src/main/resources/templates/modules/node/nodeGroup.html
index 680b2319..3dfb9920 100644
--- a/nezha-admin/src/main/resources/templates/modules/node/nodeGroup.html
+++ b/nezha-admin/src/main/resources/templates/modules/node/nodeGroup.html
@@ -127,6 +127,7 @@
v-on:node-change="nodeChange"
:init-selected-nodes="selectedNodes"
:init-selectable-nodes="selectableNodes"
+ ref="nodeRel"
></node-rel-component>
</div>