From 91f78c7a3c325b7627f269524cdf92f006948cdf Mon Sep 17 00:00:00 2001 From: WXL (wul) <wl_5969728@163.com> Date: 星期一, 20 十月 2025 17:37:35 +0800 Subject: [PATCH] 景宁电话接入 --- src/views/followvisit/discharge/ClickCall copy.vue | 1258 +++++++++++++++++++++++++++++ dist.zip | 0 vue.config.js | 4 src/api/AiCentre/phoneCall.js | 4 src/views/followvisit/record/detailpage/index.vue | 62 src/views/followvisit/discharge/ClickCall.vue | 622 ++++++++++--- src/components/CallCenterLs/index.vue | 614 ++++++++++++++ 7 files changed, 2,371 insertions(+), 193 deletions(-) diff --git a/dist.zip b/dist.zip index b6e6235..829d089 100644 --- a/dist.zip +++ b/dist.zip Binary files differ diff --git a/src/api/AiCentre/phoneCall.js b/src/api/AiCentre/phoneCall.js index 84769dc..f2f5124 100644 --- a/src/api/AiCentre/phoneCall.js +++ b/src/api/AiCentre/phoneCall.js @@ -1,11 +1,13 @@ import request from "@/utils/request"; - // 鍒犻櫎澶栭儴鎮h�呰〃 export function CallgetList() { return request({ url: "/smartor/ServiceTelInfo/getList", method: "get", + params: { + orgid: localStorage.getItem("orgid"), + }, }); } // 鏌ヨ澶栭儴鎮h�呰〃 diff --git a/src/components/CallCenterLs/index.vue b/src/components/CallCenterLs/index.vue new file mode 100644 index 0000000..2114df6 --- /dev/null +++ b/src/components/CallCenterLs/index.vue @@ -0,0 +1,614 @@ +<template> + <div class="call-center-container"> + <!-- 涓绘帶鍒跺尯 --> + <div class="control-section"> + <div class="phone-control-card"> + <h3 class="section-title">鐢佃瘽鎺у埗</h3> + <div class="input-group"> + <div class="form-field"> + <label class="form-label">瀹㈡埛鐢佃瘽鍙风爜</label> + <input + v-model="customerPhone" + type="text" + placeholder="璇疯緭鍏ョ數璇濆彿鐮�" + :disabled="isCalling" + class="phone-input" + /> + </div> + + <div class="button-group"> + <button + @click="handleCall" + :class="['call-btn', callButtonClass]" + :disabled="!canMakeCall" + > + <span class="btn-icon">馃摓</span> + {{ callButtonText }} + </button> + + <button + @click="handleHangup" + class="hangup-btn" + :disabled="!canHangup" + > + <span class="btn-icon">馃摰</span> + 鎸傛柇 + </button> + </div> + </div> + </div> + + <!-- 鐘舵�佹樉绀哄尯 --> + <div class="status-card"> + <h3 class="section-title">鐘舵�佺洃鎺�</h3> + <div class="status-grid"> + <div class="status-item"> + <span class="status-label">搴у腑鐘舵��:</span> + <span :class="['status-indicator', seatStatusClass]"> + <span class="status-dot"></span> + {{ seatStatusText }} + </span> + </div> + + <div class="status-item"> + <span class="status-label">閫氳瘽鐘舵��:</span> + <span :class="['status-indicator', callStatusClass]"> + <span class="status-dot"></span> + {{ callStatusText }} + </span> + </div> + + <div class="status-item" v-if="callDuration"> + <span class="status-label">閫氳瘽鏃堕暱:</span> + <span class="duration-display"> + 鈴憋笍 {{ callDuration }} + </span> + </div> + </div> + </div> + </div> + + <!-- 璋冭瘯闈㈡澘 --> + <div class="debug-section"> + <el-collapse accordion> + <el-collapse-item name="debug"> + <template slot="title"> + <div class="debug-header"> + <span class="debug-title">鍛煎彨璋冭瘯鏃ュ織</span> + <span class="debug-subtitle">鐐瑰嚮鏌ョ湅璇︾粏閫氳瘽淇℃伅</span> + </div> + </template> + <div class="debug-content"> + <WebsocketDemo + ref="callComponent" + :customer-phone="customerPhone" + :auto-login="true" + @status-change="onSeatStatusChange" + @call-status="onCallStatusChange" + @error="onCallError" + class="call-component" + /> + </div> + </el-collapse-item> + </el-collapse> + </div> + </div> +</template> + +<script> +import WebsocketDemo from "../../views/followvisit/discharge/ClickCall.vue"; + +export default { + name: "CallCenterModal", + components: { + WebsocketDemo, + }, + + props: { + initialPhone: { + type: String, + default: "", + }, + }, + + data() { + return { + customerPhone: "", + isSeatLoggedIn: false, + callStatus: "idle", + callStartTime: null, + callDuration: "00:00", + durationTimer: null, + lastError: null, + }; + }, + + computed: { + isCalling() { + return this.callStatus === "calling"; + }, + + isInCall() { + return this.callStatus === "connected"; + }, + + canMakeCall() { + return ( + this.isSeatLoggedIn && + this.customerPhone && + this.callStatus === "idle" && + !this.lastError + ); + }, + + canHangup() { + return this.isCalling || this.isInCall; + }, + + callButtonClass() { + if (!this.canMakeCall) return "disabled"; + return this.isCalling ? "calling" : "idle"; + }, + + callButtonText() { + if (this.isCalling) return "鍛煎彨涓�..."; + if (this.isInCall) return "閫氳瘽涓�"; + return "寮�濮嬪懠鍙�"; + }, + + seatStatusClass() { + return this.isSeatLoggedIn ? "success" : "error"; + }, + + seatStatusText() { + return this.isSeatLoggedIn ? "宸茬鍏�" : "鏈鍏�"; + }, + + callStatusClass() { + switch (this.callStatus) { + case "connected": + return "success"; + case "calling": + return "warning"; + default: + return "idle"; + } + }, + + callStatusText() { + switch (this.callStatus) { + case "connected": + return "閫氳瘽涓�"; + case "calling": + return "鍛煎彨涓�"; + default: + return "绌洪棽"; + } + }, + }, + + watch: { + initialPhone: { + immediate: true, + handler(newVal) { + if (newVal) { + this.customerPhone = newVal; + } + }, + }, + }, + + methods: { + handleCall() { + if (!this.canMakeCall) return; + this.$refs.callComponent.callout(this.customerPhone); + this.startCallTimer(); + }, + + handleHangup() { + this.$refs.callComponent.hangup(); + this.stopCallTimer(); + this.callStatus = "idle"; + }, + + onSeatStatusChange(status) { + this.isSeatLoggedIn = status.isLoggedIn; + }, + + onCallStatusChange(status) { + this.callStatus = status.status; + if (status.status === "connected") { + this.startCallTimer(); + } else if (status.status === "idle") { + this.stopCallTimer(); + } + }, + + onCallError(error) { + this.lastError = error; + this.$emit("error", error); + }, + + startCallTimer() { + this.callStartTime = new Date(); + this.durationTimer = setInterval(() => { + if (this.callStartTime) { + const duration = Math.floor((new Date() - this.callStartTime) / 1000); + const minutes = Math.floor(duration / 60) + .toString() + .padStart(2, "0"); + const seconds = (duration % 60).toString().padStart(2, "0"); + this.callDuration = `${minutes}:${seconds}`; + } + }, 1000); + }, + + stopCallTimer() { + if (this.durationTimer) { + clearInterval(this.durationTimer); + this.durationTimer = null; + } + this.callDuration = "00:00"; + this.callStartTime = null; + }, + + handleSeatBusy() { + this.$refs.callComponent.afk(); + }, + + handleSeatReady() { + this.$refs.callComponent.online(); + }, + + handleHold() { + this.$refs.callComponent.hold(); + }, + + handleResume() { + this.$refs.callComponent.holdresume(); + }, + + // 鎻愪緵缁欑埗缁勪欢璋冪敤鐨勬柟娉� + setPhoneNumber(phone) { + this.customerPhone = phone; + }, + + autoCall(phone) { + this.setPhoneNumber(phone); + this.$nextTick(() => { + this.handleCall(); + }); + }, + }, + + beforeUnmount() { + this.stopCallTimer(); + }, +}; +</script> + +<style lang="scss" scoped> +.call-center-container { + height: 100%; + display: flex; + flex-direction: column; + gap: 16px; + padding: 0; + background: #f8fafc; +} + +// 鎺у埗鍖哄煙鏍峰紡 +.control-section { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 16px; + padding: 20px; + padding-bottom: 0; + + @media (max-width: 1024px) { + grid-template-columns: 1fr; + } +} + +.section-title { + font-size: 16px; + font-weight: 600; + color: #1e293b; + margin-bottom: 16px; + display: flex; + align-items: center; + + &::before { + content: ""; + width: 3px; + height: 16px; + background: #3b82f6; + margin-right: 8px; + border-radius: 2px; + } +} + +// 鍗$墖閫氱敤鏍峰紡 +.phone-control-card, +.status-card { + background: white; + padding: 20px; + border-radius: 12px; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + border: 1px solid #e2e8f0; +} + +// 琛ㄥ崟鎺т欢鏍峰紡 +.form-field { + margin-bottom: 20px; +} + +.form-label { + display: block; + font-weight: 500; + color: #475569; + margin-bottom: 8px; + font-size: 14px; +} + +.phone-input { + width: 100%; + padding: 12px; + border: 2px solid #e2e8f0; + border-radius: 8px; + font-size: 14px; + transition: all 0.3s ease; + + &:focus { + outline: none; + border-color: #3b82f6; + box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1); + } + + &:disabled { + background-color: #f8fafc; + color: #94a3b8; + cursor: not-allowed; + } +} + +.button-group { + display: flex; + gap: 12px; + flex-wrap: wrap; +} + +// 鎸夐挳鍩虹鏍峰紡 +.call-btn, +.hangup-btn { + padding: 12px 28px; /* 澧炲姞鍐呰竟璺濓紝浣挎寜閽洿澶ф柟 */ + border: none; + border-radius: 12px; /* 浣跨敤鏇村ぇ鐨勫渾瑙掞紝鍒涢�犫�滆嵂涓糕�濆舰 */ + cursor: pointer; + font-size: 14px; + font-weight: 600; /* 瀛椾綋鍔犵矖 */ + transition: all 0.3s ease; /* 骞虫粦杩囨浮鎵�鏈夊睘鎬� */ + display: flex; + align-items: center; + justify-content: center; + gap: 8px; /* 鍥炬爣鍜屾枃瀛楃殑闂磋窛 */ + min-width: 120px; /* 璁剧疆鏈�灏忓搴� */ + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15), 0 2px 4px rgba(0, 0, 0, 0.1); /* 澶氬眰闃村奖澧炲己绔嬩綋鎰� */ +} + +.call-btn { + background: linear-gradient(135deg, #10b981, #059669); /* 缁胯壊娓愬彉 */ + color: white; +} + +.call-btn:hover:not(.disabled) { + transform: translateY(-2px); /* 鎮仠鏃惰交寰笂娴� */ + box-shadow: 0 6px 16px rgba(16, 185, 129, 0.4); /* 鎮仠鏃堕槾褰辨洿鏄庢樉 */ +} + +.call-btn.calling { + background: linear-gradient(135deg, #f59e0b, #d97706); /* 鍛煎彨涓姸鎬佹敼涓烘鑹叉笎鍙� */ + animation: pulse 1.5s infinite; /* 鍛煎彨涓坊鍔犲懠鍚歌剦鍐插姩鐢� */ +} + +.hangup-btn { + background: linear-gradient(135deg, #ef4444, #dc2626); /* 绾㈣壊娓愬彉 */ + color: white; +} + +.hangup-btn:hover:not(:disabled) { + transform: translateY(-2px); + box-shadow: 0 6px 16px rgba(239, 68, 68, 0.4); +} + +/* 绂佺敤鐘舵�� */ +.call-btn.disabled, +.hangup-btn:disabled { + background: #cbd5e1 !important; + cursor: not-allowed; + transform: none !important; + box-shadow: none !important; +} + +/* 鑴夊啿鍔ㄧ敾瀹氫箟 */ +@keyframes pulse { + 0% { box-shadow: 0 4px 12px rgba(245, 158, 11, 0.5); } + 50% { box-shadow: 0 4px 20px rgba(245, 158, 11, 0.8); } + 100% { box-shadow: 0 4px 12px rgba(245, 158, 11, 0.5); } +} + +// 鐘舵�佹樉绀烘牱寮� +.status-grid { + display: flex; + flex-direction: column; + gap: 16px; +} + +.status-item { + display: flex; + justify-content: space-between; + align-items: center; + padding: 12px; + background: #f8fafc; + border-radius: 8px; +} + +.status-label { + font-size: 14px; + color: #475569; + font-weight: 500; +} + +.status-indicator { + display: flex; + align-items: center; + gap: 8px; + font-size: 13px; + font-weight: 500; + padding: 4px 12px; + border-radius: 20px; +} + +.status-dot { + width: 8px; + height: 8px; + border-radius: 50%; + animation: pulse 2s infinite; +} + +.status-indicator.success { + background: #f0fdf4; + color: #059669; + + .status-dot { + background: #059669; + } +} + +.status-indicator.error { + background: #fef2f2; + color: #dc2626; + + .status-dot { + background: #dc2626; + } +} + +.status-indicator.warning { + background: #fffbeb; + color: #d97706; + + .status-dot { + background: #f59e0b; + } +} + +.status-indicator.idle { + background: #f8fafc; + color: #64748b; + + .status-dot { + background: #94a3b8; + } +} + +.duration-display { + font-family: 'Courier New', monospace; + font-weight: 600; + color: #059669; + font-size: 14px; +} + +// 璋冭瘯闈㈡澘鏍峰紡 +.debug-section { + background: white; + margin: 0 20px 20px; + padding: 20px; + border-radius: 12px; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); +} + +.debug-header { + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; + padding-right: 20px; +} + +.debug-title { + font-size: 16px; + font-weight: 600; + color: #1e293b; + margin-bottom: 16px; + display: flex; + align-items: center; + + &::before { + content: ""; + width: 3px; + height: 16px; + background: #3b82f6; + margin-right: 8px; + border-radius: 2px; + } +} + +.debug-subtitle { + font-size: 12px; + color: #64748b; +} + +.debug-content { + padding: 0; +} + +.call-component { + min-height: 200px; + border-top: 1px solid #e2e8f0; +} + +// 鍔ㄧ敾瀹氫箟 +@keyframes pulse { + 0% { opacity: 1; } + 50% { opacity: 0.5; } + 100% { opacity: 1; } +} + +// 鍝嶅簲寮忚璁� +@media (max-width: 768px) { + .control-section { + padding: 16px; + grid-template-columns: 1fr; + } + + .phone-control-card, + .status-card { + padding: 16px; + } + + .button-group { + flex-direction: column; + } + + .status-item { + flex-direction: column; + gap: 8px; + align-items: flex-start; + } + + .debug-section { + margin: 0 16px 16px; + } +} + +@media (max-width: 480px) { + .call-center-container { + gap: 12px; + } + + .control-section { + padding: 12px; + } +} +</style> diff --git a/src/views/followvisit/discharge/ClickCall copy.vue b/src/views/followvisit/discharge/ClickCall copy.vue new file mode 100644 index 0000000..b922b0c --- /dev/null +++ b/src/views/followvisit/discharge/ClickCall copy.vue @@ -0,0 +1,1258 @@ +<template> + <div class="websocket-demo"> + <div> + <h3>Websocket鎺ュ彛娴嬭瘯DEMO</h3> + <div class="config-area"> + <div class="input-group"> + <label>CTI_WS_URL</label> + <input + type="text" + v-model="config.cti_ws_url" + placeholder="ws://40.78.0.169:6688" + /> + + <label>鍧愬腑宸ュ彿</label> + <input type="text" v-model="config.seatname" placeholder="8000" /> + + <label>鍧愬腑鍒嗘満</label> + <input type="text" v-model="config.seatnum" placeholder="8000" /> + + <label>瀵嗙爜</label> + <input type="text" v-model="config.password" placeholder="123456" /> + </div> + + <div class="input-group"> + <label>澶栫嚎鍙风爜</label> + <input type="text" v-model="config.phone" placeholder="10086" /> + + <label>UUID</label> + <input type="text" v-model="config.uuid" /> + + <label>鍏朵粬鍧愬腑</label> + <input type="text" v-model="config.other" placeholder="8001" /> + + <label>鎶�鑳界粍</label> + <input type="text" v-model="config.group" placeholder="a3" /> + + <label>澶栧懠鍙傛暟id</label> + <input type="text" v-model="config.paramid" placeholder="3" /> + </div> + </div> + + <!-- 鎿嶄綔鎸夐挳鍖哄煙 --> + <div class="button-area"> + <!-- 绗竴琛屾寜閽� --> + <div class="button-row"> + <button @click="seatlogin">绛惧叆</button> + <button @click="seatlogout">绛惧嚭</button> + <button @click="afk">绀哄繖</button> + <button @click="online">绀洪棽</button> + <button @click="pickup">浠g瓟</button> + </div> + + <!-- 绗簩琛屾寜閽� --> + <div class="button-row"> + <button @click="hangup">鎸傛満</button> + <button @click="callout">澶栧懠</button> + <button @click="transfer">閫氳瘽杞Щ</button> + <button @click="transferresume">閫氳瘽杞Щ鏀跺洖</button> + <button @click="hold">閫氳瘽淇濇寔</button> + <button @click="holdresume">閫氳瘽淇濇寔鏀跺洖</button> + <button @click="remove">閫氳瘽寮烘媶</button> + <button @click="insert">閫氳瘽寮烘彃</button> + <button @click="monitor">鐩戝惉</button> + <button @click="monitor_to_talk">鐩戝惉杞�氳瘽</button> + <button @click="monitor_end">鐩戝惉缁撴潫</button> + <button @click="choosecall">閫夋嫨</button> + <button @click="replacecall">浠f帴</button> + <button @click="three">涓夋柟閫氳瘽</button> + </div> + + <!-- 绗笁琛屾寜閽� --> + <div class="button-row"> + <button @click="handoff_ready">鍜ㄨ寮�濮�</button> + <button @click="handoff_call">鍜ㄨ鍛煎彨</button> + <button @click="handoff_resume">鍜ㄨ鏀跺洖</button> + <button @click="handoff_transfer">鍜ㄨ杞Щ</button> + <button @click="handoff_three">鍜ㄨ涓夋柟</button> + <button @click="record_start">寮�濮嬮�氳瘽褰曢煶</button> + <button @click="record_stop">鍋滄閫氳瘽褰曢煶</button> + </div> + + <!-- 绗洓琛屾寜閽� --> + <div class="button-row"> + <button @click="openseatlist">鎵撳紑鍧愬腑鐘舵��</button> + <button @click="closeseatlist">鍏抽棴鍧愬腑鐘舵��</button> + <button @click="openqueues">鎵撳紑闃熷垪淇℃伅</button> + <button @click="closequeues">鍏抽棴闃熷垪淇℃伅</button> + <button @click="opencalllist">鎵撳紑閫氳瘽淇℃伅</button> + <button @click="closecalllist">鍏抽棴閫氳瘽淇℃伅</button> + <button @click="openroutelist">鎵撳紑璺敱淇℃伅</button> + <button @click="closeroutelist">鍏抽棴璺敱淇℃伅</button> + </div> + + <!-- 绗簲琛屾寜閽� --> + <div class="button-row"> + <button @click="seatlist">鑾峰彇鍧愬腑淇℃伅</button> + <button @click="queues">鑾峰彇闃熷垪淇℃伅</button> + <button @click="calllist">鑾峰彇閫氳瘽淇℃伅</button> + <button @click="routelist">鑾峰彇璺敱淇℃伅</button> + <button @click="batch">鑾峰彇澶栧懠鍙傛暟淇℃伅</button> + <button @click="batch_start">寮�濮嬪鍛间换鍔�</button> + <button @click="batch_stop">鍋滄澶栧懠浠诲姟</button> + </div> + </div> + + <!-- 鏃ュ織鏄剧ず鍖哄煙 --> + <h3>鍗忚鏃ュ織鍖�<button @click="testclear">娓呴櫎</button></h3> + <div id="msg" class="log-area">{{ logs }}</div> + </div> + </div> +</template> + +<script> +import { CallsetState, CallgetList } from "@/api/AiCentre/index"; + +export default { + name: "WebsocketDemo", + + data() { + return { + config: { + cti_ws_url: "wss://9.208.2.190:8092/cal-api/", + seatname: "8000", + seatnum: "8000", + password: "123456", + phone: "10086", + uuid: "", + other: "8001", + group: "a3", + paramid: "3", + }, + randomNum: "", + randomID: "", + logs: "", + ws: null, + isConnected: false, + }; + }, + + mounted() { + this.CallgetList(); + this.initializeWebSocket(); + }, + + beforeUnmount() { + this.disconnectWebSocket(); + }, + + methods: { + // 鍒濆鍖朩ebSocket杩炴帴 + initializeWebSocket() { + try { + // 鏍规嵁褰撳墠椤甸潰鍗忚鑷姩閫夋嫨WS鍗忚 + const isHttps = window.location.protocol === "https:"; + this.config.cti_ws_url = isHttps + ? "wss://9.208.2.190:8092/cal-api/" + : "ws://40.78.0.169:6688"; + + if (typeof window.WebSocket === "undefined") { + this.addLog("閿欒: 娴忚鍣ㄤ笉鏀寔WebSocket"); + return; + } + + this.connectWebSocket(); + } catch (error) { + this.addLog(`鍒濆鍖朩ebSocket閿欒: ${error.message}`); + // 灏濊瘯浣跨敤澶囩敤鍦板潃 + this.config.cti_ws_url = "wss://9.208.2.190:8092/cal-api/"; + setTimeout(() => this.connectWebSocket(), 2000); + } + }, + // 鏌ヨ鍙敤鍒嗘満鍙� + async CallgetList() { + try { + const res = await CallgetList(); + this.randomNum = res.data[0].tel; + this.randomID = res.data[0].id; + // 姝g‘璁剧疆 sipUri + this.config.seatname = randomNum; + this.config.seatnum = randomNum; + this.startCallsetState(); + } catch (error) { + console.error("鑾峰彇搴у腑鍙峰け璐�:", error); + this.updateStatus("failed", "鑾峰彇搴у腑鍙峰け璐�"); + } + }, + //浣跨敤搴у腑鍙� + async startCallsetState() { + try { + await CallsetState({ id: this.randomID, state: 1 }); + console.log("搴у腑鍙风姸鎬佹洿鏂颁负浣跨敤涓�"); + } catch (error) { + console.error("鏇存柊搴у腑鍙风姸鎬佸け璐�:", error); + } + }, + //閲婃斁搴у腑鍙� + async overCallsetState() { + try { + if (this.randomID) { + await CallsetState({ id: this.randomID, state: 0 }); + console.log("搴у腑鍙风姸鎬佹洿鏂颁负鍙敤"); + } + } catch (error) { + console.error("閲婃斁搴у腑鍙峰け璐�:", error); + } + }, + // 杩炴帴WebSocket + connectWebSocket() { + if (this.ws && this.ws.readyState === WebSocket.OPEN) { + this.addLog("WebSocket宸茶繛鎺�"); + return; + } + + try { + let wsUrl = this.config.cti_ws_url; + // 纭繚HTTPS椤甸潰浣跨敤WSS + if ( + window.location.protocol === "https:" && + wsUrl.startsWith("ws://") + ) { + wsUrl = wsUrl.replace("ws://", "wss://"); + } + + this.ws = new WebSocket(wsUrl); + + this.ws.onopen = () => { + this.isConnected = true; + this.addLog("WebSocket杩炴帴鎴愬姛"); + }; + + this.ws.onmessage = (event) => { + this.handleWebSocketMessage(event); + }; + + this.ws.onclose = (event) => { + this.isConnected = false; + this.addLog(`WebSocket杩炴帴鍏抽棴: ${event.code} ${event.reason}`); + // 鑷姩閲嶈繛 + setTimeout(() => this.connectWebSocket(), 3000); + }; + + this.ws.onerror = (error) => { + this.addLog(`WebSocket閿欒: ${error.message}`); + // 灏濊瘯澶囩敤URL + if (!wsUrl.includes("9.208.2.190")) { + this.config.cti_ws_url = "wss://9.208.2.190:8092/cal-api/"; + setTimeout(() => this.connectWebSocket(), 3000); + } + }; + } catch (error) { + this.addLog(`杩炴帴WebSocket澶辫触: ${error.message}`); + // 灏濊瘯澶囩敤URL + this.config.cti_ws_url = "wss://9.208.2.190:8092/cal-api/"; + setTimeout(() => this.connectWebSocket(), 3000); + } + }, + + // 澶勭悊WebSocket娑堟伅 + handleWebSocketMessage(event) { + const reader = new FileReader(); + reader.onloadend = (e) => { + const message = reader.result; + this.addLog(`鏀跺埌娑堟伅: ${message}`); + + try { + const obj = JSON.parse(message); + + // 澶勭悊蹇冭烦鍖� + if (obj.cmd === "system" && obj.action === "keepalive") { + this.keepalive(obj.seatname, obj.seatnum); + } + + // 鑷姩璁剧疆UUID + if (obj.cmd === "control" && obj.action === "tp_callin") { + this.config.uuid = obj.uuid; + this.addLog(`鑷姩璁剧疆UUID: ${obj.uuid}`); + } + } catch (error) { + this.addLog(`娑堟伅瑙f瀽閿欒: ${error.message}`); + } + }; + reader.readAsText(event.data); + }, + + // 鏂紑WebSocket杩炴帴 + disconnectWebSocket() { + if (this.ws) { + this.ws.close(); + this.ws = null; + this.isConnected = false; + this.addLog("WebSocket宸叉柇寮�"); + } + }, + + // 鍙戦�乄ebSocket娑堟伅 + sendWebSocketMessage(message) { + if (!this.isConnected || !this.ws) { + this.addLog("閿欒: WebSocket鏈繛鎺�"); + return false; + } + + try { + const messageStr = + typeof message === "string" ? message : JSON.stringify(message); + this.ws.send(messageStr); + this.addLog(`鍙戦�佹秷鎭�: ${messageStr}`); + return true; + } catch (error) { + this.addLog(`鍙戦�佹秷鎭け璐�: ${error.message}`); + return false; + } + }, + + // 楠岃瘉鍙傛暟 + validateParams(params, requiredFields) { + for (const field of requiredFields) { + if (!params[field] || params[field].toString().trim() === "") { + this.addLog(`閿欒: ${field} 涓嶈兘涓虹┖`); + return false; + } + } + return true; + }, + + // ==================== WebSocket.js 鍔熻兘鏁村悎 ==================== + + // 绛惧叆 + seatlogin() { + const { seatname, seatnum, password, cti_ws_url } = this.config; + + if ( + !this.validateParams({ seatname, seatnum }, ["seatname", "seatnum"]) + ) { + return; + } + + // 閲嶆柊杩炴帴WebSocket锛堝師js鏂囦欢涓殑閫昏緫锛� + this.connectWebSocket(); + setTimeout(() => { + const protocol = { + cmd: "system", + action: "seatlogin", + seatname: seatname, + seatnum: seatnum, + password: password, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, 1000); + }, + + // 绛惧嚭 + seatlogout() { + const { seatname, seatnum } = this.config; + + if ( + !this.validateParams({ seatname, seatnum }, ["seatname", "seatnum"]) + ) { + return; + } + + const protocol = { + cmd: "system", + action: "seatlogout", + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + this.ws.close(); + }, + + // 绀哄繖 + afk() { + const { seatname, seatnum } = this.config; + + if ( + !this.validateParams({ seatname, seatnum }, ["seatname", "seatnum"]) + ) { + return; + } + + const protocol = { + cmd: "system", + action: "afk", + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 绀洪棽 + online() { + const { seatname, seatnum } = this.config; + + if ( + !this.validateParams({ seatname, seatnum }, ["seatname", "seatnum"]) + ) { + return; + } + + const protocol = { + cmd: "system", + action: "online", + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 浠g瓟 + pickup() { + const { seatname, seatnum } = this.config; + + if (!this.validateParams({ seatnum }, ["seatnum"])) { + return; + } + + const protocol = { + cmd: "control", + action: "pickup", + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 鎸傛満 + hangup() { + const { seatname, seatnum } = this.config; + + if (!this.validateParams({ seatnum }, ["seatnum"])) { + return; + } + + const protocol = { + cmd: "control", + action: "hangup", + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 澶栧懠 + callout() { + const { seatname, seatnum, phone } = this.config; + + if (!this.validateParams({ seatnum, phone }, ["seatnum", "phone"])) { + return; + } + + const protocol = { + cmd: "control", + action: "callout", + phone: phone, + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 閫氳瘽杞Щ + transfer() { + const { seatname, seatnum, phone, uuid } = this.config; + + if ( + !this.validateParams({ seatnum, phone, uuid }, [ + "seatnum", + "phone", + "uuid", + ]) + ) { + return; + } + + const protocol = { + cmd: "control", + action: "transfer", + uuid: uuid, + phone: phone, + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 閫氳瘽杞Щ鏀跺洖 + transferresume() { + const { seatname, seatnum, phone, uuid } = this.config; + + if ( + !this.validateParams({ seatnum, phone, uuid }, [ + "seatnum", + "phone", + "uuid", + ]) + ) { + return; + } + + const protocol = { + cmd: "control", + action: "transferresume", + uuid: uuid, + phone: phone, + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 閫氳瘽淇濇寔 + hold() { + const { seatname, seatnum, uuid } = this.config; + + if (!this.validateParams({ seatnum, uuid }, ["seatnum", "uuid"])) { + return; + } + + const protocol = { + cmd: "control", + action: "hold", + uuid: uuid, + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 閫氳瘽淇濇寔鏀跺洖 + holdresume() { + const { seatname, seatnum, uuid } = this.config; + + if (!this.validateParams({ seatnum, uuid }, ["seatnum", "uuid"])) { + return; + } + + const protocol = { + cmd: "control", + action: "holdresume", + uuid: uuid, + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 閫氳瘽寮烘媶 + remove() { + const { seatname, seatnum, phone } = this.config; + + if (!this.validateParams({ seatnum, phone }, ["seatnum", "phone"])) { + return; + } + + const protocol = { + cmd: "control", + action: "remove", + phone: phone, + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 閫氳瘽寮烘彃 + insert() { + const { seatname, seatnum, phone } = this.config; + + if (!this.validateParams({ seatnum, phone }, ["seatnum", "phone"])) { + return; + } + + const protocol = { + cmd: "control", + action: "insert", + phone: phone, + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 鐩戝惉 + monitor() { + const { seatname, seatnum, phone } = this.config; + + if (!this.validateParams({ seatnum, phone }, ["seatnum", "phone"])) { + return; + } + + const protocol = { + cmd: "control", + action: "monitor", + phone: phone, + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 鐩戝惉杞�氳瘽 + monitor_to_talk() { + const { seatname, seatnum, phone } = this.config; + + if (!this.validateParams({ seatnum, phone }, ["seatnum", "phone"])) { + return; + } + + const protocol = { + cmd: "control", + action: "monitor_to_talk", + phone: phone, + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 鐩戝惉缁撴潫 + monitor_end() { + const { seatname, seatnum, phone } = this.config; + + if (!this.validateParams({ seatnum, phone }, ["seatnum", "phone"])) { + return; + } + + const protocol = { + cmd: "control", + action: "monitor_end", + phone: phone, + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 閫夋嫨閫氳瘽 + choosecall() { + const { seatname, seatnum, uuid } = this.config; + + if (!this.validateParams({ seatnum, uuid }, ["seatnum", "uuid"])) { + return; + } + + const protocol = { + cmd: "control", + action: "choosecall", + uuid: uuid, + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 浠f帴 + replacecall() { + const { seatname, seatnum, phone } = this.config; + + if (!this.validateParams({ seatnum, phone }, ["seatnum", "phone"])) { + return; + } + + const protocol = { + cmd: "control", + action: "replacecall", + phone: phone, + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 涓夋柟閫氳瘽 + three() { + const { seatname, seatnum, phone } = this.config; + + if (!this.validateParams({ seatnum, phone }, ["seatnum", "phone"])) { + return; + } + + const protocol = { + cmd: "control", + action: "three", + phone: phone, + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 鍜ㄨ寮�濮� + handoff_ready() { + const { seatname, seatnum, uuid } = this.config; + + if (!this.validateParams({ seatnum, uuid }, ["seatnum", "uuid"])) { + return; + } + + const protocol = { + cmd: "control", + action: "handoff_ready", + uuid: uuid, + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 鍜ㄨ鍛煎彨 + handoff_call() { + const { seatname, seatnum, other, uuid } = this.config; + + if ( + !this.validateParams({ seatnum, other, uuid }, [ + "seatnum", + "other", + "uuid", + ]) + ) { + return; + } + + const protocol = { + cmd: "control", + action: "handoff_call", + uuid: uuid, + phone: other, + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 鍜ㄨ鏀跺洖 + handoff_resume() { + const { seatname, seatnum, uuid } = this.config; + + if (!this.validateParams({ seatnum, uuid }, ["seatnum", "uuid"])) { + return; + } + + const protocol = { + cmd: "control", + action: "handoff_resume", + uuid: uuid, + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 鍜ㄨ杞Щ + handoff_transfer() { + const { seatname, seatnum, other, uuid } = this.config; + + if ( + !this.validateParams({ seatnum, other, uuid }, [ + "seatnum", + "other", + "uuid", + ]) + ) { + return; + } + + const protocol = { + cmd: "control", + action: "handoff_transfer", + uuid: uuid, + phone: other, + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 鍜ㄨ涓夋柟 + handoff_three() { + const { seatname, seatnum, uuid } = this.config; + + if (!this.validateParams({ seatnum, uuid }, ["seatnum", "uuid"])) { + return; + } + + const protocol = { + cmd: "control", + action: "handoff_three", + uuid: uuid, + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 寮�濮嬮�氳瘽褰曢煶 + record_start() { + const { seatname, seatnum, uuid } = this.config; + + if (!this.validateParams({ seatnum, uuid }, ["seatnum", "uuid"])) { + return; + } + + const protocol = { + cmd: "control", + action: "record_start", + uuid: uuid, + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 鍋滄閫氳瘽褰曢煶 + record_stop() { + const { seatname, seatnum, uuid } = this.config; + + if (!this.validateParams({ seatnum, uuid }, ["seatnum", "uuid"])) { + return; + } + + const protocol = { + cmd: "control", + action: "record_stop", + uuid: uuid, + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 鎵撳紑鍧愬腑鐘舵�� + openseatlist() { + const { seatname, seatnum } = this.config; + + if (!this.validateParams({ seatnum }, ["seatnum"])) { + return; + } + + const protocol = { + cmd: "status", + action: "openseatlist", + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 鍏抽棴鍧愬腑鐘舵�� + closeseatlist() { + const { seatname, seatnum } = this.config; + + if (!this.validateParams({ seatnum }, ["seatnum"])) { + return; + } + + const protocol = { + cmd: "status", + action: "closeseatlist", + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 鎵撳紑闃熷垪淇℃伅 + openqueues() { + const { seatname, seatnum } = this.config; + + if (!this.validateParams({ seatnum }, ["seatnum"])) { + return; + } + + const protocol = { + cmd: "status", + action: "openqueues", + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 鍏抽棴闃熷垪淇℃伅 + closequeues() { + const { seatname, seatnum } = this.config; + + if (!this.validateParams({ seatnum }, ["seatnum"])) { + return; + } + + const protocol = { + cmd: "status", + action: "closequeues", + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 鎵撳紑閫氳瘽淇℃伅 + opencalllist() { + const { seatname, seatnum } = this.config; + + if (!this.validateParams({ seatnum }, ["seatnum"])) { + return; + } + + const protocol = { + cmd: "status", + action: "opencalllist", + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 鍏抽棴閫氳瘽淇℃伅 + closecalllist() { + const { seatname, seatnum } = this.config; + + if (!this.validateParams({ seatnum }, ["seatnum"])) { + return; + } + + const protocol = { + cmd: "status", + action: "closecalllist", + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 鎵撳紑璺敱淇℃伅 + openroutelist() { + const { seatname, seatnum } = this.config; + + if (!this.validateParams({ seatnum }, ["seatnum"])) { + return; + } + + const protocol = { + cmd: "status", + action: "openroutelist", + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 鍏抽棴璺敱淇℃伅 + closeroutelist() { + const { seatname, seatnum } = this.config; + + if (!this.validateParams({ seatnum }, ["seatnum"])) { + return; + } + + const protocol = { + cmd: "status", + action: "closeroutelist", + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 鑾峰彇鍧愬腑淇℃伅 + seatlist() { + const { group } = this.config; + + if (!this.validateParams({ group }, ["group"])) { + return; + } + + const protocol = { + cmd: "status", + action: "seatlist", + group: group, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 鑾峰彇闃熷垪淇℃伅 + queues() { + const protocol = { + cmd: "status", + action: "queues", + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 鑾峰彇閫氳瘽淇℃伅 + calllist() { + const protocol = { + cmd: "status", + action: "calllist", + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 鑾峰彇璺敱淇℃伅 + routelist() { + const protocol = { + cmd: "status", + action: "routelist", + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 鑾峰彇澶栧懠鍙傛暟淇℃伅 + batch() { + const { paramid } = this.config; + + if (!this.validateParams({ paramid }, ["paramid"])) { + return; + } + + const protocol = { + cmd: "status", + action: "batch", + paramid: paramid, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 寮�濮嬪鍛间换鍔� + batch_start() { + const { seatname, seatnum } = this.config; + + if (!this.validateParams({ seatnum }, ["seatnum"])) { + return; + } + + const protocol = { + cmd: "system", + action: "batch_start", + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 鍋滄澶栧懠浠诲姟 + batch_stop() { + const { seatname, seatnum } = this.config; + + if (!this.validateParams({ seatnum }, ["seatnum"])) { + return; + } + + const protocol = { + cmd: "system", + action: "batch_stop", + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 蹇冭烦鍖� + keepalive(seatname, seatnum) { + if (!this.validateParams({ seatnum }, ["seatnum"])) { + return; + } + + const protocol = { + cmd: "system", + action: "keepalive", + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + this.sendWebSocketMessage(protocol); + }, + + // 娓呴櫎鏃ュ織 + testclear() { + this.logs = ""; + this.addLog("鏃ュ織宸叉竻闄�"); + }, + + // 娣诲姞鏃ュ織 + addLog(message) { + const timestamp = new Date().toLocaleTimeString(); + this.logs += `[${timestamp}] ${message}\n`; + + // 闄愬埗鏃ュ織闀垮害锛岄槻姝㈠唴瀛樻孩鍑� + const logLines = this.logs.split("\n"); + if (logLines.length > 100) { + this.logs = logLines.slice(-50).join("\n"); + } + }, + }, +}; +</script> + +<style scoped> +.websocket-demo { + font-family: Arial, sans-serif; + padding: 20px; + max-width: 1200px; + margin: 0 auto; +} + +.config-area { + margin-bottom: 20px; + padding: 15px; + border: 1px solid #ddd; + border-radius: 4px; + background-color: #f9f9f9; +} + +.input-group { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 10px; + margin-bottom: 10px; +} + +.input-group label { + font-weight: bold; + min-width: 80px; +} + +.input-group input { + padding: 5px 10px; + border: 1px solid #ccc; + border-radius: 3px; + width: 120px; +} + +.button-area { + margin-bottom: 20px; +} + +.button-row { + display: flex; + flex-wrap: wrap; + gap: 5px; + margin-bottom: 10px; +} + +.button-row button { + padding: 8px 15px; + border: 1px solid #ccc; + border-radius: 3px; + background-color: #f0f0f0; + cursor: pointer; + transition: background-color 0.3s; + font-size: 12px; +} + +.button-row button:hover { + background-color: #e0e0e0; +} + +.button-row button:active { + background-color: #d0d0d0; + transform: translateY(1px); +} + +.log-area { + height: 300px; + overflow-y: auto; + border: 1px solid #ccc; + padding: 10px; + background-color: #f5f5f5; + white-space: pre-wrap; + font-family: "Courier New", monospace; + font-size: 12px; + line-height: 1.4; +} + +h3 { + color: #333; + border-bottom: 2px solid #eee; + padding-bottom: 10px; + display: flex; + justify-content: space-between; + align-items: center; +} + +h3 button { + padding: 5px 10px; + font-size: 12px; + background-color: #f0f0f0; + border: 1px solid #ccc; + border-radius: 3px; + cursor: pointer; +} + +/* 鍝嶅簲寮忚璁� */ +@media (max-width: 768px) { + .websocket-demo { + padding: 10px; + } + + .input-group { + flex-direction: column; + align-items: flex-start; + } + + .input-group input { + width: 100%; + } + + .button-row { + flex-direction: column; + } + + .button-row button { + width: 100%; + margin-bottom: 5px; + } +} +</style> diff --git a/src/views/followvisit/discharge/ClickCall.vue b/src/views/followvisit/discharge/ClickCall.vue index 2896d7b..727d67e 100644 --- a/src/views/followvisit/discharge/ClickCall.vue +++ b/src/views/followvisit/discharge/ClickCall.vue @@ -1,21 +1,36 @@ <template> <div class="websocket-demo"> <div> - <h3>Websocket鎺ュ彛娴嬭瘯DEMO</h3> + <h3>Websocket鍛煎彨涓績鎺ュ彛</h3> <div class="config-area"> + <div class="status-indicator"> + <span :class="['status-dot', connectionStatus]"></span> + 杩炴帴鐘舵��: {{ connectionText }} + <span :class="['status-dot', seatStatus]"></span> + 搴у腑鐘舵��: {{ seatStatusText }} + </div> + <div class="input-group"> <label>CTI_WS_URL</label> <input type="text" v-model="config.cti_ws_url" - placeholder="ws://40.78.0.169:6688" + placeholder="wss://your-server.com" /> <label>鍧愬腑宸ュ彿</label> - <input type="text" v-model="config.seatname" placeholder="8000" /> + <input + type="text" + v-model="config.seatname" + :placeholder="randomNum" + /> <label>鍧愬腑鍒嗘満</label> - <input type="text" v-model="config.seatnum" placeholder="8000" /> + <input + type="text" + v-model="config.seatnum" + :placeholder="randomNum" + /> <label>瀵嗙爜</label> <input type="text" v-model="config.password" placeholder="123456" /> @@ -23,129 +38,136 @@ <div class="input-group"> <label>澶栫嚎鍙风爜</label> - <input type="text" v-model="config.phone" placeholder="10086" /> - - <label>UUID</label> - <input type="text" v-model="config.uuid" /> - - <label>鍏朵粬鍧愬腑</label> - <input type="text" v-model="config.other" placeholder="8001" /> + <input + type="text" + v-model="customerPhone" + placeholder="璇疯緭鍏ョ數璇濆彿鐮�" + /> <label>鎶�鑳界粍</label> <input type="text" v-model="config.group" placeholder="a3" /> - - <label>澶栧懠鍙傛暟id</label> - <input type="text" v-model="config.paramid" placeholder="3" /> </div> </div> <!-- 鎿嶄綔鎸夐挳鍖哄煙 --> <div class="button-area"> - <!-- 绗竴琛屾寜閽� --> <div class="button-row"> - <button @click="seatlogin">绛惧叆</button> - <button @click="seatlogout">绛惧嚭</button> - <button @click="afk">绀哄繖</button> - <button @click="online">绀洪棽</button> - <button @click="pickup">浠g瓟</button> + <button + @click="handleSeatLogin" + :disabled="!isConnected || isSeatLoggedIn" + > + 绛惧叆 + </button> + <button @click="handleSeatLogout" :disabled="!isSeatLoggedIn"> + 绛惧嚭 + </button> + <button @click="callout" :disabled="!isSeatLoggedIn">澶栧懠</button> + <button @click="hangup" :disabled="!isSeatLoggedIn">鎸傛満</button> </div> - <!-- 绗簩琛屾寜閽� --> <div class="button-row"> - <button @click="hangup">鎸傛満</button> - <button @click="callout">澶栧懠</button> - <button @click="transfer">閫氳瘽杞Щ</button> - <button @click="transferresume">閫氳瘽杞Щ鏀跺洖</button> - <button @click="hold">閫氳瘽淇濇寔</button> - <button @click="holdresume">閫氳瘽淇濇寔鏀跺洖</button> - <button @click="remove">閫氳瘽寮烘媶</button> - <button @click="insert">閫氳瘽寮烘彃</button> - <button @click="monitor">鐩戝惉</button> - <button @click="monitor_to_talk">鐩戝惉杞�氳瘽</button> - <button @click="monitor_end">鐩戝惉缁撴潫</button> - <button @click="choosecall">閫夋嫨</button> - <button @click="replacecall">浠f帴</button> - <button @click="three">涓夋柟閫氳瘽</button> - </div> - - <!-- 绗笁琛屾寜閽� --> - <div class="button-row"> - <button @click="handoff_ready">鍜ㄨ寮�濮�</button> - <button @click="handoff_call">鍜ㄨ鍛煎彨</button> - <button @click="handoff_resume">鍜ㄨ鏀跺洖</button> - <button @click="handoff_transfer">鍜ㄨ杞Щ</button> - <button @click="handoff_three">鍜ㄨ涓夋柟</button> - <button @click="record_start">寮�濮嬮�氳瘽褰曢煶</button> - <button @click="record_stop">鍋滄閫氳瘽褰曢煶</button> - </div> - - <!-- 绗洓琛屾寜閽� --> - <div class="button-row"> - <button @click="openseatlist">鎵撳紑鍧愬腑鐘舵��</button> - <button @click="closeseatlist">鍏抽棴鍧愬腑鐘舵��</button> - <button @click="openqueues">鎵撳紑闃熷垪淇℃伅</button> - <button @click="closequeues">鍏抽棴闃熷垪淇℃伅</button> - <button @click="opencalllist">鎵撳紑閫氳瘽淇℃伅</button> - <button @click="closecalllist">鍏抽棴閫氳瘽淇℃伅</button> - <button @click="openroutelist">鎵撳紑璺敱淇℃伅</button> - <button @click="closeroutelist">鍏抽棴璺敱淇℃伅</button> - </div> - - <!-- 绗簲琛屾寜閽� --> - <div class="button-row"> - <button @click="seatlist">鑾峰彇鍧愬腑淇℃伅</button> - <button @click="queues">鑾峰彇闃熷垪淇℃伅</button> - <button @click="calllist">鑾峰彇閫氳瘽淇℃伅</button> - <button @click="routelist">鑾峰彇璺敱淇℃伅</button> - <button @click="batch">鑾峰彇澶栧懠鍙傛暟淇℃伅</button> - <button @click="batch_start">寮�濮嬪鍛间换鍔�</button> - <button @click="batch_stop">鍋滄澶栧懠浠诲姟</button> + <button @click="afk" :disabled="!isSeatLoggedIn">绀哄繖</button> + <button @click="online" :disabled="!isSeatLoggedIn">绀洪棽</button> + <button @click="hold" :disabled="!isSeatLoggedIn">淇濇寔</button> + <button @click="holdresume" :disabled="!isSeatLoggedIn"> + 鍙栨秷淇濇寔 + </button> </div> </div> <!-- 鏃ュ織鏄剧ず鍖哄煙 --> - <h3>鍗忚鏃ュ織鍖�<button @click="testclear">娓呴櫎</button></h3> - <div id="msg" class="log-area">{{ logs }}</div> + <h3>鍗忚鏃ュ織鍖� <button @click="testclear">娓呴櫎</button></h3> + <div class="log-area">{{ logs }}</div> </div> </div> </template> <script> +import { CallsetState, CallgetList } from "@/api/AiCentre/index"; + export default { name: "WebsocketDemo", + emits: ["status-change", "call-status", "error"], + + props: { + customerPhone: { + type: String, + default: "", + }, + autoLogin: { + type: Boolean, + default: true, + }, + }, data() { return { config: { - cti_ws_url: "wss://9.208.2.190:8092/cal-api/", - seatname: "8000", - seatnum: "8000", + cti_ws_url: "", + seatname: "", + seatnum: "", password: "123456", - phone: "10086", + phone: "", uuid: "", other: "8001", group: "a3", paramid: "3", }, + randomNum: "", + randomID: "", logs: "", ws: null, isConnected: false, + isSeatLoggedIn: false, + currentCallStatus: "idle", // idle, calling, connected + seatResourceAcquired: false, + reconnectAttempts: 0, + maxReconnectAttempts: 5, + heartbeatTimer: null, }; }, - mounted() { + computed: { + connectionStatus() { + return this.isConnected ? "connected" : "disconnected"; + }, + connectionText() { + return this.isConnected ? "宸茶繛鎺�" : "鏈繛鎺�"; + }, + seatStatus() { + return this.isSeatLoggedIn ? "logged-in" : "logged-out"; + }, + seatStatusText() { + return this.isSeatLoggedIn ? "宸茬鍏�" : "鏈鍏�"; + }, + }, + + watch: { + customerPhone(newVal) { + this.config.phone = newVal; + }, + isSeatLoggedIn(newVal) { + this.$emit("status-change", { + isLoggedIn: newVal, + seatNumber: this.config.seatnum, + status: newVal ? "ready" : "offline", + }); + }, + }, + + async mounted() { + await this.initializeSeatResource(); this.initializeWebSocket(); }, beforeUnmount() { - this.disconnectWebSocket(); + this.cleanup(); }, methods: { // 鍒濆鍖朩ebSocket杩炴帴 initializeWebSocket() { try { - // 鏍规嵁褰撳墠椤甸潰鍗忚鑷姩閫夋嫨WS鍗忚 const isHttps = window.location.protocol === "https:"; this.config.cti_ws_url = isHttps ? "wss://9.208.2.190:8092/cal-api/" @@ -159,22 +181,70 @@ this.connectWebSocket(); } catch (error) { this.addLog(`鍒濆鍖朩ebSocket閿欒: ${error.message}`); - // 灏濊瘯浣跨敤澶囩敤鍦板潃 - this.config.cti_ws_url = "wss://9.208.2.190:8092/cal-api/"; setTimeout(() => this.connectWebSocket(), 2000); } }, + // 鍒濆鍖栧骇甯彿璧勬簮 + async initializeSeatResource() { + try { + const res = await CallgetList(); + if (res.data && res.data.length > 0) { + // this.randomNum = res.data[0].tel; + // this.randomID = res.data[0].id; + this.randomNum = 8000; + this.randomID = 8000; + // 璁剧疆榛樿搴у腑鍙� + this.config.seatname = this.randomNum; + this.config.seatnum = this.randomNum; + // 绔嬪嵆鍗犵敤搴у腑鍙疯祫婧� + await this.startCallsetState(); + this.seatResourceAcquired = true; + this.addLog(`搴у腑鍙疯祫婧愯幏鍙栨垚鍔�: ${this.randomNum}`); + } + } catch (error) { + console.error("鑾峰彇搴у腑鍙峰け璐�:", error); + this.addLog("閿欒: 鑾峰彇搴у腑鍙疯祫婧愬け璐�"); + this.$emit("error", { type: "seat_acquisition_failed", error }); + } + }, + // 鍗犵敤搴у腑鍙� + async startCallsetState() { + try { + await CallsetState({ id: this.randomID, state: 1 }); + this.addLog("搴у腑鍙风姸鎬佹洿鏂颁负浣跨敤涓�"); + } catch (error) { + console.error("鏇存柊搴у腑鍙风姸鎬佸け璐�:", error); + throw error; + } + }, + + // 閲婃斁搴у腑鍙� + async releaseSeatResource() { + if (this.seatResourceAcquired && this.randomID) { + try { + await CallsetState({ id: this.randomID, state: 0 }); + this.addLog("搴у腑鍙疯祫婧愬凡閲婃斁"); + this.seatResourceAcquired = false; + } catch (error) { + console.error("閲婃斁搴у腑鍙峰け璐�:", error); + } + } + }, + // 杩炴帴WebSocket // 杩炴帴WebSocket connectWebSocket() { if (this.ws && this.ws.readyState === WebSocket.OPEN) { - this.addLog("WebSocket宸茶繛鎺�"); + return; + } + + if (this.reconnectAttempts >= this.maxReconnectAttempts) { + this.addLog("閿欒: 杈惧埌鏈�澶ч噸杩炴鏁帮紝鍋滄閲嶈繛"); return; } try { let wsUrl = this.config.cti_ws_url; - // 纭繚HTTPS椤甸潰浣跨敤WSS if ( window.location.protocol === "https:" && wsUrl.startsWith("ws://") @@ -186,7 +256,14 @@ this.ws.onopen = () => { this.isConnected = true; + this.reconnectAttempts = 0; this.addLog("WebSocket杩炴帴鎴愬姛"); + this.startHeartbeat(); + + // 杩炴帴鎴愬姛鍚庤嚜鍔ㄧ鍏� + if (this.autoLogin && this.seatResourceAcquired) { + setTimeout(() => this.handleSeatLogin(), 500); + } }; this.ws.onmessage = (event) => { @@ -195,54 +272,202 @@ this.ws.onclose = (event) => { this.isConnected = false; + this.isSeatLoggedIn = false; + this.stopHeartbeat(); this.addLog(`WebSocket杩炴帴鍏抽棴: ${event.code} ${event.reason}`); + // 鑷姩閲嶈繛 - setTimeout(() => this.connectWebSocket(), 3000); + if (this.reconnectAttempts < this.maxReconnectAttempts) { + this.reconnectAttempts++; + setTimeout(() => this.connectWebSocket(), 3000); + } }; this.ws.onerror = (error) => { this.addLog(`WebSocket閿欒: ${error.message}`); - // 灏濊瘯澶囩敤URL - if (!wsUrl.includes("9.208.2.190")) { - this.config.cti_ws_url = "wss://9.208.2.190:8092/cal-api/"; - setTimeout(() => this.connectWebSocket(), 3000); - } }; } catch (error) { this.addLog(`杩炴帴WebSocket澶辫触: ${error.message}`); - // 灏濊瘯澶囩敤URL - this.config.cti_ws_url = "wss://9.208.2.190:8092/cal-api/"; setTimeout(() => this.connectWebSocket(), 3000); } }, // 澶勭悊WebSocket娑堟伅 handleWebSocketMessage(event) { - const reader = new FileReader(); - reader.onloadend = (e) => { - const message = reader.result; - this.addLog(`鏀跺埌娑堟伅: ${message}`); - - try { - const obj = JSON.parse(message); - - // 澶勭悊蹇冭烦鍖� - if (obj.cmd === "system" && obj.action === "keepalive") { - this.keepalive(obj.seatname, obj.seatnum); - } - - // 鑷姩璁剧疆UUID - if (obj.cmd === "control" && obj.action === "tp_callin") { - this.config.uuid = obj.uuid; - this.addLog(`鑷姩璁剧疆UUID: ${obj.uuid}`); - } - } catch (error) { - this.addLog(`娑堟伅瑙f瀽閿欒: ${error.message}`); + try { + // 妫�鏌ユ暟鎹被鍨嬶細鍙兘鏄瓧绗︿覆鎴朆lob + if (event.data instanceof Blob) { + // 澶勭悊浜岃繘鍒舵暟鎹紙Blob锛� + const reader = new FileReader(); + reader.onload = () => { + try { + const textData = reader.result; + this.addLog(`鏀跺埌Blob娑堟伅: ${textData}`); + this.processWebSocketData(textData); + } catch (error) { + this.addLog(`Blob鏁版嵁澶勭悊閿欒: ${error.message}`); + } + }; + reader.readAsText(event.data); + } else if (typeof event.data === "string") { + // 鐩存帴澶勭悊鏂囨湰鏁版嵁 + this.addLog(`鏀跺埌鏂囨湰娑堟伅: ${event.data}`); + this.processWebSocketData(event.data); + } else { + this.addLog(`鏈煡鏁版嵁绫诲瀷: ${typeof event.data}`); } + } catch (error) { + this.addLog(`娑堟伅澶勭悊閿欒: ${error.message}`); + } + }, + // 涓撻棬澶勭悊瑙f瀽鍚庣殑WebSocket鏁版嵁 + processWebSocketData(messageText) { + console.log(messageText,'娑堟伅1'); + + try { + const obj = JSON.parse(messageText); + console.log(obj,'娑堟伅2'); + + // 澶勭悊蹇冭烦鍖� + if (obj.cmd === "system" && obj.action === "keepalive") { + this.keepalive(obj.seatname, obj.seatnum); + } + // 澶勭悊鎸傛柇 + if (obj.action === "calloutend") { + this.hangup(); + } + + // 澶勭悊绛惧叆鍝嶅簲 + if (obj.cmd === "system" && obj.action === "seatlogin") { + this.isSeatLoggedIn = true; + this.addLog("搴у腑绛惧叆鎴愬姛"); + this.$emit("status-change", { + isLoggedIn: true, + seatNumber: this.config.seatnum, + status: "ready", + }); + } + + // 澶勭悊绛惧嚭鍝嶅簲 + if (obj.cmd === "system" && obj.action === "seatlogout") { + this.isSeatLoggedIn = false; + this.addLog("搴у腑绛惧嚭鎴愬姛"); + this.$emit("status-change", { + isLoggedIn: false, + status: "offline", + }); + } + + // 鑷姩璁剧疆UUID锛堟潵鐢典簨浠讹級 + if (obj.cmd === "control" && obj.action === "tp_callin") { + this.config.uuid = obj.uuid; + this.addLog(`鑷姩璁剧疆UUID: ${obj.uuid}`); + this.$emit("call-status", { + status: "incoming", + uuid: obj.uuid, + phone: obj.phone || "鏈煡鍙风爜", + }); + } + + // 澶勭悊澶栧懠鍝嶅簲 + if (obj.cmd === "control" && obj.action === "callout") { + this.$emit("call-status", { + status: obj.status || "calling", + uuid: obj.uuid, + phone: this.config.phone, + }); + } + + // 澶勭悊鎸傛満鍝嶅簲 + if (obj.cmd === "control" && obj.action === "hangup") { + this.$emit("call-status", { + status: "idle", + uuid: obj.uuid, + }); + } + + // 澶勭悊閫氳瘽鐘舵�佸彉鍖� + if (obj.cmd === "control" && obj.status) { + this.handleCallStatusChange(obj); + } + } catch (error) { + this.addLog(`JSON瑙f瀽閿欒: ${error.message}, 鍘熷鏁版嵁: ${messageText}`); + } + }, + // 澶勭悊鍛煎彨鐘舵�佸彉鍖� + handleCallStatusChange(obj) { + const statusMap = { + ringing: "鎸搩涓�", + connected: "閫氳瘽涓�", + held: "宸蹭繚鎸�", + ended: "閫氳瘽缁撴潫", }; - reader.readAsText(event.data); + + this.addLog(`閫氳瘽鐘舵��: ${statusMap[obj.status] || obj.status}`); + this.$emit("call-status", { + status: obj.status, + uuid: obj.uuid, + phone: obj.phone || this.config.phone, + }); + }, + // 寮�濮嬪績璺虫娴� + startHeartbeat() { + this.heartbeatTimer = setInterval(() => { + if (this.isConnected && this.isSeatLoggedIn) { + this.keepalive(this.config.seatname, this.config.seatnum); + } + }, 30000); // 30绉掑績璺� }, + // 鍋滄蹇冭烦妫�娴� + stopHeartbeat() { + if (this.heartbeatTimer) { + clearInterval(this.heartbeatTimer); + this.heartbeatTimer = null; + } + }, + // 搴у腑绛惧叆 + async handleSeatLogin() { + if (!this.seatResourceAcquired) { + this.addLog("閿欒: 鏈幏鍙栧骇甯彿璧勬簮锛屾棤娉曠鍏�"); + return; + } + + const { seatname, seatnum, password } = this.config; + if (!seatname || !seatnum) { + this.addLog("閿欒: 搴у腑宸ュ彿鍜屽垎鏈哄彿涓嶈兘涓虹┖"); + return; + } + + const protocol = { + cmd: "system", + action: "seatlogin", + seatname: seatname, + seatnum: seatnum, + password: password, + timestamp: Date.now(), + }; + + this.sendWebSocketMessage(protocol); + }, + // 搴у腑绛惧嚭 + async handleSeatLogout() { + const { seatname, seatnum } = this.config; + + const protocol = { + cmd: "system", + action: "seatlogout", + seatname: seatname, + seatnum: seatnum, + timestamp: Date.now(), + }; + + if (this.sendWebSocketMessage(protocol)) { + this.isSeatLoggedIn = false; + // 寤惰繜閲婃斁璧勬簮锛岀‘淇濈鍑哄畬鎴� + setTimeout(() => this.releaseSeatResource(), 1000); + } + }, // 鏂紑WebSocket杩炴帴 disconnectWebSocket() { if (this.ws) { @@ -333,19 +558,11 @@ // 绀哄繖 afk() { - const { seatname, seatnum } = this.config; - - if ( - !this.validateParams({ seatname, seatnum }, ["seatname", "seatnum"]) - ) { - return; - } - const protocol = { cmd: "system", action: "afk", - seatname: seatname, - seatnum: seatnum, + seatname: this.config.seatname, + seatnum: this.config.seatnum, timestamp: Date.now(), }; this.sendWebSocketMessage(protocol); @@ -353,19 +570,11 @@ // 绀洪棽 online() { - const { seatname, seatnum } = this.config; - - if ( - !this.validateParams({ seatname, seatnum }, ["seatname", "seatnum"]) - ) { - return; - } - const protocol = { cmd: "system", action: "online", - seatname: seatname, - seatnum: seatnum, + seatname: this.config.seatname, + seatnum: this.config.seatnum, timestamp: Date.now(), }; this.sendWebSocketMessage(protocol); @@ -391,27 +600,28 @@ // 鎸傛満 hangup() { - const { seatname, seatnum } = this.config; - - if (!this.validateParams({ seatnum }, ["seatnum"])) { - return; - } - const protocol = { cmd: "control", action: "hangup", - seatname: seatname, - seatnum: seatnum, + seatname: this.config.seatname, + seatnum: this.config.seatnum, timestamp: Date.now(), }; this.sendWebSocketMessage(protocol); }, // 澶栧懠 - callout() { - const { seatname, seatnum, phone } = this.config; + // 澶栧懠鎿嶄綔 + async callout(phoneNumber = null) { + const phone = phoneNumber || this.customerPhone || this.config.phone; + if (!phone) { + this.addLog("閿欒: 琚彨鍙风爜涓嶈兘涓虹┖"); + this.$emit("error", { type: "phone_number_required" }); + return; + } - if (!this.validateParams({ seatnum, phone }, ["seatnum", "phone"])) { + if (!this.isSeatLoggedIn) { + this.addLog("閿欒: 搴у腑鏈鍏ワ紝鏃犳硶澶栧懠"); return; } @@ -419,13 +629,23 @@ cmd: "control", action: "callout", phone: phone, - seatname: seatname, - seatnum: seatnum, + seatname: this.config.seatname, + seatnum: this.config.seatnum, timestamp: Date.now(), }; - this.sendWebSocketMessage(protocol); - }, + this.sendWebSocketMessage(protocol); + this.$emit("call-status", { status: "calling", phone }); + }, + // 娓呯悊璧勬簮 + cleanup() { + this.stopHeartbeat(); + if (this.ws) { + this.ws.close(); + this.ws = null; + } + this.releaseSeatResource(); + }, // 閫氳瘽杞Щ transfer() { const { seatname, seatnum, phone, uuid } = this.config; @@ -480,18 +700,12 @@ // 閫氳瘽淇濇寔 hold() { - const { seatname, seatnum, uuid } = this.config; - - if (!this.validateParams({ seatnum, uuid }, ["seatnum", "uuid"])) { - return; - } - const protocol = { cmd: "control", action: "hold", - uuid: uuid, - seatname: seatname, - seatnum: seatnum, + uuid: this.config.uuid, + seatname: this.config.seatname, + seatnum: this.config.seatnum, timestamp: Date.now(), }; this.sendWebSocketMessage(protocol); @@ -499,18 +713,12 @@ // 閫氳瘽淇濇寔鏀跺洖 holdresume() { - const { seatname, seatnum, uuid } = this.config; - - if (!this.validateParams({ seatnum, uuid }, ["seatnum", "uuid"])) { - return; - } - const protocol = { cmd: "control", action: "holdresume", - uuid: uuid, - seatname: seatname, - seatnum: seatnum, + uuid: this.config.uuid, + seatname: this.config.seatname, + seatnum: this.config.seatnum, timestamp: Date.now(), }; this.sendWebSocketMessage(protocol); @@ -1059,12 +1267,7 @@ this.sendWebSocketMessage(protocol); }, - // 蹇冭烦鍖� keepalive(seatname, seatnum) { - if (!this.validateParams({ seatnum }, ["seatnum"])) { - return; - } - const protocol = { cmd: "system", action: "keepalive", @@ -1097,6 +1300,87 @@ </script> <style scoped> +.status-indicator { + margin-bottom: 15px; + padding: 10px; + background: #f5f5f5; + border-radius: 4px; + display: flex; + align-items: center; + gap: 10px; +} + +.status-dot { + width: 10px; + height: 10px; + border-radius: 50%; + display: inline-block; +} + +.status-dot.connected { + background-color: #52c41a; +} + +.status-dot.disconnected { + background-color: #f5222d; +} + +.status-dot.logged-in { + background-color: #1890ff; +} + +.status-dot.logged-out { + background-color: #d9d9d9; +} + +.button-row button:disabled { + opacity: 0.6; + cursor: not-allowed; +} + +.config-area { + margin-bottom: 20px; +} + +.input-group { + display: flex; + flex-wrap: wrap; + gap: 10px; + margin-bottom: 10px; +} + +.input-group label { + font-weight: bold; + min-width: 80px; +} + +.input-group input { + padding: 5px 10px; + border: 1px solid #ccc; + border-radius: 3px; + width: 120px; +} + +.button-area { + margin-bottom: 20px; +} + +.button-row { + display: flex; + flex-wrap: wrap; + gap: 5px; + margin-bottom: 10px; +} + +.log-area { + height: 200px; + overflow-y: auto; + border: 1px solid #ccc; + padding: 10px; + background: #f5f5f5; + white-space: pre-wrap; + font-family: monospace; +} .websocket-demo { font-family: Arial, sans-serif; padding: 20px; diff --git a/src/views/followvisit/record/detailpage/index.vue b/src/views/followvisit/record/detailpage/index.vue index c5945bb..0525fec 100644 --- a/src/views/followvisit/record/detailpage/index.vue +++ b/src/views/followvisit/record/detailpage/index.vue @@ -1013,6 +1013,18 @@ <el-button type="primary" @click="setupsubtask">纭鍒涘缓鏈嶅姟</el-button> </div> </el-dialog> + <div class="main-content" v-if="orgname == '鏅畞鐣叉棌鑷不鍘夸汉姘戝尰闄�'"> + <!-- <el-button @click="CaldialogVisible = true">鎵撳紑寮规</el-button> --> + + <!-- 寮规璋冪敤 --> + <el-dialog + title="鍛煎彨鍔熻兘妗�" + :visible.sync="CaldialogVisible" + width="60%" + > + <CallCenterLs ref="callCenterModal" :initial-phone="currentPhoneNumber" /> + </el-dialog> + </div> </div> </template> @@ -1038,10 +1050,12 @@ } from "@/api/patient/homepage"; import CallButton from "@/components/CallButton"; import MergeAndModify from "./MergeAndModify.vue"; +import CallCenterLs from "@/components/CallCenterLs"; export default { components: { CallButton, MergeAndModify, + CallCenterLs, }, directives: { numericOnly: { @@ -1125,6 +1139,7 @@ // 宸叉湁鏁版嵁... callStatus: "idle", // idle, calling, connected, ended, failed isEndingCall: false, + CaldialogVisible: false, currentCall: null, // 褰撳墠閫氳瘽瀵硅薄 input: "浠婂ぉ韬綋杩樹笉閿�", radio: "2", @@ -1673,8 +1688,13 @@ this.$message.error("璇疯緭鍏ユ纭殑鎵嬫満鍙风爜"); return; } - this.currentPhoneNumber = phone; + // 鍛煎彨鍒ゆ柇 + if (this.orgname == "鏅畞鐣叉棌鑷不鍘夸汉姘戝尰闄�") { + this.CaldialogVisible = true; + return + } + this.callType = type; this.callStatus = "calling"; @@ -1721,28 +1741,28 @@ }, 3000); }, yuyingetdetail() { - const dataToSubmit = JSON.parse(JSON.stringify(this.tableDatatop)); + const dataToSubmit = JSON.parse(JSON.stringify(this.tableDatatop)); - dataToSubmit.forEach((item, index) => { - // 瀵规嫹璐濈殑鏁版嵁杩涜鎿嶄綔锛屼笉褰卞搷鍘熷鐨� scriptResult 鏁扮粍 - item.scriptResult = item.scriptResult.join("&"); - item.templatequestionnum = index + 1; - item.subId = this.id; - item.taskid = this.taskid; - item.asrtext = item.matchedtext; - if (!item.id) { - item.isoperation = 1; - } - item.patid = this.patid; - item.templateid = item.templateID; - }); + dataToSubmit.forEach((item, index) => { + // 瀵规嫹璐濈殑鏁版嵁杩涜鎿嶄綔锛屼笉褰卞搷鍘熷鐨� scriptResult 鏁扮粍 + item.scriptResult = item.scriptResult.join("&"); + item.templatequestionnum = index + 1; + item.subId = this.id; + item.taskid = this.taskid; + item.asrtext = item.matchedtext; + if (!item.id) { + item.isoperation = 1; + } + item.patid = this.patid; + item.templateid = item.templateID; + }); - let obj = { - serviceSubtaskDetailList: dataToSubmit, // 鎻愪氦澶勭悊鍚庣殑鍓湰 - param1: this.taskid, - param2: this.patid, - subId: this.id, - }; + let obj = { + serviceSubtaskDetailList: dataToSubmit, // 鎻愪氦澶勭悊鍚庣殑鍓湰 + param1: this.taskid, + param2: this.patid, + subId: this.id, + }; addPersonVoices(obj).then((res) => { if (res.code == 200) { diff --git a/vue.config.js b/vue.config.js index e6f390f..5f97768 100644 --- a/vue.config.js +++ b/vue.config.js @@ -37,8 +37,8 @@ [process.env.VUE_APP_BASE_API]: { // target: `https://www.health-y.cn/lssf`, // target: `http://192.168.100.129:8095`, - target: `http://192.168.100.10:8096`, - // target:`http://localhost:8095`, + // target: `http://192.168.100.10:8096`, + target:`http://localhost:8095`, // target:`http://35z1t16164.qicp.vip`, // target: `http://192.168.100.193:8095`, // target: `http://192.168.101.166:8093`, -- Gitblit v1.9.3