From 880e036a0d85cd542034794c1dac2a4e433c5553 Mon Sep 17 00:00:00 2001
From: WXL <1785969728@qq.com>
Date: 星期四, 03 七月 2025 10:51:04 +0800
Subject: [PATCH] 测试完成
---
src/views/followvisit/record/detailpage/index.vue | 8 +
src/utils/sipService.js | 87 +++++++++++++++++
package.json | 1
src/components/CallButton/index.vue | 148 +++++++++++++++++++++++++++++
4 files changed, 244 insertions(+), 0 deletions(-)
diff --git a/package.json b/package.json
index 2994555..291269c 100644
--- a/package.json
+++ b/package.json
@@ -60,6 +60,7 @@
"js-beautify": "1.13.0",
"js-cookie": "3.0.1",
"jsencrypt": "^3.3.2",
+ "jssip": "^3.10.1",
"lemon-imui": "^1.7.7",
"moment": "^2.30.1",
"nprogress": "0.2.0",
diff --git a/src/components/CallButton/index.vue b/src/components/CallButton/index.vue
new file mode 100644
index 0000000..57690ea
--- /dev/null
+++ b/src/components/CallButton/index.vue
@@ -0,0 +1,148 @@
+<template>
+ <div class="call-container">
+ <!-- 鍙风爜杈撳叆 -->
+ <input
+ v-model="phoneNumber"
+ type="text"
+ placeholder="杈撳叆鐢佃瘽鍙风爜"
+ @keyup.enter="startCall"
+ >
+
+ <!-- 鍛煎彨鎸夐挳 -->
+ <button
+ :class="['call-btn', { 'calling': isCalling }]"
+ @click="startCall"
+ >
+ {{ isCalling ? '閫氳瘽涓�...' : '涓�閿懠鍙�' }}
+ </button>
+
+ <!-- 鎸傛柇鎸夐挳 -->
+ <button
+ v-if="isCalling"
+ class="end-call-btn"
+ @click="endCall"
+ >
+ 鎸傛柇
+ </button>
+
+ <!-- 闊抽鍏冪礌锛堥殣钘忥級 -->
+ <audio id="remoteAudio" autoplay></audio>
+
+ <!-- 鐘舵�佹樉绀� -->
+ <div class="call-status">
+ {{ callStatus }}
+ </div>
+ </div>
+</template>
+
+<script>
+import sipService from '@/utils/sipService'
+
+export default {
+ data() {
+ return {
+ phoneNumber: '',
+ isCalling: false,
+ callStatus: '鍑嗗灏辩华',
+ sipConfig: {
+ wsUrl: 'wss://192.168.100.6:7443',
+ sipUri: '1000@192.168.100.6',
+ password: 'Smartor@2023',
+ displayName: 'Web 灏忛緳',
+ realm: '192.168.100.6:8090'
+ }
+ }
+ },
+ mounted() {
+ // 鍒濆鍖朣IP杩炴帴
+ sipService.init(this.sipConfig)
+ },
+ beforeDestroy() {
+ // 缁勪欢閿�姣佹椂缁撴潫閫氳瘽
+ this.endCall()
+ },
+ methods: {
+ // 寮�濮嬪懠鍙�
+ async startCall() {
+ if (!this.phoneNumber) {
+ this.callStatus = '璇疯緭鍏ョ數璇濆彿鐮�'
+ return
+ }
+ try {
+ this.isCalling = true
+ this.callStatus = '鍛煎彨涓�...'
+ // 璋冪敤SIP鏈嶅姟
+ sipService.makeCall(this.phoneNumber)
+
+ this.callStatus = '閫氳瘽宸插缓绔�'
+ } catch (error) {
+ console.error('鍛煎彨澶辫触:', error)
+ this.callStatus = `鍛煎彨澶辫触: ${error.message}`
+ this.isCalling = false
+ }
+ },
+
+ // 缁撴潫閫氳瘽
+ endCall() {
+ sipService.endCall()
+ this.isCalling = false
+ this.callStatus = '閫氳瘽宸茬粨鏉�'
+ }
+ }
+}
+</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-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;
+}
+</style>
diff --git a/src/utils/sipService.js b/src/utils/sipService.js
new file mode 100644
index 0000000..95ac836
--- /dev/null
+++ b/src/utils/sipService.js
@@ -0,0 +1,87 @@
+import JsSIP from 'jssip'
+
+class SipService {
+ constructor() {
+ this.ua = null
+ this.currentSession = null
+ }
+
+ // 鍒濆鍖朣IP瀹㈡埛绔�
+ init(config) {
+ this.ua = new JsSIP.UA({
+ sockets: [new JsSIP.WebSocketInterface(config.wsUrl)],
+ uri: config.sipUri,
+ password: config.password,
+ display_name: config.displayName,
+ realm: config.realm,
+ ha1: config.ha1,
+ register: true
+ })
+
+ this.ua.start()
+
+ // 娉ㄥ唽浜嬩欢鐩戝惉
+ this.ua.on('registered', () => {
+ console.log('SIP娉ㄥ唽鎴愬姛')
+ })
+
+ this.ua.on('registrationFailed', (e) => {
+ console.error('SIP娉ㄥ唽澶辫触:', e)
+ })
+
+ // 鐩戝惉鏉ョ數
+ this.ua.on('newRTCSession', (data) => {
+ this.handleIncomingCall(data.session)
+ })
+ }
+
+ // 涓�閿嫧鍙�
+ makeCall(targetNumber) {
+ if (!this.ua) {
+ console.error('SIP瀹㈡埛绔湭鍒濆鍖�')
+ return
+ }
+
+ const options = {
+ eventHandlers: {
+ progress: (e) => console.log('鍛煎彨涓�...'),
+ failed: (e) => console.error('鍛煎彨澶辫触:', e),
+ ended: (e) => console.log('閫氳瘽缁撴潫'),
+ confirmed: (e) => console.log('閫氳瘽宸叉帴閫�')
+ },
+ mediaConstraints: { audio: true, video: false },
+ rtcOfferConstraints: { offerToReceiveAudio: 1 }
+ }
+
+ this.currentSession = this.ua.call(`sip:${targetNumber}`, options)
+ this.setupAudio(this.currentSession)
+ }
+
+ // 鎸傛柇褰撳墠閫氳瘽
+ endCall() {
+ if (this.currentSession) {
+ this.currentSession.terminate()
+ this.currentSession = null
+ }
+ }
+
+ // 澶勭悊闊抽娴�
+ setupAudio(session) {
+ session.connection.addEventListener('addstream', (e) => {
+ const audioElement = document.getElementById('remoteAudio')
+ if (audioElement) {
+ audioElement.srcObject = e.stream
+ }
+ })
+ }
+
+ // 澶勭悊鏉ョ數
+ handleIncomingCall(session) {
+ if (session.direction === 'incoming') {
+ console.log('鏉ョ數:', session.remote_identity.uri.toString())
+ // 杩欓噷鍙互瑙﹀彂UI閫氱煡
+ }
+ }
+}
+
+export default new SipService()
diff --git a/src/views/followvisit/record/detailpage/index.vue b/src/views/followvisit/record/detailpage/index.vue
index 0abf723..0cffc18 100644
--- a/src/views/followvisit/record/detailpage/index.vue
+++ b/src/views/followvisit/record/detailpage/index.vue
@@ -354,6 +354,10 @@
</div>
</div>
<div>
+ <h2>涓�閿懠鍙姛鑳�</h2>
+ <CallButton/>
+ </div>
+ <div>
<el-tabs v-model="activeName" type="border-card">
<el-tab-pane name="wj">
<span class="mulsz" slot="label"
@@ -744,7 +748,11 @@
alterpatient,
listcontactinformation,
} from "@/api/patient/homepage";
+import CallButton from "@/components/CallButton";
export default {
+ components: {
+ CallButton,
+ },
dicts: ["sys_normal_disable", "sys_user_sex", "sys_yujing", "sys_suggest"],
data() {
return {
--
Gitblit v1.9.3