From ba4eee2e5ced6aef3e85a7c7b8317817b7ad3cae Mon Sep 17 00:00:00 2001 From: sinake <sinake1@qq.com> Date: 星期四, 14 八月 2025 10:05:53 +0800 Subject: [PATCH] Merge branch 'lishui-Smartor' of http://116.62.18.175:6699/r/~yxh/smartor-web --- src/components/CallButton/index.vue | 294 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 294 insertions(+), 0 deletions(-) diff --git a/src/components/CallButton/index.vue b/src/components/CallButton/index.vue new file mode 100644 index 0000000..47931a4 --- /dev/null +++ b/src/components/CallButton/index.vue @@ -0,0 +1,294 @@ +<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> -- Gitblit v1.9.3