|
@@ -1,5 +1,18 @@
|
|
<template>
|
|
<template>
|
|
<div class="dialer-container">
|
|
<div class="dialer-container">
|
|
|
|
+ <audio
|
|
|
|
+ src="@/assets/audio/phone_ringing.mp3"
|
|
|
|
+ loop
|
|
|
|
+ hidden="true"
|
|
|
|
+ ref="phone_ringing"
|
|
|
|
+ ></audio>
|
|
|
|
+ <audio
|
|
|
|
+ src="@/assets/audio/phone_trying.mp3"
|
|
|
|
+ loop
|
|
|
|
+ hidden="true"
|
|
|
|
+ ref="phone_trying"
|
|
|
|
+ ></audio>
|
|
|
|
+ <audio autoplay ref="callAudio"></audio>
|
|
<!-- 显示输入的电话号码 -->
|
|
<!-- 显示输入的电话号码 -->
|
|
<el-input type="text" v-model="currentPhoneNumber" readonly />
|
|
<el-input type="text" v-model="currentPhoneNumber" readonly />
|
|
<div class="dialer-buttons">
|
|
<div class="dialer-buttons">
|
|
@@ -13,20 +26,53 @@
|
|
>
|
|
>
|
|
{{ number }}
|
|
{{ number }}
|
|
</el-button>
|
|
</el-button>
|
|
- <audio v-show="false" controls autoplay="autoplay" id="audioCtl"></audio>
|
|
|
|
</div>
|
|
</div>
|
|
- <!-- 语音输入按钮 -->
|
|
|
|
- <el-button type="info" @click="startVoiceInput"> 语音输入 </el-button>
|
|
|
|
- <!-- 清除输入的电话号码 -->
|
|
|
|
- <el-button type="warning" @click="clearNumber">清除</el-button>
|
|
|
|
- <!-- 模拟拨号操作 -->
|
|
|
|
- <el-button type="success" @click="callNumber">拨号</el-button>
|
|
|
|
- <!-- 模拟拨号操作 -->
|
|
|
|
- <el-button type="danger" @click="downNumber">挂断</el-button>
|
|
|
|
|
|
+ <div
|
|
|
|
+ v-for="(phone, index) in phones"
|
|
|
|
+ :key="index"
|
|
|
|
+ :label="phone.name"
|
|
|
|
+ :name="phone.name"
|
|
|
|
+ >
|
|
|
|
+ <!-- 拨号 -->
|
|
|
|
+ <el-button :disabled="!phone.enableCall" @click="handleCall(phone)">
|
|
|
|
+ 拨号
|
|
|
|
+ </el-button>
|
|
|
|
+ <el-button
|
|
|
|
+ type="info"
|
|
|
|
+ :disabled="!phone.enableCall"
|
|
|
|
+ @click="clearNumber(1)"
|
|
|
|
+ >
|
|
|
|
+ 回退
|
|
|
|
+ </el-button>
|
|
|
|
+ <!-- 清除输入的电话号码 -->
|
|
|
|
+ <el-button
|
|
|
|
+ type="warning"
|
|
|
|
+ :disabled="!phone.enableCall"
|
|
|
|
+ @click="clearNumber(2)"
|
|
|
|
+ >清除</el-button
|
|
|
|
+ >
|
|
|
|
+ <!-- 模拟接听操作 -->
|
|
|
|
+ <el-button
|
|
|
|
+ type="success"
|
|
|
|
+ :disabled="!phone.enableAnswer"
|
|
|
|
+ @click="handleAnswer(phone)"
|
|
|
|
+ >接听</el-button
|
|
|
|
+ >
|
|
|
|
+ <!-- 模拟拨号操作 -->
|
|
|
|
+ <el-button
|
|
|
|
+ type="danger"
|
|
|
|
+ :disabled="!phone.enableHungup"
|
|
|
|
+ @click="handleHungup(phone)"
|
|
|
|
+ >挂断</el-button
|
|
|
|
+ >
|
|
|
|
+ </div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
|
|
|
|
- <script>
|
|
|
|
|
|
+<script>
|
|
|
|
+import { getSipList } from "@/API/sip";
|
|
|
|
+import { mapGetters } from "vuex";
|
|
|
|
+
|
|
export default {
|
|
export default {
|
|
props: {
|
|
props: {
|
|
phoneNumber: {
|
|
phoneNumber: {
|
|
@@ -36,23 +82,43 @@ export default {
|
|
},
|
|
},
|
|
data() {
|
|
data() {
|
|
return {
|
|
return {
|
|
- id: this.generateGuid(),
|
|
|
|
- baseUrl: "api/webrtc/",
|
|
|
|
- pc: null,
|
|
|
|
// 拨号盘上的数字和符号
|
|
// 拨号盘上的数字和符号
|
|
numbers: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "*", "0", "#"],
|
|
numbers: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "*", "0", "#"],
|
|
|
|
+ // 拨号链接
|
|
|
|
+ clientId: "",
|
|
|
|
+ dispalyDialog: false,
|
|
|
|
+ activeName: "",
|
|
|
|
+ sips: [],
|
|
|
|
+ phones: [],
|
|
|
|
+ pc: null,
|
|
|
|
+ localStream: null,
|
|
};
|
|
};
|
|
},
|
|
},
|
|
- computed: {
|
|
|
|
- getOfferUrl() {
|
|
|
|
- return `${this.baseUrl}getoffer?id=${this.id}`;
|
|
|
|
- },
|
|
|
|
- setAnswerUrl() {
|
|
|
|
- return `${this.baseUrl}setanswer?id=${this.id}`;
|
|
|
|
|
|
+ created() {
|
|
|
|
+ this.init();
|
|
|
|
+ },
|
|
|
|
+ watch: {
|
|
|
|
+ "voiceCallDialog.show": {
|
|
|
|
+ handler(newVal) {
|
|
|
|
+ if (newVal && localStorage.getItem("token") !== null) {
|
|
|
|
+ this.init();
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ // deep: true,
|
|
|
|
+ immediate: true,
|
|
},
|
|
},
|
|
- setIceCandidateUrl() {
|
|
|
|
- return `${this.baseUrl}addicecandidate?id=${this.id}`;
|
|
|
|
|
|
+ phoneNumber: {
|
|
|
|
+ handler(newVal) {
|
|
|
|
+ if (newVal && newVal.length >= 5) {
|
|
|
|
+ this.phones[0].no = newVal;
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ // deep: true,
|
|
|
|
+ immediate: true,
|
|
},
|
|
},
|
|
|
|
+ },
|
|
|
|
+ computed: {
|
|
|
|
+ ...mapGetters(["voiceCallDialog"]),
|
|
currentPhoneNumber: {
|
|
currentPhoneNumber: {
|
|
get() {
|
|
get() {
|
|
return this.phoneNumber;
|
|
return this.phoneNumber;
|
|
@@ -67,116 +133,275 @@ export default {
|
|
appendNumber(number) {
|
|
appendNumber(number) {
|
|
this.currentPhoneNumber += number;
|
|
this.currentPhoneNumber += number;
|
|
},
|
|
},
|
|
- clearNumber() {
|
|
|
|
- this.currentPhoneNumber = "";
|
|
|
|
- },
|
|
|
|
- callNumber() {
|
|
|
|
- if (this.currentPhoneNumber) {
|
|
|
|
- alert(`正在拨打号码: ${this.currentPhoneNumber}`);
|
|
|
|
- this.start();
|
|
|
|
- } else {
|
|
|
|
- alert("请输入电话号码");
|
|
|
|
|
|
+ clearNumber(type) {
|
|
|
|
+ switch (type) {
|
|
|
|
+ case 1:
|
|
|
|
+ this.currentPhoneNumber = this.currentPhoneNumber.slice(0, -1);
|
|
|
|
+ break;
|
|
|
|
+ case 2:
|
|
|
|
+ this.currentPhoneNumber = "";
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
},
|
|
},
|
|
- downNumber() {
|
|
|
|
- this.closePeer();
|
|
|
|
|
|
+ beforeDialogClose() {
|
|
|
|
+ console.log("beforeDialogClose");
|
|
|
|
+ this.dispalyDialog = false;
|
|
},
|
|
},
|
|
- startVoiceInput() {
|
|
|
|
- const recognition = new (window.SpeechRecognition ||
|
|
|
|
- window.webkitSpeechRecognition)();
|
|
|
|
- recognition.lang = "zh-CN";
|
|
|
|
-
|
|
|
|
- recognition.onresult = (event) => {
|
|
|
|
- const transcript = event.results[0][0].transcript;
|
|
|
|
- this.currentPhoneNumber = transcript.replace(/[^0-9*#]/g, "");
|
|
|
|
- };
|
|
|
|
- recognition.start();
|
|
|
|
|
|
+ click() {
|
|
|
|
+ this.dispalyDialog = true;
|
|
},
|
|
},
|
|
-
|
|
|
|
- generateGuid() {
|
|
|
|
- return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(
|
|
|
|
- /[xy]/g,
|
|
|
|
- function (c) {
|
|
|
|
- var r = (Math.random() * 16) | 0,
|
|
|
|
- v = c == "x" ? r : (r & 0x3) | 0x8;
|
|
|
|
- return v.toString(16);
|
|
|
|
- }
|
|
|
|
- );
|
|
|
|
|
|
+ handleCall(phone) {
|
|
|
|
+ if (!phone.no) {
|
|
|
|
+ this.$message.error("请先输入号码");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ phone.ws.send(JSON.stringify({ cmd: 1, no: phone.no }));
|
|
},
|
|
},
|
|
- async start() {
|
|
|
|
- this.closePeer();
|
|
|
|
|
|
+ handleAnswer(phone) {
|
|
|
|
+ phone.ws.send(JSON.stringify({ cmd: 2 }));
|
|
|
|
+ },
|
|
|
|
+ handleHungup(phone) {
|
|
|
|
+ phone.ws.send(JSON.stringify({ cmd: 3 }));
|
|
|
|
+ this.$refs.phone_trying.pause();
|
|
|
|
+ this.$refs.phone_ringing.pause();
|
|
|
|
+ this.stopPeer();
|
|
|
|
+ },
|
|
|
|
+ async startPeer(phone) {
|
|
|
|
+ if (this.pc) this.pc.close();
|
|
|
|
+ this.pc = new RTCPeerConnection();
|
|
|
|
|
|
- let videoControl = document.querySelector("#audioCtl");
|
|
|
|
|
|
+ this.pc.ontrack = (evt) => {
|
|
|
|
+ console.log("ontrack");
|
|
|
|
+ this.$refs.callAudio.srcObject = evt.streams[0];
|
|
|
|
+ };
|
|
|
|
|
|
- const localStream = await navigator.mediaDevices.getUserMedia({
|
|
|
|
|
|
+ this.localStream = await navigator.mediaDevices.getUserMedia({
|
|
video: false,
|
|
video: false,
|
|
audio: true,
|
|
audio: true,
|
|
});
|
|
});
|
|
- videoControl.srcObject = localStream;
|
|
|
|
-
|
|
|
|
- this.pc = new RTCPeerConnection(null);
|
|
|
|
-
|
|
|
|
- localStream.getTracks().forEach((track) => {
|
|
|
|
|
|
+ this.localStream.getTracks().forEach((track) => {
|
|
console.log("add local track " + track.kind + " to peer connection.");
|
|
console.log("add local track " + track.kind + " to peer connection.");
|
|
console.log(track);
|
|
console.log(track);
|
|
- this.pc.addTrack(track, localStream);
|
|
|
|
|
|
+ this.pc.addTrack(track, this.localStream);
|
|
});
|
|
});
|
|
|
|
|
|
- this.pc.onicegatheringstatechange = function () {
|
|
|
|
|
|
+ this.pc.onicegatheringstatechange = () => {
|
|
console.log("onicegatheringstatechange: " + this.pc.iceGatheringState);
|
|
console.log("onicegatheringstatechange: " + this.pc.iceGatheringState);
|
|
- }.bind(this);
|
|
|
|
|
|
+ };
|
|
|
|
|
|
- this.pc.oniceconnectionstatechange = function () {
|
|
|
|
|
|
+ this.pc.oniceconnectionstatechange = () => {
|
|
console.log(
|
|
console.log(
|
|
"oniceconnectionstatechange: " + this.pc.iceConnectionState
|
|
"oniceconnectionstatechange: " + this.pc.iceConnectionState
|
|
);
|
|
);
|
|
- }.bind(this);
|
|
|
|
|
|
+ if (this.pc.iceConnectionState === "disconnected") {
|
|
|
|
+ this.handleHungup(phone);
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ this.pc.onconnectionstatechange = () => {
|
|
|
|
+ console.log("onconnectionstatechange: " + this.pc.connectionState);
|
|
|
|
+ };
|
|
|
|
|
|
- this.pc.onsignalingstatechange = function () {
|
|
|
|
|
|
+ this.pc.onsignalingstatechange = () => {
|
|
console.log("onsignalingstatechange: " + this.pc.signalingState);
|
|
console.log("onsignalingstatechange: " + this.pc.signalingState);
|
|
- }.bind(this);
|
|
|
|
|
|
+ // if (this.pc.signalingState == 'have-remote-offer') {
|
|
|
|
+ // this.pc.createAnswer().then((answer) => {
|
|
|
|
+ // this.pc.setLocalDescription(answer)
|
|
|
|
+ // console.log('Sending answer SDP.')
|
|
|
|
+ // console.log('SDP: ' + answer)
|
|
|
|
+ // phone.ws.send(JSON.stringify({ cmd: 5, body: JSON.stringify(answer) }))
|
|
|
|
+ // })
|
|
|
|
+ // }
|
|
|
|
+ };
|
|
|
|
|
|
- this.pc.onicecandidate = async function (event) {
|
|
|
|
|
|
+ this.pc.onicecandidate = (event) => {
|
|
if (event.candidate) {
|
|
if (event.candidate) {
|
|
console.log("new-ice-candidate:");
|
|
console.log("new-ice-candidate:");
|
|
console.log(event.candidate.candidate);
|
|
console.log(event.candidate.candidate);
|
|
console.log(event.candidate);
|
|
console.log(event.candidate);
|
|
- await fetch(this.setIceCandidateUrl, {
|
|
|
|
- method: "POST",
|
|
|
|
- body: JSON.stringify(event.candidate),
|
|
|
|
- headers: { "Content-Type": "application/json" },
|
|
|
|
- });
|
|
|
|
|
|
+ phone.ws.send(
|
|
|
|
+ JSON.stringify({ cmd: 4, body: JSON.stringify(event.candidate) })
|
|
|
|
+ );
|
|
}
|
|
}
|
|
- }.bind(this);
|
|
|
|
|
|
+ };
|
|
|
|
+ },
|
|
|
|
+ stopPeer() {
|
|
|
|
+ if (this.localStream) {
|
|
|
|
+ this.localStream.getTracks().forEach((track) => {
|
|
|
|
+ track.stop();
|
|
|
|
+ });
|
|
|
|
+ this.localStream = null;
|
|
|
|
+ }
|
|
|
|
+ if (this.pc) {
|
|
|
|
+ this.pc.close();
|
|
|
|
+ this.pc.ontrack = null;
|
|
|
|
+ this.pc.onicegatheringstatechange = null;
|
|
|
|
+ this.pc.oniceconnectionstatechange = null;
|
|
|
|
+ this.pc.onconnectionstatechange = null;
|
|
|
|
+ this.pc.onsignalingstatechange = null;
|
|
|
|
+ this.pc.onicecandidate = null;
|
|
|
|
+ this.pc = null;
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ async init() {
|
|
|
|
+ this.clientId = Math.random().toString(16).substring(2, 8);
|
|
|
|
+ try {
|
|
|
|
+ const res = await getSipList({ enable: true });
|
|
|
|
+ if (res.code === 20000) {
|
|
|
|
+ this.sips = res.data.content;
|
|
|
|
|
|
- let offerResponse = await fetch(this.getOfferUrl);
|
|
|
|
- let offer = await offerResponse.json();
|
|
|
|
- console.log("got offer: " + offer.type + " " + offer.sdp + ".");
|
|
|
|
- await this.pc.setRemoteDescription(offer);
|
|
|
|
|
|
+ if (this.sips) {
|
|
|
|
+ this.phones = this.sips.map((a) => {
|
|
|
|
+ const ws = new WebSocket(VUE_APP_BASE_WS() + "/SipOverWebSocket");
|
|
|
|
+ const obj = {
|
|
|
|
+ name: a.name,
|
|
|
|
+ no: "",
|
|
|
|
+ enableCall: true,
|
|
|
|
+ enableAnswer: false,
|
|
|
|
+ enableHungup: false,
|
|
|
|
+ ws,
|
|
|
|
+ };
|
|
|
|
+ const _this = this;
|
|
|
|
+ ws.onmessage = (evt) => {
|
|
|
|
+ const resp = JSON.parse(evt.data);
|
|
|
|
+ console.info(resp);
|
|
|
|
+ switch (resp.type) {
|
|
|
|
+ case "invite":
|
|
|
|
+ this.phoneNumber = resp.no;
|
|
|
|
+ obj.no = resp.no;
|
|
|
|
+ obj.enableCall = false;
|
|
|
|
+ obj.enableAnswer = true;
|
|
|
|
+ obj.enableHungup = true;
|
|
|
|
+ console.log(this.$refs.phone_ringing);
|
|
|
|
+ this.$refs.phone_ringing.currentTime = 0;
|
|
|
|
+ this.$refs.phone_ringing.play();
|
|
|
|
+ break;
|
|
|
|
+ case "trying":
|
|
|
|
+ this.$refs.phone_trying.currentTime = 0;
|
|
|
|
+ this.$refs.phone_trying.play();
|
|
|
|
+ break;
|
|
|
|
+ case "ringing":
|
|
|
|
+ this.$refs.phone_ringing.currentTime = 0;
|
|
|
|
+ this.$refs.phone_ringing.play();
|
|
|
|
+ break;
|
|
|
|
+ case "failed":
|
|
|
|
+ this.$message.error(resp.msg);
|
|
|
|
+ this.stopPeer();
|
|
|
|
+ this.$refs.phone_trying.pause();
|
|
|
|
+ this.$refs.phone_ringing.pause();
|
|
|
|
+ break;
|
|
|
|
+ case "answered":
|
|
|
|
+ this.$refs.phone_trying.pause();
|
|
|
|
+ this.$refs.phone_ringing.pause();
|
|
|
|
+ if (resp.isSelf) {
|
|
|
|
+ obj.enableCall = false;
|
|
|
|
+ obj.enableAnswer = false;
|
|
|
|
+ obj.enableHungup = true;
|
|
|
|
+ } else {
|
|
|
|
+ obj.no = "";
|
|
|
|
+ obj.enableCall = true;
|
|
|
|
+ obj.enableAnswer = false;
|
|
|
|
+ obj.enableHungup = false;
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ case "serverCallCancelled":
|
|
|
|
+ this.stopPeer();
|
|
|
|
+ this.$refs.phone_trying.pause();
|
|
|
|
+ this.$refs.phone_ringing.pause();
|
|
|
|
+ obj.no = "";
|
|
|
|
+ obj.enableCall = true;
|
|
|
|
+ obj.enableAnswer = false;
|
|
|
|
+ obj.enableHungup = false;
|
|
|
|
+ break;
|
|
|
|
+ case "callHungup":
|
|
|
|
+ this.stopPeer();
|
|
|
|
+ this.$refs.phone_trying.pause();
|
|
|
|
+ this.$refs.phone_ringing.pause();
|
|
|
|
+ obj.no = "";
|
|
|
|
+ obj.enableCall = true;
|
|
|
|
+ obj.enableAnswer = false;
|
|
|
|
+ obj.enableHungup = false;
|
|
|
|
+ if (resp.isSelf) {
|
|
|
|
+ } else {
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ case "call":
|
|
|
|
+ if (resp.msg) {
|
|
|
|
+ this.$message.error(resp.msg);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ obj.enableCall = false;
|
|
|
|
+ obj.enableAnswer = false;
|
|
|
|
+ obj.enableHungup = true;
|
|
|
|
+ break;
|
|
|
|
+ case "answer":
|
|
|
|
+ this.$refs.phone_trying.pause();
|
|
|
|
+ this.$refs.phone_ringing.pause();
|
|
|
|
+ if (resp.msg) {
|
|
|
|
+ this.$message.error(resp.msg);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ obj.enableCall = false;
|
|
|
|
+ obj.enableAnswer = false;
|
|
|
|
+ obj.enableHungup = true;
|
|
|
|
+ break;
|
|
|
|
+ case "hungup":
|
|
|
|
+ this.stopPeer();
|
|
|
|
+ this.$refs.phone_trying.pause();
|
|
|
|
+ this.$refs.phone_ringing.pause();
|
|
|
|
+ if (resp.msg) {
|
|
|
|
+ this.$message.error(resp.msg);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ obj.no = "";
|
|
|
|
+ obj.enableCall = true;
|
|
|
|
+ obj.enableAnswer = false;
|
|
|
|
+ obj.enableHungup = false;
|
|
|
|
+ break;
|
|
|
|
+ case "getOffer":
|
|
|
|
+ const offer = JSON.parse(resp.body);
|
|
|
|
+ console.log(
|
|
|
|
+ "get offer: " + offer.type + " " + offer.sdp + "."
|
|
|
|
+ );
|
|
|
|
+ this.startPeer(obj).then(() => {
|
|
|
|
+ this.pc.setRemoteDescription(
|
|
|
|
+ new RTCSessionDescription(offer)
|
|
|
|
+ );
|
|
|
|
+ this.pc.createAnswer().then((answer) => {
|
|
|
|
+ this.pc.setLocalDescription(answer);
|
|
|
|
+ console.log("Sending answer SDP.");
|
|
|
|
+ console.log("SDP: " + answer);
|
|
|
|
+ ws.send(
|
|
|
|
+ JSON.stringify({
|
|
|
|
+ cmd: 5,
|
|
|
|
+ body: JSON.stringify(answer),
|
|
|
|
+ })
|
|
|
|
+ );
|
|
|
|
+ });
|
|
|
|
+ });
|
|
|
|
+ break;
|
|
|
|
+ case "getIcecandidate":
|
|
|
|
+ console.log("get icecandidate: ", resp.body);
|
|
|
|
+ this.pc.addIceCandidate(JSON.parse(resp.body));
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ ws.send(
|
|
|
|
+ JSON.stringify({ sipId: a.id, clientId: this.clientId })
|
|
|
|
+ );
|
|
|
|
+ }, 500);
|
|
|
|
|
|
- this.pc
|
|
|
|
- .createAnswer()
|
|
|
|
- .then(
|
|
|
|
- function (answer) {
|
|
|
|
- return this.pc.setLocalDescription(answer);
|
|
|
|
- }.bind(this)
|
|
|
|
- )
|
|
|
|
- .then(
|
|
|
|
- async function () {
|
|
|
|
- console.log("Sending answer SDP.");
|
|
|
|
- console.log("SDP: " + this.pc.localDescription.sdp);
|
|
|
|
- await fetch(this.setAnswerUrl, {
|
|
|
|
- method: "POST",
|
|
|
|
- body: JSON.stringify(this.pc.localDescription),
|
|
|
|
- headers: { "Content-Type": "application/json" },
|
|
|
|
|
|
+ return obj;
|
|
});
|
|
});
|
|
- }.bind(this)
|
|
|
|
- );
|
|
|
|
- },
|
|
|
|
- closePeer() {
|
|
|
|
- if (this.pc != null) {
|
|
|
|
- console.log("close peer");
|
|
|
|
- this.pc.close();
|
|
|
|
|
|
+
|
|
|
|
+ this.activeName = this.sips[0].name;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.log(error);
|
|
}
|
|
}
|
|
},
|
|
},
|
|
},
|
|
},
|