功能优化-发送文件之前二次确认

This commit is contained in:
unknown
2022-05-23 16:33:14 +08:00
parent 93105830e0
commit c378339e20
9 changed files with 297 additions and 132 deletions

View File

@ -5,15 +5,14 @@ import React, {
} from 'react'
import PropTypes from 'prop-types';
import style from './style.module.css'
//import {doEncrypt} from '@/utils/utils'
import ChatToolBar from '../ChatToolsBar/ChatToolBar'
import { mouseOverHandle, mouseMoveHandle, mouseDrag, utf16toEntities, closeHTML, imageHandleUtil, doEncrypt} from '../../utils/utils'
import { mouseOverHandle, mouseMoveHandle, mouseDrag, utf16toEntities, isEmojiCharacter,closeHTML, imageHandleUtil, doEncrypt, parseBase64ToBlob} from '../../utils/utils'
import { customerserviceAPI as API} from '@/services/customerservice';
import { Spin, Modal, message } from 'antd';
import { Spin, Modal, message, Tooltip } from 'antd';
import { useLocation } from 'react-router-dom'
//import {docUp} from '@config/host'
import lodash from 'lodash';
import moment from "moment";
import { cns } from '../../utils/toClass'
const ChatInput = ((props) => {
const {
@ -96,11 +95,17 @@ const ChatInput = ((props) => {
for(var i=0; i<allElements.length;i++){
let el = allElements[i]
if(el.tagName!="IMG"){
if(!el.hasAttribute('emoji')){
// if(el.tagName=="SPAN"){
// if(isEmojiCharacter(el.innerHTML)){
// el.style.fontSize='26px'
// }else{
// el.removeAttribute('style')
// el.style.fontSize='15px'
// }
// }else{
// el.removeAttribute('style')
// }
el.removeAttribute('style')
}else if(el.getAttribute('emoji')!='emoji'){
el.removeAttribute('style')
}
el.removeAttribute('className')
el.removeAttribute('class')
}
@ -137,7 +142,7 @@ const ChatInput = ((props) => {
}else{
judge_div.innerHTML = text
if(judge_div.innerText.trim()!=''){
msgArr.push({type:'text',content:text})
msgArr.push({type:'text',content:closeHTML(text)})
}
setLoading(false)
const isAllowSend = msgArr && msgArr.length>0
@ -340,7 +345,6 @@ const keyUpHandle = (e) => {
seIsCtrl(false)
}
}
const mouseUpHandle = () => {
window.getSelection().rangeCount>0 && setCachedRange(window.getSelection().getRangeAt(0))
}
@ -379,15 +383,36 @@ const str_substr = (start, end, str)=> {
var el = document.createElement('span')
el.innerHTML=txt
var allImgs = el.getElementsByTagName('img')
// var allElements = docuemnt.getElementsByTagName('*')
// //输入框内容去除样式
// if(allElements && allElements.length>0){
// for(var i=0; i<allElements.length;i++){
// let el = allElements[i]
// console.log(el)
// if(el.tagName!="IMG"){
// if(el.tagName=="SPAN"){
// if(isEmojiCharacter(el.innerHTML)){
// el.style.fontSize='20px'
// }else{
// el.removeAttribute('style')
// el.style.fontSize='13px'
// }
// }
// el.removeAttribute('className')
// el.removeAttribute('class')
// }
// }
// }
var allImgs = el.getElementsByTagName('img')
if(allImgs && allImgs.length>0){
window.getSelection().deleteFromDocument() //如果有选中内容,粘贴时替换
let range = cachedRange
if(!cachedRange && innerRef.current){
innerRef.current.focus()
range = window.getSelection().getRangeAt(0)
}
let range = window.getSelection().getRangeAt(0)
// if(!cachedRange && innerRef.current){
// innerRef.current.focus()
// range = window.getSelection().getRangeAt(0)
// }
if(range) {
let params={srcArr:allImgs, sig:0, el, range, reformMsg, showPic, resetCachedRange, resetLoadling, imgInputSize, imgMsgSize, imgPreviewSize}
imageHandleUtil.pasteImages(params)
@ -406,13 +431,13 @@ const str_substr = (start, end, str)=> {
}
}
if( item && item.kind === 'file' && item.type.match(/^image\//i) ){
//imgReader(item.getAsFile());
window.getSelection().deleteFromDocument() //如果有选中内容粘贴时替换
let range = cachedRange
if(!cachedRange && innerRef.current){
innerRef.current.focus()
range = window.getSelection().getRangeAt(0)
}
// let range = cachedRange
// if(!cachedRange && innerRef.current){
// innerRef.current.focus()
// range = window.getSelection().getRangeAt(0)
// }
let range = window.getSelection().getRangeAt(0)
if(range) {
let params={image:item.getAsFile(), range, reformMsg, showPic, resetCachedRange, resetLoadling, imgInputSize, imgMsgSize, imgPreviewSize}
imageHandleUtil.insertImageHandle(params)
@ -428,19 +453,12 @@ const str_substr = (start, end, str)=> {
innerRef.current.focus()
range = window.getSelection().getRangeAt(0)
}
if (range && innerRef.current) {
var wrapped_obj = document.createElement('span')
if (range) {
var obj = document.createElement('span')
var obj2 = document.createElement('span')
obj.setAttribute('emoji','emoji')
obj.setAttribute('contentEditable',false)
obj.style.fontSize="20px"
// obj.style.fontSize="26px"
obj.innerHTML=emoji
wrapped_obj.appendChild(obj)
wrapped_obj.appendChild(obj2)
range.insertNode(wrapped_obj)
range.insertNode(obj)
setCachedRange(range)
range.collapse(false)
window.getSelection().removeAllRanges();
@ -468,6 +486,31 @@ const str_substr = (start, end, str)=> {
imageHandleUtil.insertImageHandle(params)
}
}
//打开本地已上传文件
const openLocalUploadFile = ()=>{
let file = uploadFile
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onloadend = function (e) {
const element = document.createElement("a");
element.target='_blank'
const content = e.target.result
if(content.indexOf('base64')!=-1){
const type = uploadFile.type
var arr = content.split(',') //分割为数组,分割到第一个逗号
let mime = arr[0].match(/:(.*?);/)[1] //获取分割后的base64前缀中的类型
let myBlob = parseBase64ToBlob(arr[1], mime);
element.href = URL.createObjectURL(myBlob);
if(type.indexOf('text/plain')==-1 && type.indexOf('image')==-1){
element.download = uploadFile.name;
}
document.body.appendChild(element); // Required for this to work in FireFox
element.click();
document.body.removeChild(element);
window.URL.revokeObjectURL(myBlob); //释放掉blob对象
}
};
}
//文件发送
const sendFile = ()=>{
let file = uploadFile
@ -563,7 +606,15 @@ const str_substr = (start, end, str)=> {
</div>
{isSendFile &&
<Modal title="提醒" getContainer={false} visible={isSendFile} onOk={()=>{setIsSendFile(false);sendFile()}} onCancel={()=>setIsSendFile(false)} >
<p>您确定要上传文件么确定文件将无法撤回!</p>
<Tooltip title='点击查看文件' placement='topRight'>
<div onDragOver={(e)=>{e.preventDefault()}} onClick={openLocalUploadFile} className={style.customer_service_uploadfile}>
<span className={cns([style.customer_service_filename, style.customer_service_ellipsis])}>{uploadFile.name}</span>
<span className={style.customer_service_filesize}>{uploadFile.size / 1024>=1024?(uploadFile.size / 1024/1024).toFixed(1)+"M":(uploadFile.size / 1024).toFixed(1)+"K"}</span>
<span className={style.customer_service_uploadicon}></span>
</div>
</Tooltip>
<br/>
<p style={{color:'red'}}>您确定要上传文件么确定文件将无法撤回!</p>
</Modal>
}
</Spin>

View File

@ -15,11 +15,14 @@
outline: none;
padding: 10px;
margin-right: 10px;
font-size: 13px;
line-height: 13px;
font-size: 16px;
line-height: 16px;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
letter-spacing: 2px;
}
.customer_service_content .input_area .emoji{
font-size: 20px;
}
.customer_service_content .input_area::placeholder {
color: #999;
}
@ -53,3 +56,50 @@
box-sizing: border-box;
background-color: white
}
.customer_service_uploadfile{
border: 1px solid #CCC;
background-color: white;
width: 200px;
height: 120px;
position: relative;
-display: flex;
-flex-direction: column;
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Chrome/Safari/Opera */
-khtml-user-select: none; /* Konqueror */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; /* Non-prefixed version, currently
not supported by any browser */
}
.customer_service_uploadfile:hover{
cursor: pointer;
}
.customer_service_filename {
height: 45px;
margin-left: 10px;
margin-top: 5px;
}
.customer_service_filesize {
margin-left: 10px;
margin-top: 5px;
color: rgb(153,153,153);
}
.customer_service_ellipsis {
max-width: 150px;
overflow: hidden;
text-overflow: ellipsis;
display:-webkit-box;
-webkit-box-orient:vertical;
-webkit-line-clamp:2;
-white-space: nowrap;
}
.customer_service_uploadicon{
float: right;
margin-top: 15px;
margin-right: 10px;
width: 40px;
height: 40px;
background-image: url('../../image/uploadFile.png');
background-size: cover;
}

View File

@ -3,23 +3,107 @@ import PropTypes from 'prop-types'
import style from './style.module.css'
import { cns } from '../../utils/toClass'
// const emojiList = [
// '😀',
// '😃',
// '😄',
// '😁',
// '😆',
// '😅',
// '😂',
// '🤣',
// '😊',
// '😇',
// '🙂',
// '🙃',
// '😉',
// '😌',
// '😍',
// '🥰',
// '😘',
// '😗',
// '😙',
// '😚',
// '😋',
// '😛',
// '😝',
// '😜',
// '🤪',
// '🤨',
// '🧐',
// '🤓',
// '😎',
// '🤩',
// '🥳',
// '😏',
// '😒',
// '😞',
// '😔',
// '😟',
// '😕',
// '🙁',
// '😣',
// '😖',
// '😫',
// '😩',
// '🥺',
// '😢',
// '😭',
// '😤',
// '😠',
// '😡',
// '🤬',
// '🤯',
// '😳',
// '🥵',
// '🥶',
// '😱',
// '😨',
// '😰',
// '😥',
// '😓',
// '🤗',
// '🤔',
// '🤭',
// '🤫',
// '🤥',
// '😶',
// '😐',
// '😑',
// '😬',
// '🙄',
// '😯',
// '😦',
// '😧',
// '😮',
// '😲',
// '🥱',
// '😴',
// '🤤',
// '😪',
// '😵',
// '🤐',
// '🥴',
// '🤢',
// '🤮',
// '🤧',
// '😷',
// '🤒',
// '🤕',
// ]
const emojiList = [
'😀',
'😃',
'😄',
'😁',
'😆',
'😅',
'😂',
'🤣',
'😊',
'😇',
'🙂',
'🙃',
'😉',
'😌',
'😍',
'🥰',
'😘',
'😗',
'😙',
@ -28,70 +112,15 @@ const emojiList = [
'😛',
'😝',
'😜',
'🤪',
'🤨',
'🧐',
'🤓',
'😎',
'🤩',
'🥳',
'😏',
'😒',
'😞',
'😔',
'😟',
'😕',
'🙁',
'😣',
'😖',
'😫',
'😩',
'🥺',
'😢',
'😭',
'😤',
'😠',
'😡',
'🤬',
'🤯',
'😳',
'🥵',
'🥶',
'😱',
'😨',
'😰',
'😥',
'😓',
'🤗',
'🤔',
'🤭',
'🤫',
'🤥',
'😶',
'😐',
'😑',
'😬',
'🙄',
'😯',
'😦',
'😧',
'😮',
'😲',
'🥱',
'😴',
'🤤',
'😪',
'😵',
'🤐',
'🥴',
'🤢',
'🤮',
'🤧',
'😷',
'🤒',
'🤕',
]
]
export default function EmojiPopover(props) {
const {onSelect} = props
const [visible, setVisible] = useState(false)

View File

@ -30,7 +30,7 @@
left: -14.5px;
}
.customer_service_content .emoji_item {
font-size: 20px;
font-size: 22px;
box-sizing: border-box;
padding: 0px 7px 0px 3px;
}

View File

@ -1,29 +1,27 @@
import React, {useRef } from 'react'
import React, {useRef, useState } from 'react'
import PropTypes from 'prop-types'
import style from './style.module.css'
import { message, } from 'antd';
import { message, Modal, Tooltip} from 'antd';
export default function FilePopover(props) {
const { onFile } = props
const fileSelector = useRef()
const isUpload = (file) => {
/*
let name = file.name;
let type;
if (name.lastIndexOf(".") > 0) {
type = name
.substr(name.lastIndexOf(".") + 1, name.length)
.toLocaleLowerCase();
}
let isType = ["pdf", "png", "jpg", "jpeg"].indexOf(type) === -1;
if (isType) {
message.error("上传格式错误");
}*/
// /*
// let name = file.name;
// let type;
// if (name.lastIndexOf(".") > 0) {
// type = name
// .substr(name.lastIndexOf(".") + 1, name.length)
// .toLocaleLowerCase();
// }
// let isType = ["pdf", "png", "jpg", "jpeg"].indexOf(type) === -1;
// if (isType) {
// message.error("上传格式错误");
// }*/
const isType = false
const isLt50M = file.size / 1024 / 1024 < 50;
const isLt50M = file.size / 1024 / 1024 < 20;
if (!isLt50M) {
message.error("文件大小不能超过50MB");
message.error("文件大小不能超过20MB");
}
const bool = !isType && isLt50M;
return bool
@ -46,17 +44,18 @@ export default function FilePopover(props) {
const fileHandle = (event) => {
const files = event.target.files
//console.log(files[0])
if(files && files[0] && (files[0].type.indexOf('application/')!=-1 || files[0].type.indexOf('text/plain')!=-1 )){
// if(files && files[0] && (files[0].type.indexOf('application/')!=-1 || files[0].type.indexOf('text/plain')!=-1 )){
// beforeUpload(files[0])
// }else{
// message.error('上传文件格式不支持')
// }
beforeUpload(files[0])
}else{
message.error('上传文件格式不支持')
}
}
return (
<div className={style.customer_service_content} onClick={selectImg}>
<input
type="file"
accept="application/*,text/plain"
//accept="application/*,text/plain"
ref={fileSelector}
onChange={fileHandle}
/>

View File

@ -35,6 +35,7 @@ export default function MsgBubble(props) {
document.body.appendChild(element); // Required for this to work in FireFox
element.click();
document.body.removeChild(element);
window.URL.revokeObjectURL(myBlob); //释放掉blob对象
}else{
if(data.content.fileId!=''){
onDownload(data.content.fileId)

View File

@ -15,7 +15,7 @@
max-width: 100%;
word-wrap: break-word;
word-break: break-all;
font-size: 13px;
font-size: 15px;
font-family:sans-serif;
letter-spacing: 2px;
}

View File

@ -85,7 +85,7 @@ const conversation = (props) => {
user: {
id: data.serverNo,
avatar: serverAvatar,
name: '供应链客服',
name: data.serverName? data.serverName: '供应链客服',
},
message: { type: type, content: content },
}

View File

@ -283,7 +283,9 @@ export function parseBase64ToBlob (data, fileType) {
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new Blob([u8arr], { type: fileType })
if(fileType=='text/plain')
return new Blob(['\ufeff', u8arr], { type: fileType })
else return new Blob([u8arr], { type: fileType })
}
// 表情解码
export function entitiestoUtf16 (strObj) {
@ -330,6 +332,39 @@ str = str.replace(patt, (char) => {
return str;
}
export function isEmojiCharacter(substring) {
for ( var i = 0; i < substring.length; i++) {
var hs = substring.charCodeAt(i);
if (0xd800 <= hs && hs <= 0xdbff) {
if (substring.length > 1) {
var ls = substring.charCodeAt(i + 1);
var uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
if (0x1d000 <= uc && uc <= 0x1f77f) {
return true;
}
}
} else if (substring.length > 1) {
var ls = substring.charCodeAt(i + 1);
if (ls == 0x20e3) {
return true;
}
} else {
if (0x2100 <= hs && hs <= 0x27ff) {
return true;
} else if (0x2B05 <= hs && hs <= 0x2b07) {
return true;
} else if (0x2934 <= hs && hs <= 0x2935) {
return true;
} else if (0x3297 <= hs && hs <= 0x3299) {
return true;
} else if (hs == 0xa9 || hs == 0xae || hs == 0x303d || hs == 0x3030
|| hs == 0x2b55 || hs == 0x2b1c || hs == 0x2b1b
|| hs == 0x2b50) {
return true;
}
}
}
}
//补齐html标签
export function closeHTML(str){
var arrTags=["span","font","b","u","i","h1","h2","h3","h4","h5","h6","p","li","ul","table","div"];