import {
Component,
Input,
OnInit,
SimpleChange,
Output,
EventEmitter,
} from "@angular/core";
import { ValidationErrors } from "@angular/forms";
import { TranslateService } from "@ngx-translate/core";
import { IOption } from "paletx";
@Component({
selector: "app-center-ip-config",
templateUrl: "./center-ip-config.component.html",
styleUrls: ["./center-ip-config.component.less"],
})
export class CenterIpConfigComponent implements OnInit {
@Input() item: any; // 每一条ip信息内容
@Input() errNetworkid: boolean;
@Input() networkOptions: any; // 所有网络平面信息(下拉选项)
@Input() tab: any; // tab
@Output() change = new EventEmitter<any>();
public typesOptions: IOption[] = [
// 传输协议类型(下拉选项)
{ value: "udp", label: "udp" },
];
public typeOptions: IOption[] = [
// 传输协议类型(下拉选项)
{ value: "QUIC", label: "QUIC" },
{ value: "WSS", label: "WSS" },
];
valid: boolean; // 每一条ip信息校验是否通过标志
errors: ValidationErrors = {
noNet: false,
noType: false,
atLeastOne: false,
atLeastOne_: false,
ipv4_fmt_err: false,
ipv6_fmt_err: false,
domain_fmt_err: false,
port_fmt_err: false,
};
// 错误提示
errorTips = {
atLeastOne: this.translate.instant("platform.center_node.at_least_one_ip"),
atLeastOne_: this.translate.instant("platform.center_node.at_least_one"),
ipv4_fmt_err: this.translate.instant("platform.node.ipv4_fmt_err"),
ipv6_fmt_err: this.translate.instant("platform.node.ipv6_fmt_err"),
port_fmt_err: this.translate.instant("platform.center_node.port_fmt_err"),
domain_fmt_err: this.translate.instant("platform.node.domain_fmt_err"),
ipv4_domain_fmt_err: this.translate.instant(
"platform.node.ipv4_domain_fmt_err"
),
errNetworkid: this.translate.instant(
"platform.node.err_repeat_networkid"
),
};
// 正则
public patterns = {
ipv4: /^((\d|[1-9]\d|1\d\d|2([0-4]\d|5[0-5]))\.){4}$/,
ipv6: /^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*$/,
port: /^([0-9]|[1-9]\d|[1-9]\d{2}|[1-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$/,
domain:
/^(?=^.{3,255}$)[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+$/,
};
constructor(private translate: TranslateService) { }
ngOnInit() {
if (!this.networkOptions) this.networkOptions = [];
if (!this.item) {
this.errors = {
noNet: true,
atLeastOne: true,
noType: true,
port_fmt_err: true,
atLeastOne_: true
};
this.item = {
networkid: null,
network_ipv4: "",
network_ipv6: "",
port: null,
domain: "",
transport: null,
};
}
}
ngOnChanges(changes: SimpleChange) {
if (changes.hasOwnProperty("item")) {
if (!this.item) this.item = {};
this.checkRequired(this.tab);
if (this.item != undefined) {
if (this.item.network_ipv4 != "") {
this.checkIpv4();
}
if (this.item.network_ipv6 != "") {
this.checkIpv6();
}
if (this.item.port != "" && this.item.port != null) {
this.checkPort();
}
if (this.item.domain != "" && this.item.domain != null) {
this.checkDomain();
}
}
}
this.check();
}
// 选中网络平面
onSelected(v) {
this.item.networkid = Number(v);
this.checkRequired(this.tab);
this.check();
}
onSelectedType(v) {
this.item.transport = v;
this.checkRequired(this.tab);
this.check();
}
// IPv4和IPv6二选一
checkBothEmpty() {
if (!this.item) this.errors.atLeastOne = true;
if (
(!this.item.network_ipv4 || this.item.network_ipv4.length < 1) &&
(!this.item.network_ipv6 || this.item.network_ipv6.length < 1)
) {
this.errors.atLeastOne = true;
} else {
this.errors.atLeastOne = false;
}
}
// ipv4、ipv6、域名三选一
checkAllEmpty() {
if (!this.item) this.errors.atLeastOne_ = true;
if (
(!this.item.network_ipv4 || this.item.network_ipv4.length < 1) &&
(!this.item.network_ipv6 || this.item.network_ipv6.length < 1) &&
(!this.item.domain || this.item.domain.length < 1)
) {
this.errors.atLeastOne_ = true;
} else {
this.errors.atLeastOne_ = false;
}
}
// SIP校验ipv4、ipv6二选一,接入点校验ipv4、ipv6、域名三选一
checkRequired(tab) {
switch (tab) {
case 0:
this.checkBothEmpty();
break;
case 1:
this.checkBothEmpty();
break;
case 2:
this.checkAllEmpty();
break;
case 3:
this.checkAllEmpty();
break;
}
}
// 校验ipv4
checkIpv4() {
let ipv4 = this.item.network_ipv4;
if (ipv4 == "" || this.patterns.ipv4.test(ipv4 + ".")) {
this.errors.ipv4_fmt_err = false;
} else {
this.errors.ipv4_fmt_err = true;
}
}
// 校验ipv6
checkIpv6() {
let ipv6 = this.item.network_ipv6;
if (ipv6 == "" || this.patterns.ipv6.test(ipv6)) {
this.errors.ipv6_fmt_err = false;
} else {
this.errors.ipv6_fmt_err = true;
}
}
checkDomain() {
let domain = this.item.domain;
if (domain == "" || this.patterns.domain.test(domain)) {
this.errors.domain_fmt_err = false;
} else {
this.errors.domain_fmt_err = true;
}
}
// 校验端口
checkPort() {
let port = this.item.port;
if (port && this.patterns.port.test(port)) {
this.errors.port_fmt_err = false;
} else {
this.errors.port_fmt_err = true;
}
}
// 检查是否无错,并输出
check() {
let tab = this.tab;
this.item.networkid == undefined
? (this.errors.noNet = true)
: (this.errors.noNet = false);
if (tab == 3 || tab == 0) {
this.item.transport == undefined
? (this.errors.noType = true)
: (this.errors.noType = false);
}
if (tab == 0) {
// 校验ipv4、ipv6二选一
if (
this.errors.noNet ||
this.errors.noType ||
this.errors.ipv4_fmt_err ||
this.errors.ipv6_fmt_err ||
this.errors.port_fmt_err ||
this.errors.atLeastOne
) {
this.valid = false;
} else {
this.valid = true;
}
} else if (tab == 1) {
if (
this.errors.noNet ||
this.errors.ipv4_fmt_err ||
this.errors.ipv6_fmt_err ||
this.errors.port_fmt_err ||
this.errors.atLeastOne
) {
this.valid = false;
} else {
this.valid = true;
}
} else if (tab == 2) {
// 接入点校验ipv4、ipv6、域名三选一
if (
this.errors.noNet ||
this.errors.ipv4_fmt_err ||
this.errors.ipv6_fmt_err ||
this.errors.domain_fmt_err ||
this.errors.port_fmt_err ||
this.errors.atLeastOne_
) {
this.valid = false;
} else {
this.valid = true;
}
}
else if (tab == 2 || tab == 3) {
// 接入点校验ipv4、ipv6、域名三选一
if (
this.errors.noNet ||
this.errors.noType ||
this.errors.ipv4_fmt_err ||
this.errors.ipv6_fmt_err ||
this.errors.domain_fmt_err ||
this.errors.port_fmt_err ||
this.errors.atLeastOne_
) {
this.valid = false;
} else {
this.valid = true;
}
}
this.change.emit({
valid: this.valid,
data: this.item,
});
}
ipv4ValueChange(e) {
this.checkIpv4();
this.checkRequired(this.tab);
this.checkPort();
this.check();
}
ipv6ValueChange(e) {
this.checkIpv6();
this.checkRequired(this.tab);
this.checkPort();
this.check();
}
portValueChange(e) {
this.checkBothEmpty();
this.checkPort();
this.check();
}
domainValueChange(e) {
this.checkRequired(this.tab);
this.checkDomain();
this.check();
}
}
<div class="centerIpWrap">
<div class="ipInfoWrap">
<!-- 网络平面下拉选项 -->
<div class="networkWrap">
<app-single-network-conf [networkid]="item.networkid" [networkOptions]="networkOptions" (change)="onSelected($event)"></app-single-network-conf>
<span *ngIf="errNetworkid" class="error-msg">{{ errorTips.errNetworkid }}
</span>
</div>
<!-- IPv4输入框及错误提示 -->
<div class="ipv4Wrap">
<plx-text-input placeholder="IPv4" width="152px" [(ngModel)]="item.network_ipv4" (inputValueChange)="ipv4ValueChange($event)"></plx-text-input>
<div *ngIf="!valid" class="error-msg-container">
<span *ngIf="errors.ipv4_fmt_err" class="error-msg">{{ errorTips.ipv4_fmt_err }}
</span>
</div>
</div>
<!-- IPv4或域名输入框及错误提示 -->
<!-- <div *ngIf="tab==1" class="ipv4Wrap">
<plx-text-input
placeholder="IPv4或域名"
width="152px"
[(ngModel)]="item.network_ipv4"
(inputValueChange)="ipv4OrDomainValueChange($event)"
></plx-text-input>
<div *ngIf="!valid" class="error-msg-container">
<span *ngIf="errors.ipv4_domain_fmt_err" class="error-msg">{{
errorTips.ipv4_domain_fmt_err
}}</span>
</div>
</div> -->
<!-- IPv6输入框及错误提示 -->
<div class="ipv6Wrap">
<plx-text-input placeholder="IPv6" width="317px" [(ngModel)]="item.network_ipv6" (inputValueChange)="ipv6ValueChange($event)"></plx-text-input>
<div *ngIf="!valid" class="error-msg-container">
<span *ngIf="errors.ipv6_fmt_err" class="error-msg">{{ errorTips.ipv6_fmt_err }}
</span>
</div>
</div>
<!-- 端口输入框及错误提示 -->
<div class="portWrap">
<plx-text-input placeholder="{{ 'system.dcs_config.port' | translate }}" width="160px" [(ngModel)]="item.port" (inputValueChange)="portValueChange($event)"></plx-text-input>
<div *ngIf="!valid" class="error-msg-container">
<span *ngIf="errors.port_fmt_err" class="error-msg">{{ errorTips.port_fmt_err }}
</span>
</div>
</div>
<!-- 传输协议下拉选项 -->
<div class="protocolType" *ngIf="tab == 0">
<app-sbc-protocol-type [transport]="item.transport" [typesOptions]="typesOptions" (change)="onSelectedType($event, idx)"></app-sbc-protocol-type>
</div>
<!-- 传输协议下拉选项 -->
<div class="protocolType" *ngIf="tab == 3">
<app-sbc-protocol-type [transport]="item.transport" [typesOptions]="typeOptions" (change)="onSelectedType($event, idx)"></app-sbc-protocol-type>
</div>
<!-- 域名输入框及错误提示 -->
<div class="domainWrap" *ngIf="tab == 2||tab == 3">
<plx-text-input placeholder="{{ 'system.dcs_config.domain' | translate }}" width="160px" [(ngModel)]="item.domain" (inputValueChange)="domainValueChange($event)"></plx-text-input>
<div *ngIf="!valid" class="error-msg-container">
<span *ngIf="errors.domain_fmt_err" class="error-msg">{{ errorTips.domain_fmt_err }}
</span>
</div>
</div>
</div>
<!-- 提示:IPv4与IPv6地址至少填一项 -->
<div *ngIf="!valid" class="error-msg-container row-bottom">
<span *ngIf="errors.atLeastOne && (tab == 0||tab == 1)" class="error-msg">{{ errorTips.atLeastOne }}
</span>
<span *ngIf="errors.atLeastOne_ && (tab == 2||tab == 3)" class="error-msg">{{ errorTips.atLeastOne_ }}
</span>
</div>
</div>
import {
Component,
Input,
OnInit,
Output,
EventEmitter,
SimpleChange,
} from "@angular/core";
@Component({
selector: "app-center-ip-config-group",
templateUrl: "./center-ip-config-group.component.html",
styleUrls: ["./center-ip-config-group.component.less"],
})
export class CenterIpConfigGroupComponent implements OnInit {
@Input() ipInfo: any; // 整组ip信息内容
@Input() networkOptions: any; // 所有网络平面信息(下拉选项)
@Input() canEmpty?: any; // ip信息组可为空
@Input() tab: any; // tab
@Input() refer: string;
@Output() change = new EventEmitter<any>();
@Input() instanceid: any; // 整组ip的标志
public validArray = []; // 判断每一条IP配置是否合法
errNetworkid: boolean = false;
newIds = []
constructor() { }
ngOnInit() {
}
ngOnChanges(changes: SimpleChange) {
this.validArray = [];
}
// 添加一条配置
addIpItem() {
this.ipInfo = this.ipInfo ? this.ipInfo : []
let item = {
networkid: null,
network_ipv4: "",
network_ipv6: "",
port: null,
domain: "",
transport: null,
};
this.ipInfo.push(item);
this.validArray.push(false);
this.change.emit(this.outputInfo());
}
// 删除一条配置
removeIpItem(idx) {
this.ipInfo.splice(idx, 1);
this.validArray.splice(idx, 1);
this.change.emit(this.outputInfo());
}
// 一条配置改变
onItemChanged(e, idx) {
if (e && e.hasOwnProperty("valid")) {
this.ipInfo[idx] = e.data;
this.validArray[idx] = e.valid;
}
this.change.emit(this.outputInfo());
}
// 校验是否通过
isValid() {
let valid = this.validArray;
if (!valid) return true;
for (let i = 0; i < valid.length; i++) {
if (!valid[i]) return false;
}
return true;
}
outputInfo() {
if (this.tab == 4) {
return {
valid: this.isValid(),
data: this.ipInfo,
instanceid: this.instanceid
};
} else {
return {
valid: this.isValid(),
data: this.ipInfo,
};
}
}
}
<div class="centerIpConfigGroupWrap">
<!-- ip信息组及删除按钮 -->
<div class="ipInfo" *ngFor="let item of ipInfo; let idx = index">
<app-center-ip-config
[item]="item"
[errNetworkid]="errNetworkid"
[networkOptions]="networkOptions"
[tab]="tab"
(change)="onItemChanged($event, idx)"
></app-center-ip-config>
<i
*ngIf="ipInfo.length > 1 || canEmpty"
(click)="removeIpItem(idx)"
aria-hidden="true"
class="plx-ico-remove-16 plx-form-custom-icon-hover"
></i>
</div>
<!-- 添加配置按钮 -->
<button
(click)="addIpItem()"
type="button"
class="plx-btn plx-btn-xs"
style="border: 0; padding: 0"
>
<i class="plx-btn-icon plx-ico-new-16"></i
>{{ "platform.node.add_net_conf" | translate }}
</button>
</div>