mirror of
https://git.hmsn.ink/kospo/helptalk/api.git
synced 2026-03-20 07:43:33 +09:00
first
This commit is contained in:
201
sample/dev/talk/js/module/attach.js
Normal file
201
sample/dev/talk/js/module/attach.js
Normal file
@@ -0,0 +1,201 @@
|
||||
import {talkEvent} from "http://devtalk.kospo.co.kr:3000/static/js/module/talkEvent.js";
|
||||
import {global} from "http://devtalk.kospo.co.kr:3000/static/js/module/variable.js";
|
||||
import Common from "http://devtalk.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}
|
||||
Reference in New Issue
Block a user