mirror of
https://git.hmsn.ink/kospo/helptalk/api.git
synced 2026-03-20 00:52:24 +09:00
201 lines
6.4 KiB
JavaScript
201 lines
6.4 KiB
JavaScript
import {talkEvent} from "http://talk.kospo.co.kr:3000/static/js/module/talkEvent.js";
|
|
import {global} from "http://talk.kospo.co.kr:3000/static/js/module/variable.js";
|
|
import Common from "http://talk.kospo.co.kr:3000/static/js/utils.js";
|
|
|
|
// 첨부파일 업로드 기능
|
|
|
|
function readFileAsDataURL(file) {
|
|
return new Promise((resolve, reject) => {
|
|
const reader = new FileReader();
|
|
reader.onload = (e) => resolve(e.target.result);
|
|
reader.onerror = reject;
|
|
reader.readAsDataURL(file);
|
|
});
|
|
}
|
|
|
|
function loadImage(src) {
|
|
return new Promise((resolve, reject) => {
|
|
const img = new Image();
|
|
img.onload = () => resolve(img);
|
|
img.onerror = reject;
|
|
img.src = src;
|
|
});
|
|
}
|
|
|
|
const attachUpload = async (files) => {
|
|
checkAllowExt()
|
|
const chunkSize = 256 * 1024;
|
|
const key = talkEvent.generateUUID()
|
|
|
|
const workId = localStorage.getItem('workId');
|
|
const workNm = localStorage.getItem('workNm');
|
|
const talkId = localStorage.getItem(global.tabId);
|
|
|
|
if(talkId === null || workId === null) {
|
|
global.notifier.alert('통신 오류가 발생 했어요.<br/>새로고침 해주세요.')
|
|
return
|
|
}
|
|
|
|
const $files = [];
|
|
const insDate = Common.dateWithNanos(new Date());
|
|
let allFileSize = 0;
|
|
let isImage = true;
|
|
|
|
// mimtype 조회 이미지가 아닌 다른 파일이 있는지 확인
|
|
Array.from(files).forEach((fi) => {
|
|
if (!(fi.type.includes('image'))) {
|
|
isImage = false;
|
|
}
|
|
})
|
|
|
|
for (const file of Array.from(files)) {
|
|
const idx = Array.from(files).indexOf(file);
|
|
allFileSize += file.size;
|
|
const att = {
|
|
onm: file.name,
|
|
type: file.type,
|
|
sort: idx,
|
|
size: file.size,
|
|
}
|
|
|
|
// 파일 전체가 이미지 일 경우 해당 바이너리 정보 주입
|
|
if (isImage) {
|
|
// 1. 파일을 읽어서 DataURL로 변환 (FileReader 비동기 처리)
|
|
const dataURL = await readFileAsDataURL(file);
|
|
// 2. 변환된 DataURL을 이용해 이미지 로드 (Image 비동기 처리)
|
|
const img = await loadImage(dataURL);
|
|
// 3. 썸네일 용 dataURL 생성
|
|
const blob = await Common.cropImage(img, 105);
|
|
att.data = blob;
|
|
}
|
|
|
|
$files.push(att);
|
|
|
|
}
|
|
/*
|
|
첨부파일 업로드 설정 소켓 통신으로 해당 파일의 정보를 보내준다.
|
|
정보를 받는 대상자는 첨부파일 업로드 화면을 렌더링 한다.
|
|
이미지 같은 경우는 위 바이너리 정보로 썸네일 구성
|
|
이미지외 파일 혼합된 경우 파일 다운로드 화면 구성
|
|
(서버에서는 해당 내용으로 메시지를 저장한다.)
|
|
*/
|
|
talkEvent.attach(global.talkParams({
|
|
type: 'INIT',
|
|
talkId: talkId,
|
|
workId: workId,
|
|
workNm: workNm,
|
|
message: isImage ? "[사진]" : '[파일]',
|
|
insDate: insDate,
|
|
talkAttachDtos: $files,
|
|
attach: {
|
|
key: key,
|
|
totalSize: allFileSize
|
|
}
|
|
}))
|
|
|
|
|
|
setTimeout(attachStart, 300)
|
|
|
|
function checkAllowExt() {
|
|
const allow = ["jpg", "jpeg", "gif", "png", "bmp",
|
|
"xls", "xlsx", "csv", "pdf", "hwp", "doc", "docx", "ppt", "pptx", "txt",
|
|
"zip", "egg",
|
|
"mp4"]
|
|
|
|
files = Array.from(files).filter((file) => {
|
|
const fileExt = file.name.toLowerCase().substr(file.name.toLowerCase().lastIndexOf('.') + 1)
|
|
return allow.join(',').includes(fileExt)
|
|
})
|
|
}
|
|
|
|
function attachStart() {
|
|
if (files.length !== 0) {
|
|
Array.from(files).forEach((file, idx) => {
|
|
const vnm = Common.getAttachVnm(new Date(), global.tabId)
|
|
console.log(idx, vnm)
|
|
let offset = 0;
|
|
/*
|
|
각파일 정보를 전송
|
|
(서버에서는 메시지 첨부파일을 저장한다.)
|
|
*/
|
|
talkEvent.attach(global.talkParams({
|
|
type: 'START',
|
|
talkId: talkId,
|
|
workId: workId,
|
|
workNm: workNm,
|
|
insDate: insDate,
|
|
attach: {
|
|
key: key,
|
|
onm: file.name,
|
|
vnm: vnm,
|
|
size: file.size,
|
|
type: file.type,
|
|
sort: idx,
|
|
totalSize: allFileSize
|
|
|
|
}
|
|
}))
|
|
readAndSEndChunk(file, idx, offset, vnm)
|
|
})
|
|
}
|
|
|
|
}
|
|
|
|
let progressSize = 0;
|
|
|
|
function readAndSEndChunk(file, idx, offset, vnm) {
|
|
const reader = new FileReader();
|
|
reader.onload = (e) => {
|
|
const chunk = reader.result;
|
|
/*
|
|
파일의 바이너리 정보를 chunkSize 256kb 로 잘라서 전송한다.
|
|
받는 대상자는 해당 첨부파일의 진행률을 돌려받는다.
|
|
*/
|
|
talkEvent.attach(global.talkParams({
|
|
type: 'PROGRESS',
|
|
talkId: talkId,
|
|
workId: workId,
|
|
workNm: workNm,
|
|
insDate: insDate,
|
|
attach: {
|
|
key: key,
|
|
onm: file.name,
|
|
sort: idx,
|
|
vnm: vnm,
|
|
totalSize: allFileSize,
|
|
size: progressSize,
|
|
data: Array.from(new Uint8Array(chunk))
|
|
},
|
|
}))
|
|
|
|
progressSize += chunk.byteLength;
|
|
offset += chunk.byteLength;
|
|
if (offset < file.size) {
|
|
Common.sleep(100).then(() => {
|
|
readAndSEndChunk(file, idx, offset, vnm)
|
|
})
|
|
} else {
|
|
/*
|
|
파일 전송 완료 메시지
|
|
*/
|
|
talkEvent.attach(global.talkParams({
|
|
type: 'END',
|
|
talkId: talkId,
|
|
workId: workId,
|
|
workNm: workNm,
|
|
insDate: insDate,
|
|
attach: {
|
|
onm: file.name,
|
|
vnm: vnm,
|
|
key: key,
|
|
},
|
|
}))
|
|
}
|
|
}
|
|
|
|
const slice = file.slice(offset, offset + chunkSize);
|
|
reader.readAsArrayBuffer(slice)
|
|
}
|
|
}
|
|
|
|
export {attachUpload} |