MetaHub program
[ SI 프로젝트 ] 콜센터 실시간대응 프로그램
Description
- IPCC 실시간 대용량서버통신 개선 위해 코드퀄리티 UP
- 상담사/관리자 권한 및 웹/모바일 환경에 따른 라우터 화면 이동방식 구현
#1. 모바일 로그인 / 권한관리
Code
/** 로그인 처리 **/
const _loginHandler = async () => {
const userId = <string>username.value
const userPs = <string>password.value
try {
const tmp = userId.split('@');
if (tmp.length < 2 || tmp[1] === "") {
await modalStore.show('Alert','프로젝트 코드를 입력해주세요.<br/>예) 사용자ID@프로젝트코드')
return
}
// 로그인 요청
const res = await authStore.login(userId, userPs, useSoft.value)
const result = res.code
if (result === 'OK') {
// 로그인 성공
if (useSoft.value) {
const connected = await softphoneStore.open()
if (connected) {
softphoneStore.emit('login', {
userid: userId.split('@')[0],
mode: 'Outbound',
})
} else {
await modalStore.show('Alert','연결에 실패하였습니다.<br/>잠시 후 다시 시도해주세요.',)
}
} else {
await _loginCallback()
}
} else if (result === 'PWD_LOCK') {
// 비밀번호 5회 불일치 잠금
await modalStore.show('Alert',`비밀번호 입력 오류로 인해<br/><span style="color: red;">로그인이 5회 실패하였습니다.</span><br/>회원님의 정보 보호를 위해<br/>5분간 접속 차단이 됩니다.`,)
} else if (result === 'NOTFOUND') {
// 계정 없음
await modalStore.show('Alert', '계정을 찾을 수 없습니다.')
} else if (result === 'DUPLICATE') {
// 중복 로그인
await modalStore.show('Alert', '중복로그인 입니다.')
} else if (result === 'WRONG') {
// 비밀번호 불일치
const checkData = res.data.value.split('_')
const count = checkData[0]
const total = checkData[1]
await modalStore.show('Alert', `비밀번호가 일치하지 않습니다.<br/><span style="color: red;">로그인이 ${count}회 실패하였습니다.</span><br/>비밀번호 ${total}회 오류시 5분간 접속이 차단됩니다`)
} else if (result === 'PWDCHG') {
// 비밀번호 변경 90일 경과
popupTitleMessage.value = '비밀번호 변경 안내'
await modalStore.show('Alert',`비밀번호 변경 후 <span style="color:red">90일이 경과</span>하였습니다.<br>비밀번호를 변경하세요.`)
_showChangePw(true)
} else if (result === 'PWDINIT') {
// 초기 비밀번호 popup
popupTitleMessage.value = '초기 비밀번호 변경'
_showChangePw(true)
} else {
await modalStore.show('Alert', '처리 중 오류가 발생하였습니다.')
}
} catch (error) {
await modalStore.show('Alert', '처리 중 오류가 발생하였습니다.')
return error
}
}
#2. 실시간 대시보드/ 사이트별 통계
Code
/** @function 대시보드데이터조회 */
const _srchDashBoard = async () => {
//조회기준: 현재날짜-현재날짜
const cdate = stringUtil.formatDateStr(params.value.cdate)
//실시간모니터링(대시보드) 조회
const dashRslt = await dashBoardStore.getRealTime(cdate)
if(dashRslt.code === 'OK'){
totData.value = {...dashRslt.data}
}
//미처리건수조회
const alrtRslt1 = await dashBoardStore.getAlertList('00', cdate) //미열람개수 알림리스트
if(alrtRslt1.code === 'OK'){
totData.value.unPrcsCnt = alrtRslt1.list.length //미처리건수
}
_setData(totData.value)
}
#3. 업무이관/상세조회/처리하기
Code
/** @function 상세조회 */
const _onSelected = async (array: any) => {
detail.value.siteCd = array.siteCd
detail.value.trId = array.trId
//업무이관상세조회(A_TRANS_002)
const rslt = await transStore.info(params.value.projCd, detail.value.siteCd, detail.value.trId)
if(rslt === null) return
detail.value = rslt.info
historyReq.value = _.cloneDeep(rslt.info) //처리이력
detail.value.phone = stringUtil.formatPhone(detail.value.phone)
prcsInfo.value.length = rslt.processInfo.length
rslt.processInfo.forEach((r:any, i:number)=> {
prcsInfo.value[rslt.processInfo.length-1-i] = r //순서 오름차순 정렬
})
await _getAuthUser('res', rslt.info.resTeamCd) // 처리정보 담당팀에 따른 담당자 목록 바인딩
files.value = rslt.fileInfo //파일정보(SavesAll)
fileInfo.value = files.value //파일정보(Ref)
//파일업로드 용량 카운트
for (const file of fileInfo.value) {
file.size = parseInt(file.fileSize)
fileSizes.value += file.size || 0
}
_setMaskYn(detail)
if(detail.value.trGb){
//공통코드조회(A_CMMNCD_003)
const rslt2 = await codeStore.fetchCodesList(detail.value.trGb, '') //이관구분
if (rslt2.code === 'OK') {
cmCdDTrType.value = rslt2.list
}
}
//티켓정보조회(A_TICKET_004)
if(!!detail.value.callSeq){
ticketInfoYn.value = true
const rslt3 = await ticketStore.fetchTicketHistory({
gb: '01',
projCd: detail.value.projCd,
siteCd: detail.value.siteCd,
callSeq: detail.value.callSeq,
custId: detail.value.custId,
sdate: params.value.sdateStr,
edate: params.value.edateStr,
})
}
_getCounsArr(detail.value.siteCd) //티켓유형조회
_init()
//라우터이동박식으로 직접접근시 params_detail={}조작을 방지, 접근제한 체크(처리자=본인)
noAuthAccess.value = userStore.user.userId !== array.resUserId
}
#4. 설문조사 - 카카오인앱연동
Code
/** 단답형질문에 대한 선택지 선택 */
const fnSelect = (item: any, index: number, aIndex?:number) => {
//해당질문이 하위섹션유형이 아니고 && 객관식단답형이면
if (item.sectionYn == 'N' && item.answType == '01' && aIndex !== undefined){
// 1. 이전에 답변 체크한 값에 따른 하위섹션이 있었는지 체크 (추가된 목록 제거)
const { aNo } = item
if (aNo != 0 && item.list[aNo-1].sectionValue != ''){
const findSubQue = mainQuests.value.find((x:any) => x.qNo === item.list[aNo-1].sectionValue )
if (findSubQue) {
mainQuests.value.splice(index, 1)
--page.value
}
}
// 2. 선택한 해당답변이 연결된 하위섹션이동이 있으면 추가
if(item.list[aIndex].sectionValue != ''){
const findSubQue = subQuests.value.find((x:any) => x.qNo === item.list[aIndex].sectionValue )
if (findSubQue) {
//순차적 다음질문 이전에 하위섹션먼저 추가
mainQuests.value.splice(index, 0, findSubQue)
++page.value
}
}
}
//다음 문항으로
fnNext(index)
}
/** 설문종료 */
const closeSubmit = () => {
if(isMobile()){
const userAgent = window.navigator.userAgent.toLocaleLowerCase()
// kakaoTalk 인앱 브라우저에서 설문조사 띄웠을경우
if (userAgent.indexOf("kakaotalk") > -1) {
// IOS vs Android 에 따른 종료 명령
window.location.href = (/iPad|iPhone|iPod/.test(userAgent)) ? "kakaoweb://closeBrowser" : "kakaotalk://inappbrowser/close";
}
} else {
// 웹에서 띄웠을 경우
window.open("about:blank","_self")?.close()
}
}