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