jssip-emicnet
Version:
jssip wrapper, use for emicnet callcenter
997 lines (968 loc) • 127 kB
JavaScript
import Logger from '../lib/Logger'
import Phone from './phone'
import creatHtml from './html'
import config from '../lib/config'
const logger = new Logger('phonebar:ui')
; (function (global, doc) {
class Ephone {
constructor() {
//定义Ephone的属性
this.options = {
width: '490px',
height: '50px',
background: '',
callBackground: ['#1E59B9', '#19C583', '#FF6754', '#E6A23C'],
drop: true
}
this.closeTimer = null
this.watchTimer = null
this.outTimer = null
this.titleTimer = null
this.recordsTotal = null // 某组坐席总数 滚动加载时使用
this.callintype = 2 // 模式
this.callType = 0 // type = 1 外线拨号 type = 2 回拨 type = 3 内线互拨
this._ccNumber = undefined //ccNumber
this.socket_uri = config.devcm
this.consultParams = {}
this.monitorState = {
isMonitor: false, // 标记是否在监听状态
selectedSeat: null, // 被选中的坐席
selectedGid: undefined // 被选中的技能组 id
}
}
init(targetID, options) {
// var ccNumber = localStorage.getItem("ccNumber")
var userData = localStorage.userData
? JSON.parse(localStorage.userData)
: false
var toolbar = document.createElement('div')
var target =
doc.querySelector(targetID) || doc.querySelector('body')
if (!!window.ActiveXObject || 'ActiveXObject' in window) {
target.innerHTML =
"<h1 style='text-align:center'>请使用非 IE 浏览器!!!</h1>"
return
}
//初始化配置
if (typeof options == 'object' && options) {
this.options.width = options.width
? options.width
: this.options.width
this.options.height = options.height
? options.height
: this.options.height
this.options.background = options.background
? options.background
: this.options.background
this.options.drop =
options.drop != undefined ? options.drop : this.options.drop
this.options.callBackground =
options.callBackground &&
Array.isArray(options.callBackground)
? options.callBackground
: this.options.callBackground
}
//增加拖拽功能
if (this.options.drop) {
this._addDrop(toolbar, target)
}
//html
toolbar.style.maxWidth = this.options.width
toolbar.style.boxShadow = '0px 1px 15px ' + '#c3c3c3'
toolbar.style.zIndex = 999
toolbar.style.background = this.options.background
toolbar.id = 'PHONE-DROP'
toolbar.innerHTML = creatHtml(this.options)
target.appendChild(toolbar)
if (localStorage.refresh) {
alert('您可能已打开一个页面,同时打开多个页面会造成通话不正常')
/*
* 经过试验,强制关闭 Safari浏览器 beforeunload不会被执行
* Chrome 75版本可以,但我们确实也碰到refresh没被清除的情况,暂时没找到复现规律
* 所以保险点就是清掉refresh。
* 如果是异常造成refresh没清掉,下次再打开就可以了
* 如果确实已打开一个tab,清掉了refresh,唯一问题是再打开一次,不再提醒了。
*/
localStorage.removeItem('refresh')
window.open(
'https://www.yuque.com/yimi/phonebar/welcome-to-lark',
'_self'
)
return
} else {
localStorage.refresh = '1'
}
//添加DOM事件处理
this.eventListener()
// this._hideAllMode()
// https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event
window.addEventListener('beforeunload', e => {
Phone.terminate(this.ccNumber)
if (Phone.kefuStatus == 0 && localStorage.getItem('userData'))
localStorage.removeItem('userData')
localStorage.removeItem('refresh')
e.returnValue = '离开取消会话'
})
// 初始位置 功能按钮位置 配置项可配
if (userData && userData.setting) {
this.setTogglePosition(userData.setting)
}
}
eventListener() {
var stopProList = []
var that = this //回调函数才需要that=this,或者箭头函数
var targetId = '' // 技能组id
var timer = null
var page = 1 // 记录当前页数
var checked = 0 // 仅查可转接坐席是否勾选 0 未勾选 1 已勾选
var gid
var tranNumber
// 三方
var threeway = 0
//工具条元素
let actionButtons = doc.querySelectorAll(
'#EphoneBar li[data-phone-key]'
)
let registerBtn = doc.querySelector(
"#EphoneBar li[data-phone-type='register']"
) //登陆
var holdBtn = doc.querySelector(
"#EphoneBar li[data-phone-type='hold']"
)
var unHoldBtn = doc.querySelector(
"#EphoneBar li[data-phone-type='unhold']"
)
let planePageBtn = doc.querySelector(
"#PHONE-LEFT-STATUS>div[data-type='planePage']>div"
) //拨号面板按钮
let kefuStatus = registerBtn.querySelector(
"span[data-type='toggle']"
) //注册按钮显示状态
//弹框元素
let loginTarget = doc.querySelector('#PHONE-ENTRY-LOGIN[data-hide]') //登陆页面
let selectGroupTarget = doc.querySelector(
'#PHONE-ENTRY-SELECTGROUP[data-hide]'
) //登陆选择技能组
let toggleTarget = doc.querySelector(
'#PHONE-ENTRY-TOGGLE[data-hide]'
) //切换状态
let settingTarget = doc.querySelector(
'#PHONE-ENTRY-SETTING[data-hide]'
) //设置页面
let panel = doc.querySelector('#PHONE-ENTRY-PANEL[data-hide]') //拨号面板
let switchPage = doc.querySelector('#PHONE-ENTRY-SWITCH') //转接页面
var incomingStatus = doc.querySelector(
"#PHONE-LEFT-STATUS>div[data-type='incomingStatus']>div"
) //来电
//loginTarget 登陆页面元素
let Logininputs = doc.querySelectorAll(
'#PHONE-ENTRY-LOGIN[data-hide] input[data-type]'
)
let switchnumber = Logininputs[0] //总机号
let seatnumber = Logininputs[1] //分机号
let password = Logininputs[2] //密码
let modelnumber = Logininputs[3] //回拨话机/sip话机
let error = loginTarget.querySelector("span[data-type='error']") // 错误提示
var statusBtn = loginTarget.querySelector(
"[data-type='loginStatus']"
)
var status_text = statusBtn.querySelector('span') // 示忙/示闲
let modelSel = loginTarget.querySelectorAll(
"li input[name='callintype']"
)
let modelLi = loginTarget.querySelector("li[data-type='model']")
//selectGroupTarget 登陆选组元素
let selectGroupTargetConfirm = selectGroupTarget.querySelector(
"button[data-type='confirm']"
)
let busyStatus = toggleTarget.querySelector("li[data-state_id='2']")
// settingTarget //设置页面元素
let moveBtn = settingTarget.querySelector("input[value='51']")
let fixBtn = settingTarget.querySelector("input[value='52']")
let wsUrl = settingTarget.querySelector("input[data-type='wsUrl']")
let settingError = settingTarget.querySelector(
"span[data-type='error']"
)
//panel 快速拨号元素
let panelInput = panel.querySelector("input[data-type='input']") //手机号输入框
// switchPage转接页元素
let p = switchPage.querySelector("div[data-type='select_text']")
let errorTitle = switchPage.querySelector("span[data-type='error']")
let checkInp = switchPage.querySelector("input[type='checkbox']")
let optionInp = switchPage.querySelectorAll('option')
let kefuList = switchPage.querySelector("ul[data-type='kefuList']") //坐席
// monitorPage 页面的相关元素
const MonitorPage = doc.querySelector('#PHONE-ENTRY-MONITOR') //监控页面
const MonitorPage_p = MonitorPage.querySelector(
"div[data-type='select_text']"
)
const MonitorPage_error = MonitorPage.querySelector(
"span[data-type='error']"
)
const MonitorPage_checkbox = MonitorPage.querySelector(
"input[type='checkbox']"
)
const MonitorPage_options = MonitorPage.querySelector('option')
const MonitorPage_kefuList = MonitorPage.querySelector(
"ul[data-type='kefuList']"
)
let MonitorGroupTarget = doc.querySelector(
'#PHONE-ENTRY-MONITOR[data-hide]'
)
//incomingStatus来电呼入
let incomingS = incomingStatus.querySelector(
"span[data-type='status']"
)
let incomingA = incomingStatus.querySelector(
"button[data-type='answer']"
)
let title = doc.querySelector(
"#PHONE-LEFT-STATUS div[data-type='pattern']>div"
) //移动模式提示
// 咨询按钮的 dom
// eslint-disable-next-line prettier/prettier
const consultBtn = doc.querySelector(
"li[data-phone-type='consult']"
)
const consultCancelBtn = doc.querySelector(
"li[data-phone-type='consult-cancel']"
)
const consultPage = doc.querySelector('#PHONE-ENTRY-CONSULT')
// eslint-disable-next-line prettier/prettier
const consultTabs = consultPage.querySelectorAll(
'li[class="consult-tab-header-item"]'
)
// 咨询的 tab 点击
Array.from(consultTabs).forEach(tab => {
tab.onclick = event => {
event.stopPropagation()
Array.from(consultTabs).forEach(tab => {
tab.classList.remove('active')
})
tab.classList.add('active')
const type = tab.dataset.type
switch (type) {
case 'consult-to-seat':
// 获取咨询的坐席
// eslint-disable-next-line prettier/prettier
that.getGroupMembers(
{ gid: '' },
null,
'consultPage'
)
break
case 'consult-to-group':
// 获取咨询的技能组
that.getGroups('consultPage')
break
case 'consult-to-outline':
// 获取咨询的外线
that.getOutlineNumbres()
break
default:
// 默认获取坐席
// eslint-disable-next-line prettier/prettier
that.getGroupMembers(
{ gid: '' },
null,
'consultPage'
)
}
}
})
//自动登陆
if (localStorage && localStorage.userData) {
this.register()
}
// 聚焦 错误提示隐藏
// Array.from(Logininputs).forEach(v => {
// v.onfocus = () => { error.innerText = '' }
// })
//工具条点击事件
Array.from(actionButtons).forEach(v => {
stopProList.push(v)
v.onclick = async function (e) {
e.stopPropagation()
//this here is v so we can't use arrow function.
//BUT I really hate coding like this!!
var type = this.getAttribute('data-phone-type')
var key = this.getAttribute('data-phone-key')
try {
JSON.parse(localStorage.userData)
} catch (err) {
if (err) {
if (Phone.kefuStatus > 0) alert('请重新登录')
that.sethighlight('register setting', true)
kefuStatus.dataset.hide = '0'
Phone.logout()
}
}
if (this.classList.contains('gray')) return
let userData = localStorage.userData
? JSON.parse(localStorage.userData)
: undefined
// const cc_number = that.monitorState?.selectedSeat?.cc_number;
const cc_number = that.monitorState && that.monitorState.selectedSeat && that.monitorState.selectedSeat.cc_number;
const monitor_uid = that.monitorState && that.monitorState.selectedSeat && that.monitorState.selectedSeat.monitor_uid;
switch (key) {
case '0': //注册,这里主要是续注册处理,要优化
logger.logDB(logger.debug, `当前状态:${Phone.kefuStatus}`)
if (Phone.kefuStatus > 0) {
userData = JSON.parse(localStorage.userData)
// //状态 退出空闲忙碌元素
let statusBtns = toggleTarget.querySelector(
"li[data-type='state']"
)
Array.from(statusBtns).forEach(v => {
v.dataset.hide =
userData.seatMode == 1 ? '0' : '1'
})
// leisureStatus.dataset.hide = busyStatus.dataset.hide =
// userData.seatMode == 1 ? '0' : '1'
that.setDisplayNone('statusPage')
} else {
that.setDisplayNone('loginPage')
}
break
case '1': // 快速呼叫 挂断 保持 恢复
if (type == 'open') {
that.setDisplayNone('fastPage')
}
if (type == 'terminate') {
Phone.terminate(that.ccNumber)
}
if (type == 'hold') {
// Phone.hold(that.ccNumber)
//TODO MPTY call test 借用hold
threeway += 1
logger.logDB(logger.debug, '借用hold调试三方通话')
if (threeway % 2 == 1) {
Phone.threewayCall({
ccNumber: that.ccNumber,
type: 3,
callee: '95555'
})
} else {
Phone.threewayCall({
ccNumber: that.ccNumber,
type: 4
})
}
}
if (type == 'unhold') {
Phone.unhold(that.ccNumber)
}
break
case '2': // 转接
var hide = doc.querySelector(
'#PHONE-ENTRY-SWITCH[data-hide]'
).dataset.hide
if (hide == 0) {
// 置空可转接座席选择框
checkInp.checked = false
checked = 0
// 获取技能组
that.getGroups()
// 获取坐席 getGroupMembers
userData = localStorage.userData
? JSON.parse(localStorage.userData)
: {}
gid = userData.loginGid ? userData.loginGid : -1
that.getGroupMembers({ gid: gid })
// 获取技能组状态 getMemberCallStates
// var res3 = await Phone.webApiHandler("getMemberCallStates", webParam)
// console.log({ getMemberCallStates: res3 })
}
that.setDisplayNone('switchPage')
break
case '4': //设置
that.setDisplayNone('setting')
wsUrl.value = that.socket_uri
if (userData && Phone.kefuStatus > 0) {
userData.seatMode == '1'
? (moveBtn.checked = true)
: (fixBtn.checked = true)
moveBtn.disabled = fixBtn.disabled = false
wsUrl.disabled = true
} else {
wsUrl.disabled = false
moveBtn.disabled = fixBtn.disabled = fixBtn.checked = true
}
break
case '5': // 监控的
switch (type) {
case 'consult': // 咨询
that.setDisplayNone('consultPage')
break
case 'monitor_show': // 唤出页面之前应该先去获取可以被监听的坐席列表
if (
doc.querySelector(
'#PHONE-ENTRY-MONITOR[data-hide]'
).dataset.hide == 0
) {
// 调用接口 获取可被监听的列表
await that.getMonitorGroups()
await that.getMonitorGroupSeats('')
that.setDisplayNone('monitorPage')
}
break
case 'monitor_terminate': // 结束监听
// op_code 1 监听 2 强插 3 强拆/结束监听
if (!that.monitorState.isMonitor && !cc_number && !monitor_uid) {
return
}
await that.monitorTerminate(cc_number, monitor_uid)
break
case 'monitor_insert': // 强插
if (!that.monitorState.isMonitor && !cc_number && !monitor_uid) {
return
}
await that.monitorInsert(cc_number, monitor_uid)
break
case 'monitor_remove': // 强拆
if (!that.monitorState.isMonitor && !cc_number && !monitor_uid) {
return
}
await that.monitorRemove(cc_number, monitor_uid)
break
case 'monitor_intercept': // 拦截
if (!that.monitorState.isMonitor && !cc_number && !monitor_uid) {
return
}
await that.monitorIntercept(cc_number, monitor_uid)
break
}
break
case '6': // 取消咨询
that.consultParams.type = 4
await Phone.consultCall(that.consultParams)
that.consultParams = {}
consultBtn.dataset.hide = '1'
consultCancelBtn.dataset.hide = '0'
that.sethighlight('terminal,consult', true)
break
case '7': // 静音的
if (type === 'mute_start') {
// 请求静音的逻辑
that.muteStart(that.ccNumber)
} else {
// 取消静音的逻辑
that.muteRemove(that.ccNumber)
}
break
default:
break
}
}
})
//话机模式 切换
Array.from(modelSel).forEach(v => {
v.onchange = function () {
if (this.value != '2') {
modelLi.dataset.hide = '1'
modelLi.querySelectorAll('span').forEach(sv => {
sv.dataset.hide =
sv.dataset.type == this.value ? '1' : '0'
})
modelnumber.value = ''
modelnumber.oninput = null
modelnumber.oninput = function () {
v.value == '5'
? (this.value = this.value.replace(/\D/g, ''))
: (this.value = this.value.replace(
/[^0-9A-Z]/g,
''
))
this.value.length > 15
? (this.value = this.value.substr(0, 14))
: this.value
}
} else {
modelLi.dataset.hide = '0'
}
}
})
//loginTarget 登陆页面
loginTarget.onclick = async function (e) {
e.stopPropagation()
var target = e.target || e.srcElement
that._closePage(target, loginTarget)
if (
target.dataset.type == 'loginStatus' ||
target.parentNode.dataset.type == 'loginStatus'
) {
var hasBusyClass = statusBtn.classList.contains('busy')
hasBusyClass
? statusBtn.classList.remove('busy')
: statusBtn.classList.add('busy')
status_text.innerText = hasBusyClass ? '示闲' : '示忙'
let preferredStatus = hasBusyClass ? '1' : '2'
localStorage.setItem('preferredStatus', preferredStatus)
}
if (target.dataset.type == 'login') {
var checkedModel = loginTarget.querySelector(
"li input[name='callintype']:checked"
).value
//https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/radio
//https://developer.mozilla.org/en-US/docs/Web/API/DOMString
//所以返回是string, 我们再转成 int
that.callintype = +checkedModel
if (switchnumber.value.length == 0)
return that.showError(
switchnumber,
error,
'请输入总机号码'
)
if (seatnumber.value.length == 0)
return that.showError(
seatnumber,
error,
'请输入分机号码'
)
if (
seatnumber.value.length < 4 ||
seatnumber.value.length > 6
)
return that.showError(
seatnumber,
error,
'分机号码错误,请重新输入'
)
if (password.value.length == 0)
return that.showError(password, error, '请输入密码')
if (checkedModel != '2' && modelnumber.value.length == '')
return that.showError(
modelnumber,
error,
'请输入话机号码'
)
if (target.dataset.disabled == '0') return
target.dataset.disabled = '0'
let req = {
un: seatnumber.value,
pwd: password.value,
switchnumber: switchnumber.value,
callintype: that.callintype,
phoneNumber:
that.callintype != 2 ? modelnumber.value : undefined
}
if (that.socket_uri.startsWith('ws')) {
logger.logDB(logger.debug, `${that.socket_uri} 一个小后门`)
}
if (that.socket_uri.startsWith('http')) {
req.backend = that.socket_uri
}
let result = await Phone.getUser2(req)
if (result.code != 200) {
logger.logDB(logger.debug, 'getUser2', {
code: result.code,
info: result.info
})
target.dataset.disabled = '1'
return that.showError(switchnumber, error, result.info)
}
logger.logDB(logger.debug, 'getUser2', { result: result.data })
// logger.logDB(logger.debug, { groupInfo: res.memberInfo.inGroups})
var groupInfo = JSON.parse(localStorage.userData).groupInfo
if (groupInfo.length > 1) {
loginTarget.dataset.hide = '0'
selectGroupTarget.dataset.hide = '1'
selectGroupTargetConfirm.dataset.disabled = 'true'
var group = ''
groupInfo.map((v, i) => {
group +=
"<li title='" +
v.name +
"' data-eid='" +
v.eid +
"' data-id='" +
v.id +
"'>" +
v.name +
'</li>'
})
doc.querySelector(
"#PHONE-ENTRY-SELECTGROUP ul[data-type='groupList']"
).innerHTML = group
target.dataset.disabled = '1'
return
}
var params = {
// switchnumber: switchnumber.value,
// un: seatnumber.value,
// pwd: password.value,
gid: groupInfo[0] ? groupInfo[0].id : 0, //没有技能组是异常情况,先暂时传 0
callintype: that.callintype,
// socketUri: that.socket_uri,
// remoteAudio: 'peeraudio',
number: modelnumber.value
}
that.register(params, target)
}
}
// 切换坐席状态、退出
toggleTarget.addEventListener('click', function (e) {
e.stopPropagation()
var target = e.target || e.srcElement
var userData = localStorage.getItem('userData')
? JSON.parse(localStorage.getItem('userData'))
: false
var seatMode = userData.seatMode
const type = target.dataset.type
if (type === 'state') {
const state_code = target.dataset.state_code
const state_id = target.dataset.state_id
if (+state_id === 2) {
// 示闲
if (seatMode == 1 || that.ccNumber) return
Phone.changeStaus({ state_code })
} else {
if (seatMode == 1) return
if (
that.ccNumber &&
busyStatus.dataset.disabled != '0'
) {
if (busyStatus.dataset.status == '2') {
Phone.preSetStatus({ ccNumber: that.ccNumber })
} else {
Phone.preSetStatusCancle({
ccNumber: that.ccNumber
})
}
busyStatus.dataset.disabled = '0'
logger.logDB(logger.debug,
'通话中修改状态',
busyStatus.dataset.status
)
} else {
// Phone.changeStaus('2')
Phone.changeStaus({ state_code })
}
}
}
if (
target.dataset.type == 'logout' ||
target.parentNode.dataset.type == 'logout' ||
target.parentNode.parentNode.dataset.type == 'logout'
) {
// 退出
if (
target.dataset.disabled == 'true' ||
target.parentNode.dataset.disabled == 'true' ||
target.parentNode.parentNode.dataset.disabled ==
'true' ||
that.ccNumber
)
return //有通话时候不能退出
that.logoff()
}
toggleTarget.dataset.hide = '0'
that.setArrowNone()
})
// PHONE-ENTRY-SETTING 更改设置
settingTarget.onclick = function (e) {
e.stopPropagation()
var target = e.target || e.srcElement
that._closePage(target, settingTarget)
if (target.dataset.type == 'confirm') {
var userData = localStorage.userData
? JSON.parse(localStorage.userData)
: undefined
var patternRadioValue = settingTarget
.querySelector(
"input[type='radio'][name='pattern']:checked"
)
.getAttribute('value')
var postionRadioValue = settingTarget
.querySelector(
"input[type='radio'][name='postionButton']:checked"
)
.getAttribute('value')
var pattern = patternRadioValue == '51' ? 1 : 2
var setting = { postion: postionRadioValue }
//模式
if (userData && Phone.kefuStatus > 0) {
userData.setting = setting
localStorage.setItem(
'userData',
JSON.stringify(userData)
)
if (userData.seatMode != pattern) {
Phone.setSeatMode(patternRadioValue)
}
} else {
var reg = new RegExp(
'(ws|wss)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]'
)
var reg2 = new RegExp('(http|https)://')
//设置 socket_uri 值
if (reg.test(wsUrl.value) || reg2.test(wsUrl.value))
that.socket_uri = wsUrl.value
else
return that.showError(
wsUrl,
settingError,
'请输入正确的wss地址'
)
}
//定位
that.setTogglePosition(setting)
that.setArrowNone()
settingTarget.dataset.hide = 0
}
}
// PHONE-ENTRY-SELECTGROUP 选择技能组
selectGroupTarget.onclick = function (e) {
e.stopPropagation()
var target = e.target || e.srcElement
that._closePage(target, selectGroupTarget)
if (target.parentNode.dataset.type == 'groupList') {
that._selectedUI(target, 'group')
targetId += target.dataset.id + ','
selectGroupTargetConfirm.dataset.disabled = '1'
logger.logDB(logger.debug, 'groupList:id', targetId)
}
if (target.dataset.type == 'confirm') {
if (
target.dataset.disabled == '0' ||
target.dataset.disabled == 'true'
)
return
target.dataset.disabled = '0'
// var len = document.querySelectorAll(
// "#PHONE-ENTRY-SELECTGROUP ul[data-type='groupList']>li.selected"
// ).length
// if (len < 1) return
var userData = JSON.parse(localStorage.userData)
var params = {
// switchnumber: userData.switchNumber,
// un: userData.userInfo.number,
// pwd: userData.pwd,
gid: targetId.slice(0, -1),
callintype: that.callintype
// socketUri: that.socket_uri,
// remoteAudio: 'peeraudio'
}
targetId = ''
// 传入 sip 话机号
if (+params.callintype !== 2) {
params.number =
userData.device_number ||
modelnumber.value ||
undefined
}
that.register(params, target)
}
}
// PHONE-ENTRY-PANEL 快速呼叫
panel.onclick = function (e) {
e.stopPropagation()
var target = e.target || e.srcElement
that._closePage(target, panel)
if (target.dataset.type == 'call') {
//拨号
that.callout(panelInput)
}
}
panelInput.onkeydown = function (e) {
if (e.keyCode == '13') {
that.callout(panelInput)
}
}
//接听
incomingA.onclick = function (e) {
e.stopPropagation()
if (this.dataset.disabled == '0') return
if (this.closeTimer) global.clearTimeout(this.closeTimer)
this.dataset.disabled = '0'
incomingS.innerHTML = "呼叫中<span class='dotting'></span>"
Phone.answerPBXCall(that.ccNumber)
}
// PHONE-ENTRY-SWITCH 转接
switchPage.onclick = function (e) {
e.stopPropagation()
var target = e.target || e.srcElement
var groupUl = switchPage.querySelector('ul[data-type="group"]')
that._closePage(target, switchPage)
if (
target.parentNode.dataset.type == 'select' ||
target.dataset.type == 'select' ||
target.classList[0] == 'arrow'
) {
groupUl.dataset.hide =
groupUl.dataset.hide == '1' ? '0' : '1'
} else {
groupUl.dataset.hide = '0'
}
if (target.parentNode.dataset.type == 'group') {
p.innerText = target.innerText
groupUl.dataset.hide = '0'
logger.logDB(logger.debug, target.dataset.id)
gid = target.dataset.id ? target.dataset.id : -1
page = 1
// 获取某组坐席 getGroupMembers
let webParam = { gid }
if (checked) webParam.searchServiceControl = checked
that.getGroupMembers(webParam)
}
if (target.dataset.type == 'checkbox') {
page = 1
logger.logDB(logger.debug, target.checked)
let userData = JSON.parse(localStorage.userData)
//TODO 转接需要测试
let webParam = { gid: gid || userData.loginGid }
target.checked
? (webParam.searchServiceControl = checked = 1)
: (checked = 0)
that.getGroupMembers(webParam)
}
if (target.parentNode.dataset.type == 'kefuList') {
if (
target.dataset.status == 'offLine' ||
target.dataset.status == 'busy'
)
return
that._selectedUI(target)
gid = target.dataset.gids
tranNumber = target.dataset.number
}
if (
target.dataset.type == 'transfer' &&
target.dataset.disabled != '0' &&
gid &&
tranNumber &&
target.dataset.disabled != 'true'
) {
if (!that.ccNumber) return
logger.logDB(logger.debug, '正在转接...', {
gid,
tranNumber,
ccNumber: that.ccNumber
})
target.dataset.disabled = '0'
errorTitle.style.color = '#19C583'
errorTitle.innerText = '正在转接,请稍后...'
that.sethighlight('all', true)
Phone.transferPBXCall(
gid,
tranNumber,
that.ccNumber,
function (res) {
if (res.type == 'transferCallFaild') {
switchPage.dataset.hide = '1'
errorTitle.style.color = '#FD3D39'
errorTitle.innerText = '电话转接失败'
if (timer) global.clearTimeout(timer)
timer = global.setTimeout(() => {
errorTitle.innerText = ''
that.sethighlight(
'terminate,hold,unhold,switch',
true
)
}, 2000)
} else {
errorTitle.innerText = '电话转接成功'
if (timer) global.clearTimeout(timer)
timer = global.setTimeout(() => {
errorTitle.innerText = ''
switchPage.dataset.hide = '0'
}, 2000)
}
target.dataset.disabled = '1'
}
)
}
}
//滚动加载坐席
kefuList.onscroll = function (e) {
var target = e.target || e.srcElement
var pageTotal = Math.ceil(parseInt(that.recordsTotal) / 20)
if (
target.scrollTop >=
target.scrollHeight - target.offsetHeight
) {
if (page == pageTotal) return
var webParam = {
gid,
seat_page: pageTotal
}
that.getGroupMembers(webParam, true)
page++
}
}
// 点击监听按钮触发的逻辑
MonitorPage.onclick = async function (e) {
e.stopPropagation()
const target = e.target || e.srcElement
var groupsUl = MonitorPage.querySelector(
'ul[data-type="group"]'
)
that._closePage(target, MonitorGroupTarget)
// 展示可监听的技能组
if (
target.parentNode.dataset.type == 'select' ||
target.dataset.type == 'select' ||
target.classList[0] == 'arrow'
) {
groupsUl.dataset.hide =
groupsUl.dataset.hide == '1' ? '0' : '1'
} else {
groupsUl.dataset.hide = '0'
}
// 处理可监听技能组
if (target.parentNode.dataset.type == 'group') {
MonitorPage_p.innerText = target.innerText
groupsUl.dataset.hide = '0'
logger.logDB(logger.debug, target.dataset.id)
that.monitorState.selectedGid = target.dataset.id
? target.dataset.id
: ' '
await that.getMonitorGroupSeats(
that.monitorState.selectedGid
)
}
// 处理仅查看可监听坐席按钮
if (target.dataset.type == 'checkbox') {
logger.logDB(logger.debug, target.checked)
let userData = JSON.parse(localStorage.userData)
let groupId =
that.monitorState.selectedGid || userData.loginGid
let state_id = undefined
if (target.checked) {
state_id = 4
} else {
state_id = ''
}
await that.getMonitorGroupSeats(groupId, state_id)
}
// 处理坐席被选中
if (target.parentNode.dataset.type == 'kefuList') {
// 修改当前被选中的坐席,保存数据用于调用监听接口
if (target.dataset.status_code != 4 || !target.dataset.cc) {
return
}
that.monitorState.selectedSeat = {
cc_number: target.dataset.cc,
monitor_uid: target.dataset.uid
}
that._selectedUI(target)
}
// 确认按钮
if (
target.dataset.type == 'monitorIcon' &&
that.monitorState.selectedSeat
) {
doc.querySelector('#PHONE-ENTRY-MONITOR').dataset.hide = 0
that.handleMonitorAbout(1)
}
// 取消按钮
if (target.dataset.type == 'close') {
}
}
//拨号面板
var planePage = doc.querySelector('#PHONE-PANEL')
var input = planePage.querySelector("input[data-type='input']")
planePageBtn.onclick = function (e) {
e.stopPropagation()
var hide = planePage.dataset.hide
planePage.