1
0
mirror of https://github.com/chatopera/cosin.git synced 2025-08-01 16:38:02 +08:00

Fixed #106 支持文件上传

This commit is contained in:
Hai Liang Wang 2018-10-22 17:21:26 +08:00
parent b914c0d5b8
commit a0dbd1ea14
9 changed files with 1316 additions and 1260 deletions

View File

@ -15,5 +15,6 @@ PACKAGE_VERSION=1.0.0
[ -z "${BASH_SOURCE[0]}" -o "${BASH_SOURCE[0]}" = "$0" ] || return
cd $appHome
set -x
docker build --force-rm=true --tag $imagename:$PACKAGE_VERSION .
docker tag $imagename:$PACKAGE_VERSION $imagename:develop

View File

@ -877,7 +877,7 @@ public class MainUtils {
}
attachmentFile.setFileid(fileid);
attachementRes.save(attachmentFile);
FileUtils.writeByteArrayToFile(new File(path, "app/workorders/" + fileid), file.getBytes());
FileUtils.writeByteArrayToFile(new File(path, "upload/" + fileid), file.getBytes());
}
}
}

View File

@ -788,7 +788,7 @@ public class IMController extends Handler {
}
attachmentFile.setFileid(fileid);
attachementRes.save(attachmentFile);
FileUtils.writeByteArrayToFile(new File(path, "app/app/" + fileid), file.getBytes());
FileUtils.writeByteArrayToFile(new File(path, "upload/" + fileid), file.getBytes());
id = attachmentFile.getId();
}
}

View File

@ -47,131 +47,132 @@ import com.chatopera.cc.app.model.UploadStatus;
@Controller
@RequestMapping("/res")
public class MediaController extends Handler{
@Value("${web.upload-path}")
public class MediaController extends Handler {
@Value("${web.upload-path}")
private String path;
private String TEMPLATE_DATA_PATH = "WEB-INF/data/templates/";
@Autowired
private AttachmentRepository attachementRes;
private String TEMPLATE_DATA_PATH = "WEB-INF/data/templates/";
@Autowired
private AttachmentRepository attachementRes;
@RequestMapping("/image")
@Menu(type = "resouce" , subtype = "image" , access = true)
@Menu(type = "resouce", subtype = "image", access = true)
public void index(HttpServletResponse response, @Valid String id) throws IOException {
File file = new File(path ,id) ;
if(!StringUtils.isBlank(id) && !(id.endsWith(".png") || id.endsWith(".jpg"))){
if(id.endsWith("_original") && !file.exists()){
File orgFile = new File(path , id.substring(0 , id.indexOf("_original"))) ;
if(orgFile.exists()){
MainUtils.processImage(file = new File(path , id), orgFile) ;
}
}else if(!StringUtils.isBlank(id) && file.exists() && !id.endsWith("_original")){
File originalFile = new File( path , id+"_original") ;
if(!originalFile.exists()){
MainUtils.processImage(new File( path , id+"_original"), file) ;
}
}else if(!StringUtils.isBlank(id) && !file.exists() && !id.endsWith("_original")){
File destFile = new File(path , id+"_original") ;
if(destFile.exists()){
MainUtils.processImage(new File(path + id), destFile) ;
}
file = new File(path , id) ;
}
}
if(file.exists() && file.isFile()){
response.setHeader("Content-Type","image/png");
response.setContentType("image/png");
response.getOutputStream().write(FileUtils.readFileToByteArray(new File(path ,id)));
}
File file = new File(path, id);
if (!StringUtils.isBlank(id) && !(id.endsWith(".png") || id.endsWith(".jpg"))) {
if (id.endsWith("_original") && !file.exists()) {
File orgFile = new File(path, id.substring(0, id.indexOf("_original")));
if (orgFile.exists()) {
MainUtils.processImage(file = new File(path, id), orgFile);
}
} else if (!StringUtils.isBlank(id) && file.exists() && !id.endsWith("_original")) {
File originalFile = new File(path, id + "_original");
if (!originalFile.exists()) {
MainUtils.processImage(new File(path, id + "_original"), file);
}
} else if (!StringUtils.isBlank(id) && !file.exists() && !id.endsWith("_original")) {
File destFile = new File(path, id + "_original");
if (destFile.exists()) {
MainUtils.processImage(new File(path + id), destFile);
}
file = new File(path, id);
}
}
if (file.exists() && file.isFile()) {
response.setHeader("Content-Type", "image/png");
response.setContentType("image/png");
response.getOutputStream().write(FileUtils.readFileToByteArray(new File(path, id)));
}
}
@RequestMapping("/voice")
@Menu(type = "resouce" , subtype = "voice" , access = true)
@Menu(type = "resouce", subtype = "voice", access = true)
public void voice(HttpServletResponse response, @Valid String id) throws IOException {
File file = new File(path ,id) ;
if(file.exists() && file.isFile()){
response.getOutputStream().write(FileUtils.readFileToByteArray(new File(path ,id)));
}
File file = new File(path, id);
if (file.exists() && file.isFile()) {
response.getOutputStream().write(FileUtils.readFileToByteArray(new File(path, id)));
}
}
@RequestMapping("/url")
@Menu(type = "resouce" , subtype = "image" , access = true)
@Menu(type = "resouce", subtype = "image", access = true)
public void url(HttpServletResponse response, @Valid String url) throws IOException {
byte[] data = new byte[1024] ;
int length = 0 ;
OutputStream out = response.getOutputStream();
if(!StringUtils.isBlank(url)){
InputStream input = new URL(url).openStream() ;
while((length = input.read(data) )> 0){
out.write(data, 0, length);
}
input.close();
}
byte[] data = new byte[1024];
int length = 0;
OutputStream out = response.getOutputStream();
if (!StringUtils.isBlank(url)) {
InputStream input = new URL(url).openStream();
while ((length = input.read(data)) > 0) {
out.write(data, 0, length);
}
input.close();
}
}
@RequestMapping("/image/upload")
@Menu(type = "resouce" , subtype = "imageupload" , access = false)
public ModelAndView upload(ModelMap map,HttpServletRequest request , @RequestParam(value = "imgFile", required = false) MultipartFile imgFile) throws IOException {
ModelAndView view = request(super.createRequestPageTempletResponse("/public/upload")) ;
UploadStatus upload = null ;
String fileName = null ;
if(imgFile!=null && imgFile.getOriginalFilename().lastIndexOf(".") > 0){
File uploadDir = new File(path , "upload");
if(!uploadDir.exists()){
uploadDir.mkdirs() ;
}
fileName = "upload/"+ MainUtils.md5(imgFile.getBytes())+imgFile.getOriginalFilename().substring(imgFile.getOriginalFilename().lastIndexOf(".")).toLowerCase() ;
FileCopyUtils.copy(imgFile.getBytes(), new File(path , fileName));
String fileURL = request.getScheme()+"://"+request.getServerName()+"/res/image.html?id="+fileName ;
if(request.getServerPort() == 80){
fileURL = request.getScheme()+"://"+request.getServerName()+"/res/image.html?id="+fileName;
}else{
fileURL = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+"/res/image.html?id="+fileName;
}
upload = new UploadStatus("0" , fileURL); //图片直接发送给 客户不用返回
}else{
upload = new UploadStatus("请选择图片文件");
}
map.addAttribute("upload", upload) ;
return view ;
@Menu(type = "resouce", subtype = "imageupload", access = false)
public ModelAndView upload(ModelMap map, HttpServletRequest request, @RequestParam(value = "imgFile", required = false) MultipartFile imgFile) throws IOException {
ModelAndView view = request(super.createRequestPageTempletResponse("/public/upload"));
UploadStatus upload = null;
String fileName = null;
if (imgFile != null && imgFile.getOriginalFilename().lastIndexOf(".") > 0) {
File uploadDir = new File(path, "upload");
if (!uploadDir.exists()) {
uploadDir.mkdirs();
}
fileName = "upload/" + MainUtils.md5(imgFile.getBytes()) + imgFile.getOriginalFilename().substring(imgFile.getOriginalFilename().lastIndexOf(".")).toLowerCase();
FileCopyUtils.copy(imgFile.getBytes(), new File(path, fileName));
String fileURL = request.getScheme() + "://" + request.getServerName() + "/res/image.html?id=" + fileName;
if (request.getServerPort() == 80) {
fileURL = request.getScheme() + "://" + request.getServerName() + "/res/image.html?id=" + fileName;
} else {
fileURL = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/res/image.html?id=" + fileName;
}
upload = new UploadStatus("0", fileURL); //图片直接发送给 客户不用返回
} else {
upload = new UploadStatus("请选择图片文件");
}
map.addAttribute("upload", upload);
return view;
}
@RequestMapping("/file")
@Menu(type = "resouce" , subtype = "file" , access = false)
public void file(HttpServletResponse response,HttpServletRequest request, @Valid String id) throws IOException {
if(!StringUtils.isBlank(id)){
AttachmentFile attachmentFile = attachementRes.findByIdAndOrgi(id, super.getOrgi(request)) ;
if(attachmentFile!=null){
response.setContentType(attachmentFile.getFiletype());
response.setHeader("Content-Disposition", "attachment;filename="+java.net.URLEncoder.encode(attachmentFile.getTitle(), "UTF-8"));
if(!StringUtils.isBlank(attachmentFile.getModel()) && attachmentFile.getModel().equals("app")){
response.getOutputStream().write(FileUtils.readFileToByteArray(new File(path , "app/app/"+attachmentFile.getFileid())));
}else{
response.getOutputStream().write(FileUtils.readFileToByteArray(new File(path , "app/workorders/"+attachmentFile.getFileid())));
}
}
}
@Menu(type = "resouce", subtype = "file", access = false)
public void file(HttpServletResponse response, HttpServletRequest request, @Valid String id) throws IOException {
if (!StringUtils.isBlank(id)) {
AttachmentFile attachmentFile = attachementRes.findByIdAndOrgi(id, super.getOrgi(request));
if (attachmentFile != null) {
response.setContentType(attachmentFile.getFiletype());
response.setHeader("Content-Disposition", "attachment;filename=" + java.net.URLEncoder.encode(attachmentFile.getTitle(), "UTF-8"));
if (StringUtils.isNotBlank(attachmentFile.getModel()) && attachmentFile.getModel().equals("app")) {
response.getOutputStream().write(FileUtils.readFileToByteArray(new File(path, "app/" + attachmentFile.getFileid())));
} else {
response.getOutputStream().write(FileUtils.readFileToByteArray(new File(path, "upload/" + attachmentFile.getFileid())));
}
}
}
}
@RequestMapping("/template")
@Menu(type = "resouce" , subtype = "template" , access = false)
public void template(HttpServletResponse response,HttpServletRequest request, @Valid String filename) throws IOException {
if(!StringUtils.isBlank(filename)){
InputStream is = MediaController.class.getClassLoader().getResourceAsStream(TEMPLATE_DATA_PATH+filename);
if(is!=null) {
response.setContentType("text/plain");
response.setHeader("Content-Disposition", "attachment;filename="+java.net.URLEncoder.encode(filename, "UTF-8"));
int length ;
byte[] data = new byte[1024] ;
while((length = is.read(data)) > 0) {
response.getOutputStream().write(data , 0 , length);
}
is.close();
}
}
return ;
@Menu(type = "resouce", subtype = "template", access = false)
public void template(HttpServletResponse response, HttpServletRequest request, @Valid String filename) throws IOException {
if (!StringUtils.isBlank(filename)) {
InputStream is = MediaController.class.getClassLoader().getResourceAsStream(TEMPLATE_DATA_PATH + filename);
if (is != null) {
response.setContentType("text/plain");
response.setHeader("Content-Disposition", "attachment;filename=" + java.net.URLEncoder.encode(filename, "UTF-8"));
int length;
byte[] data = new byte[1024];
while ((length = is.read(data)) > 0) {
response.getOutputStream().write(data, 0, length);
}
is.close();
}
}
return;
}
}

View File

@ -24,6 +24,7 @@ import com.chatopera.cc.app.im.message.AgentStatusMessage;
import com.chatopera.cc.app.im.message.ChatMessage;
import com.chatopera.cc.app.im.message.NewRequestMessage;
import com.chatopera.cc.app.im.util.ChatbotUtils;
import com.chatopera.cc.app.im.util.IMServiceUtils;
import com.chatopera.cc.app.model.*;
import com.chatopera.cc.app.persistence.repository.AgentUserRepository;
import com.chatopera.cc.app.persistence.repository.ChatbotRepository;
@ -82,6 +83,11 @@ public class ChatbotEventHandler {
NettyClients.getInstance().putChatbotEventClient(user, client);
CousultInvite invite = OnlineUserUtils.cousult(appid, orgi, MainContext.getContext().getBean(ConsultInviteRepository.class));
/**
* 更新坐席服务类型
*/
IMServiceUtils.shiftOpsType(user, orgi, MainContext.OptTypeEnum.CHATBOT);
// send out tip
MessageOutContent tip = new MessageOutContent();
tip.setMessage("您正在使用机器人客服!");

View File

@ -25,6 +25,7 @@ import com.chatopera.cc.app.im.message.AgentStatusMessage;
import com.chatopera.cc.app.im.message.ChatMessage;
import com.chatopera.cc.app.im.message.NewRequestMessage;
import com.chatopera.cc.app.im.util.HumanUtils;
import com.chatopera.cc.app.im.util.IMServiceUtils;
import com.chatopera.cc.app.model.*;
import com.chatopera.cc.app.persistence.impl.AgentUserService;
import com.chatopera.cc.app.persistence.repository.AgentServiceRepository;
@ -37,6 +38,8 @@ import com.corundumstudio.socketio.annotation.OnConnect;
import com.corundumstudio.socketio.annotation.OnDisconnect;
import com.corundumstudio.socketio.annotation.OnEvent;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.UnsupportedEncodingException;
@ -45,6 +48,7 @@ import java.util.Date;
import java.util.List;
public class IMEventHandler {
private final static Logger logger = LoggerFactory.getLogger(IMEventHandler.class);
protected SocketIOServer server;
@Autowired
@ -75,11 +79,16 @@ public class IMEventHandler {
InetSocketAddress address = (InetSocketAddress) client.getRemoteAddress();
String ip = MainUtils.getIpAddr(client.getHandshakeData().getHttpHeaders(), address.getHostString());
NewRequestMessage newRequestMessage = OnlineUserUtils.newRequestMessage(user, orgi, session, appid, ip, client.getHandshakeData().getSingleUrlParam("osname"), client.getHandshakeData().getSingleUrlParam("browser"), MainContext.ChannelTypeEnum.WEBIM.toString(), skill, agent, nickname, title, url, traceid, MainContext.ChatInitiatorType.USER.toString());
// /**
// * 加入到 缓存列表
// */
/**
* 加入到 缓存列表
*/
NettyClients.getInstance().putIMEventClient(user, client);
//
/**
* 更新坐席服务类型
*/
IMServiceUtils.shiftOpsType(user, orgi, MainContext.OptTypeEnum.HUMAN);
if (newRequestMessage != null && StringUtils.isNotBlank(newRequestMessage.getMessage())) {
MessageOutContent outMessage = new MessageOutContent();
outMessage.setMessage(newRequestMessage.getMessage());
@ -137,6 +146,7 @@ public class IMEventHandler {
agentUser.setEmail(contacts.getEmail());
agentUser.setResion(contacts.getMemo());
agentUser.setChatbotops(false); // 非机器人客服
agentUser.setOpttype(MainContext.OptTypeEnum.HUMAN.toString());
service.save(agentUser);
CacheHelper.getAgentUserCacheBean().put(agentUser.getUserid(), agentUser, MainContext.SYSTEM_ORGI);
}

View File

@ -0,0 +1,39 @@
package com.chatopera.cc.app.im.util;
import com.chatopera.cc.app.basic.MainContext;
import com.chatopera.cc.app.cache.CacheHelper;
import com.chatopera.cc.app.model.AgentUser;
import com.chatopera.cc.app.persistence.impl.AgentUserService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class IMServiceUtils {
private final static Logger logger = LoggerFactory.getLogger(IMServiceUtils.class);
public static void shiftOpsType(final String userId, final String orgi, final MainContext.OptTypeEnum opsType){
AgentUser agentUser = (AgentUser) CacheHelper.getAgentUserCacheBean().getCacheObject(userId, orgi);
AgentUserService service = MainContext.getContext().getBean(
AgentUserService.class);
if (agentUser == null) {
agentUser = service.findByUseridAndOrgi(userId, orgi);
}
if (agentUser != null) {
switch (opsType){
case CHATBOT:
agentUser.setOpttype(MainContext.OptTypeEnum.CHATBOT.toString());
agentUser.setChatbotops(true);
break;
case HUMAN:
agentUser.setOpttype(MainContext.OptTypeEnum.HUMAN.toString());
agentUser.setChatbotops(false);
break;
default:
logger.warn("shiftOpsType unknown type.");
break;
}
}
service.save(agentUser);
CacheHelper.getAgentUserCacheBean().put(agentUser.getUserid(), agentUser, orgi);
}
}

View File

@ -103,7 +103,7 @@ public class RichMediaUtils {
data.setTouser(agentUser.getAgentno());
data.setAppid(agentUser.getAppid());
data.setOrgi(agentUser.getOrgi());
if (StringUtils.equals(agentUser.getOpttype(), MainContext.OptTypeEnum.CHATBOT.toString())) {
if (agentUser.isChatbotops()) {
// TODO #75 create Chatbot Message
// https://github.com/chatopera/cosin/issues/75
logger.info("[createRichMediaMessageWithChannel] TODO #75 create Chatbot Message");