¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="call-container"> |
| | | <div class="sip-status" :class="sipStatusClass"> |
| | | SIPç¶æ: {{ sipStatus }} |
| | | </div> |
| | | |
| | | <!-- ç¶ææ¾ç¤º --> |
| | | <div class="call-status" :class="callStatusClass"> |
| | | {{ callStatusText }} |
| | | </div> |
| | | |
| | | <!-- å¼å«æé® --> |
| | | <button |
| | | :class="['call-btn', { calling: isCalling }]" |
| | | @click="startCall" |
| | | :disabled="isCalling || sipStatus !== '已注å'" |
| | | > |
| | | {{ callButtonText }} |
| | | </button> |
| | | |
| | | <!-- æææé® --> |
| | | <button v-if="isCalling" class="end-call-btn" @click="endCall">ææ</button> |
| | | |
| | | <!-- é³é¢å
ç´ ï¼éèï¼ --> |
| | | <audio id="remoteAudio" autoplay></audio> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import sipService from "@/utils/sipService"; |
| | | |
| | | export default { |
| | | props: { |
| | | phoneNumber: { |
| | | type: String, |
| | | default: "", |
| | | }, |
| | | }, |
| | | data() { |
| | | const randomNum = Math.floor(Math.random() * 11) + 1000; // å
é¨å®ä¹ |
| | | return { |
| | | isCalling: false, |
| | | callStatus: "idle", // idle, calling, connected, ended |
| | | sipStatus: "æªè¿æ¥", |
| | | sipStatusClass: "status-disconnected", |
| | | sipConfig: { |
| | | wsUrl: "wss://192.168.10.124:7443", |
| | | sipUri: `${randomNum}` + "@192.168.10.124", |
| | | password: "Smartor@2023", |
| | | displayName: "Web å°é¾", |
| | | }, |
| | | }; |
| | | }, |
| | | computed: { |
| | | callStatusText() { |
| | | const statusMap = { |
| | | idle: "åå¤å°±ç»ª", |
| | | calling: "å¼å«ä¸...", |
| | | connected: "éè¯ä¸", |
| | | ended: "éè¯ç»æ", |
| | | }; |
| | | return statusMap[this.callStatus]; |
| | | }, |
| | | callStatusClass() { |
| | | return `status-${this.callStatus}`; |
| | | }, |
| | | callButtonText() { |
| | | return this.isCalling ? "éè¯ä¸..." : "ä¸é®å¼å«"; |
| | | }, |
| | | }, |
| | | mounted() { |
| | | sipService.init(this.sipConfig); |
| | | sipService.onStatusChange = (status) => { |
| | | this.sipStatus = status.text; |
| | | this.sipStatusClass = `status-${status.type}`; |
| | | }; |
| | | |
| | | // çå¬éè¯ç¶æåå |
| | | sipService.onCallStatusChange = (status) => { |
| | | this.callStatus = status.type; |
| | | this.isCalling = status.type === "calling" || status.type === "connected"; |
| | | |
| | | // éç¥ç¶ç»ä»¶éè¯ç¶æåå |
| | | this.$emit("call-status-change", status); |
| | | }; |
| | | }, |
| | | methods: { |
| | | async startCall() { |
| | | if (!this.phoneNumber) { |
| | | this.$message.error("请è¾å
¥çµè¯å·ç "); |
| | | return; |
| | | } |
| | | |
| | | try { |
| | | this.callStatus = "calling"; |
| | | this.isCalling = true; |
| | | |
| | | await sipService.makeCall(this.phoneNumber); |
| | | } catch (error) { |
| | | console.error("å¼å«å¤±è´¥:", error); |
| | | this.callStatus = "ended"; |
| | | this.isCalling = false; |
| | | this.$message.error(`å¼å«å¤±è´¥: ${error.message}`); |
| | | } |
| | | }, |
| | | |
| | | endCall() { |
| | | sipService.endCall(); |
| | | this.callStatus = "ended"; |
| | | this.isCalling = false; |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .call-container { |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 10px; |
| | | max-width: 300px; |
| | | margin: 0 auto; |
| | | padding: 20px; |
| | | border: 1px solid #eee; |
| | | border-radius: 8px; |
| | | } |
| | | |
| | | input { |
| | | padding: 8px; |
| | | border: 1px solid #ccc; |
| | | border-radius: 4px; |
| | | } |
| | | |
| | | .call-btn { |
| | | padding: 10px; |
| | | background-color: #4caf50; |
| | | color: white; |
| | | border: none; |
| | | border-radius: 4px; |
| | | cursor: pointer; |
| | | } |
| | | .call-status { |
| | | padding: 8px; |
| | | margin: 10px 0; |
| | | border-radius: 4px; |
| | | text-align: center; |
| | | } |
| | | |
| | | .status-idle { |
| | | background-color: #f5f5f5; |
| | | color: #666; |
| | | } |
| | | |
| | | .status-calling { |
| | | background-color: #fff8e1; |
| | | color: #ff8f00; |
| | | } |
| | | |
| | | .status-connected { |
| | | background-color: #e8f5e9; |
| | | color: #2e7d32; |
| | | } |
| | | |
| | | .status-ended { |
| | | background-color: #ffebee; |
| | | color: #c62828; |
| | | } |
| | | |
| | | /* åææ ·å¼ä¿æä¸å */ |
| | | .call-container { |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 10px; |
| | | max-width: 300px; |
| | | margin: 0 auto; |
| | | padding: 20px; |
| | | border: 1px solid #eee; |
| | | border-radius: 8px; |
| | | } |
| | | |
| | | .call-btn { |
| | | padding: 10px; |
| | | background-color: #4caf50; |
| | | color: white; |
| | | border: none; |
| | | border-radius: 4px; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .call-btn:hover:not(:disabled) { |
| | | background-color: #45a049; |
| | | } |
| | | |
| | | .call-btn:disabled { |
| | | background-color: #cccccc; |
| | | cursor: not-allowed; |
| | | } |
| | | |
| | | .call-btn.calling { |
| | | background-color: #2196f3; |
| | | } |
| | | |
| | | .end-call-btn { |
| | | padding: 10px; |
| | | background-color: #f44336; |
| | | color: white; |
| | | border: none; |
| | | border-radius: 4px; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .end-call-btn:hover { |
| | | background-color: #d32f2f; |
| | | } |
| | | |
| | | .sip-status { |
| | | padding: 8px; |
| | | margin-bottom: 10px; |
| | | border-radius: 4px; |
| | | text-align: center; |
| | | } |
| | | |
| | | .status-disconnected { |
| | | background-color: #ffebee; |
| | | color: #c62828; |
| | | } |
| | | |
| | | .status-connecting { |
| | | background-color: #fff8e1; |
| | | color: #ff8f00; |
| | | } |
| | | |
| | | .status-registered { |
| | | background-color: #e8f5e9; |
| | | color: #2e7d32; |
| | | } |
| | | |
| | | .status-failed { |
| | | background-color: #ffebee; |
| | | color: #c62828; |
| | | } |
| | | .call-btn:hover { |
| | | background-color: #45a049; |
| | | } |
| | | |
| | | .call-btn.calling { |
| | | background-color: #2196f3; |
| | | } |
| | | |
| | | .end-call-btn { |
| | | padding: 10px; |
| | | background-color: #f44336; |
| | | color: white; |
| | | border: none; |
| | | border-radius: 4px; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .end-call-btn:hover { |
| | | background-color: #d32f2f; |
| | | } |
| | | |
| | | .call-status { |
| | | margin-top: 10px; |
| | | font-size: 14px; |
| | | color: #666; |
| | | } |
| | | .sip-status { |
| | | padding: 8px; |
| | | margin-bottom: 10px; |
| | | border-radius: 4px; |
| | | text-align: center; |
| | | } |
| | | |
| | | .status-disconnected { |
| | | background-color: #ffebee; |
| | | color: #c62828; |
| | | } |
| | | |
| | | .status-connecting { |
| | | background-color: #fff8e1; |
| | | color: #ff8f00; |
| | | } |
| | | |
| | | .status-registered { |
| | | background-color: #e8f5e9; |
| | | color: #2e7d32; |
| | | } |
| | | |
| | | .status-failed { |
| | | background-color: #ffebee; |
| | | color: #c62828; |
| | | } |
| | | </style> |