jiangping
2025-04-24 80ea9d9c1b4474fb3d14622c945c3ddceb860218
代码初始化
已添加2个文件
已修改4个文件
321 ■■■■■ 文件已修改
server/src/main/java/com/doumee/api/common/PublicCloudController.java 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/com/doumee/core/utils/HttpsUtil.java 99 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/com/doumee/core/utils/qiyeweixin/QywxConstant.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/com/doumee/core/utils/qiyeweixin/QywxUtil.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxUploadMediaResponse.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/com/doumee/dao/business/dto/WebQwUploadDto.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/com/doumee/api/common/PublicCloudController.java
@@ -10,9 +10,13 @@
import com.doumee.core.constants.Constants;
import com.doumee.core.constants.ResponseStatus;
import com.doumee.core.exception.BusinessException;
import com.doumee.core.model.ApiResponse;
import com.doumee.core.utils.DateUtil;
import com.doumee.core.utils.FtpUtil;
import com.doumee.core.utils.azure.AzureBlobUtil;
import com.doumee.core.utils.qiyeweixin.QywxUtil;
import com.doumee.core.utils.qiyeweixin.model.response.QywxUploadMediaResponse;
import com.doumee.dao.business.dto.WebQwUploadDto;
import com.doumee.dao.system.model.SystemDictData;
import com.doumee.service.common.EmailService;
import io.swagger.annotations.Api;
@@ -56,6 +60,62 @@
    public static FtpUtil ftp  = null;
    public static AzureBlobUtil azureBlobUtil  = null;
    @ApiOperation(value = "测试企业素材上传下载")
    @RequestMapping(method= RequestMethod.POST,value="/testQwImg")
    @ResponseBody
    public ApiResponse<Map<String, Object>> testQwImg(  @RequestParam(required = false) String imgurl ) throws Exception {
        QywxUploadMediaResponse r = QywxUtil.uploadMedia(systemDictDataBiz.queryByCode(Constants.QYWX,Constants.QYWX_TOKEN).getCode(),"image",imgurl);
        if(r!=null && r.getMedia_id()!=null){
            String  folder = systemDictDataBiz.queryByCode(Constants.FTP,Constants.WORKORDER_FILE_PATH).getCode();
            String prefixPath = systemDictDataBiz.queryByCode(Constants.FTP,Constants.FTP_RESOURCE_PATH).getCode();
            Map<String, Object> context = new HashMap<>();
            try {
                initUploadTool();
                context.put("success", true);
                context.put("code", 200);
                context.put("errno",0);
                JSONArray jsonArray = new JSONArray();
                Integer index = Constants.ONE;
                    //获得每一个文件
                    String endType = ".jpg";
                    String originname = UUID.randomUUID().toString()+endType;
                    InputStream is = QywxUtil.getMediaInputstream(systemDictDataBiz.queryByCode(Constants.QYWX,Constants.QYWX_TOKEN).getCode(),r.getMedia_id());
                    if(is == null){
                        context.put("code", 0);
                        context.put("message", "上传失败");
                        context.put("errno",0);
                    }else{
                        String date = DateUtil.getNowShortDate();
                        String fName = date + "/" + originname;
                        String fileName = folder + fName;
                        boolean r1 =false;
                        if(StringUtils.equals(Constants.uploadType.blob,uploadType)){
                            r1 = azureBlobUtil.uploadFileWithResponse( fileName,is);//上传
                        }else{
                            r1 = ftp.uploadInputstreamBatch(is, fileName, true,index);
                        }
                        if (r1) {
                            JSONObject fileJSON = new JSONObject();
                            fileJSON.put("url", prefixPath + fileName);
                            fileJSON.put("imgaddr", fName);
                            fileJSON.put("imgname", fileName);
                            fileJSON.put("originname", originname);
                            jsonArray.add(fileJSON);
                        }
                    }
                context.put("data",jsonArray);
            } catch (Exception e) {
                log.error("【上传FTP失败】======================"+e.getMessage());
                context.put("code", 0);
                context.put("message", "上传失败");
                context.put("errno",0);
            }
            return ApiResponse.success(context);
        }
        return ApiResponse.failed("上传失败"+r!=null?JSONObject.toJSONString(r):"");
    }
    @ApiOperation(value = "测试邮件发送")
    @RequestMapping(method= RequestMethod.POST,value="/testEmail")
    @ResponseBody
@@ -149,6 +209,72 @@
        writerJson(response, context);
        return;
    }
    @ApiOperation(value = "批量从企业临时素材库上传文件到文件服务器")
    @PostMapping(value="/uploadBatchFromWx")
    @ResponseBody
    public void uploadBatchFromWx(@RequestBody WebQwUploadDto param, HttpServletResponse response) throws Exception {
        if(Objects.isNull(param.getFolder()) || param.getMediaIds()==null || param.getMediaIds().size()==0){
            throw new BusinessException(ResponseStatus.BAD_REQUEST);
        }
        SystemDictData folderData =  systemDictDataBiz.queryByCode(Constants.FTP,param.getFolder());
        if(Objects.isNull(folderData)||StringUtils.isBlank(folderData.getCode())){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"目标文件夹错误");
        }
        String  folder = systemDictDataBiz.queryByCode(Constants.FTP,param.getFolder()).getCode();
        String prefixPath = systemDictDataBiz.queryByCode(Constants.FTP,Constants.FTP_RESOURCE_PATH).getCode();
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        Map<String, Object> context = new HashMap<>();
        try {
            initUploadTool();
            context.put("success", true);
            context.put("code", 200);
            context.put("errno",0);
                JSONArray jsonArray = new JSONArray();
                    Integer index = Constants.ONE;
                    for (String media : param.getMediaIds()) {
                        //获得每一个文件
                        String endType = ".jpg";
                        String originname = UUID.randomUUID().toString()+endType;
                        InputStream is = QywxUtil.getMediaInputstream(systemDictDataBiz.queryByCode(Constants.QYWX,Constants.QYWX_TOKEN).getCode(),media);
                        if(is == null){
                            log.error("企业微信素材下载失败:========="+media);
                            continue;
                        }
                        log.error("企业微信素材下载成功:========="+media);
                        String date = DateUtil.getNowShortDate();
                        String fName = date + "/" + originname;
                        String fileName = folder + fName;
                        boolean r =false;
                        if(StringUtils.equals(Constants.uploadType.blob,uploadType)){
                            r = azureBlobUtil.uploadFileWithResponse( fileName,is);//上传
                        }else{
                            r = ftp.uploadInputstreamBatch(is, fileName, Constants.equalsInteger(index ,param.getMediaIds().size()),index);
                        }
                        if (r) {
                            JSONObject fileJSON = new JSONObject();
                            fileJSON.put("url", prefixPath + fileName);
                            fileJSON.put("imgaddr", fName);
                            fileJSON.put("imgname", fileName);
                            fileJSON.put("originname", originname);
                            jsonArray.add(fileJSON);
                        }
                        index = index + 1;
                }
                context.put("data",jsonArray);
        } catch (Exception e) {
            log.error("【上传FTP失败】======================"+e.getMessage());
            context.put("code", 0);
            context.put("message", "上传失败");
            context.put("errno",0);
            writerJson(response, context);
            return;
        }
        writerJson(response, context);
        return;
    }
    @ApiOperation(value = "批量上传文件到FTP")
    @RequestMapping(method= RequestMethod.POST,value="/uploadBatchOld")
    @ResponseBody
server/src/main/java/com/doumee/core/utils/HttpsUtil.java
@@ -1,9 +1,7 @@
package com.doumee.core.utils;
import javax.net.ssl.*;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.KeyManagementException;
@@ -28,7 +26,80 @@
            return connectionHttp(url, "POST", data, "application/json");
        }
    }
    public static String uploadTempMedia(String urlString ,String fileUrl){
        HttpsURLConnection conn= null;
        try {
            String fileName = fileUrl.substring(fileUrl.lastIndexOf("/") + 1);
            // èŽ·å–ç½‘ç»œå›¾ç‰‡
            URL mediaUrl = new URL(fileUrl);
            HttpURLConnection meidaConn = (HttpURLConnection) mediaUrl.openConnection();
            meidaConn.setDoOutput(true);
            meidaConn.setRequestMethod("GET");
            String result = null;
            URL url=new URL(urlString);
            conn=(HttpsURLConnection) url.openConnection();
            conn.setRequestMethod("POST");//以POST方式提交表单
            conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.setUseCaches(false);//POST方式不能使用缓存
            //设置请求头信息
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.setRequestProperty("Charset", "UTF-8");
            //设置边界
            String BOUNDARY="----------"+System.currentTimeMillis();
            conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
            //请求正文信息
            //第一部分
            StringBuilder sb=new StringBuilder();
            sb.append("--");//必须多两条道
            sb.append(BOUNDARY);
            sb.append("\r\n");
            sb.append("Content-Disposition: form-data;name=\"media\"; filename=\"" + fileName+"\"\r\n");
            sb.append("Content-Type:application/octet-stream\r\n\r\n");
            System.out.println("sb:"+sb);
            //获得输出流
            OutputStream out=new DataOutputStream(conn.getOutputStream());
            //输出表头
            out.write(sb.toString().getBytes("UTF-8"));
            //文件正文部分
            //把文件以流的方式 æŽ¨é€é“URL中
            DataInputStream din=new DataInputStream(meidaConn.getInputStream());
            int bytes=0;
            byte[] buffer=new byte[1024];
            while((bytes=din.read(buffer))!=-1){
                out.write(buffer,0,bytes);
            }
            din.close();
            //结尾部分
            byte[] foot=("\r\n--" + BOUNDARY + "--\r\n").getBytes("UTF-8");//定义数据最后分割线
            out.write(foot);
            out.flush();
            out.close();
            if(HttpsURLConnection.HTTP_OK==conn.getResponseCode()){
                InputStream is = conn.getInputStream();
                byte[] b = new byte[4096];
                ByteArrayOutputStream baos = new ByteArrayOutputStream(b.length);
                int len;
                while ((len = is.read(b)) != -1) {
                    baos.write(b, 0, len);
                }
                is.close();
                return baos.toString("utf-8");
            }
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(conn != null){
                conn.disconnect();
            }
        }
        return null;
    }
    public static String connection(String url,String method,String data,String contentType,boolean ignoreSSL){
        HttpsURLConnection connection = null;
        try {
@@ -92,29 +163,11 @@
        try {
            URL _url = new URL(url);
            connection = (HttpURLConnection) _url.openConnection();
            connection.setRequestMethod(method);
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setUseCaches(false);
            if(contentType != null){
                connection.setRequestProperty("Content-Type", contentType);
            }
            connection.connect();
            if(data != null){
                OutputStream outputStream = connection.getOutputStream();
                outputStream.write(data.getBytes("utf-8"));
                outputStream.close();
            }
            int responseCode = connection.getResponseCode();
            if (responseCode == HttpsURLConnection.HTTP_OK) {
               return  connection.getInputStream();
            }
            connection.setRequestMethod("GET");
            return connection.getInputStream();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(connection != null){
                connection.disconnect();
            }
        }
        return null;
    }
server/src/main/java/com/doumee/core/utils/qiyeweixin/QywxConstant.java
@@ -19,6 +19,8 @@
    //获取部门成员,access_token=调用接口凭证,department_id=获取的部门id,fetch_child=    æ˜¯å¦é€’归获取子部门下面的成员:1-递归获取,0-只获取本部门
    public final static String[]  GET_DEPARTMENT_SIMPLE_LIST = new String[]{"/cgi-bin/user/simplelist?access_token=${accesstoken}&department_id=${departmentId}","获取部门成员"};
    public final static String[]  GET_DEPARTMENT_USER_LIST = new String[]{"/cgi-bin/user/list?access_token=${accesstoken}&department_id=${departmentId}","获取部门成员"};
    public final static String[]  GET_MEDIA = new String[]{"/cgi-bin/media/get?access_token=${accesstoken}&media_id=${media_id}","获取临时素材"};
    public final static String[]  UPLOAD_TEMP_MEDIA = new String[]{"/cgi-bin/media/upload?access_token=${accesstoken}&type=${type}","上传临时素材"};
    //获取成员详情,access_token=调用接口凭证,userid=成员UserID
    public final static String[]  GET_USER_DETAIL =new String[]{ "/cgi-bin/user/get?access_token=${accesstoken}&userid=${id}","获取成员详情"};
    //发送应用消息,access_token=调用接口凭证  POST请求,
server/src/main/java/com/doumee/core/utils/qiyeweixin/QywxUtil.java
@@ -13,7 +13,9 @@
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -112,12 +114,42 @@
        return null;
    }
    public static InputStream getMediaInputstream(String token, String media)   {
        try {
            String[] interfaceUrl = QywxConstant.GET_MEDIA;
            String url = qyUtil.qiweiUrl+interfaceUrl[0].replace("${accesstoken}",token).replace("${media_id}",media);
            log.error("企业微信临时素材获取url=========="+url);
            return  HttpsUtil.connectionInputsteam(url,"GET",null,null);
        }catch (Exception e){
            e.printStackTrace();
            log.error("企业微信临时素材获取error=========="+e.getMessage());
        }
        return null;
    }
    public static QywxUserInfoResponse getUserInfo(String token,String id)  {
        String[] interfaceUrl = QywxConstant.GET_USER_DETAIL;
        String url = interfaceUrl[0].replace("${accesstoken}",token).replace("${id}",id);
        QywxUserInfoResponse response = sendHttpRequestSingle(url,interfaceUrl[1],""
                ,new TypeReference<QywxUserInfoResponse>(){});
        if(response.getErrcode()!=null && response.getErrcode() ==0){
            return response;
        }
        return null;
    }
    /**
     *
     * @param token
     * @param type     åª’体文件类型,分别有图片(image)、语音(voice)、视频(video),普通文件(file)
     * @return
     */
    public static QywxUploadMediaResponse uploadMedia(String token,String type,String imgurl)  {
        String[] interfaceUrl = QywxConstant.UPLOAD_TEMP_MEDIA;
        String url = interfaceUrl[0].replace("${accesstoken}",token).replace("${type}",type);
        QywxUploadMediaResponse response = sendHttpRequestMultifile(url,interfaceUrl[1],imgurl
                ,new TypeReference<QywxUploadMediaResponse>(){});
        if(response !=null && response.getErrcode()!=null && response.getErrcode() ==0){
            return response;
        }
        return null;
@@ -172,6 +204,23 @@
        }
        return  null;
    }
    public static  <T extends QywxBaseSingleResponse>  T sendHttpRequestMultifile(String url, String name, String imgUrl  , TypeReference<T> typeReference){
        log.info("【"+name+"】================开始===="+ imgUrl);
        if ( StringUtils.isNotBlank(url)) {
            String res = null;
            try {
                 res = HttpsUtil.uploadTempMedia (qyUtil.qiweiUrl+url,imgUrl);
                log.info("从企微接口:{}----上传临时素材结果:{}",url,res);
                JSONObject jsonObject = JSONObject.parseObject(res);
                T result = JSONObject.parseObject(res, typeReference.getType());
                return  result;
            }catch (Exception e){
                e.printStackTrace();
                log.error("【"+name+"】================失败===="+ imgUrl);
            }
        }
        return  null;
    }
    public static  <T extends QywxBaseSingleResponse>  T sendHttpRequestSingle(String url, String name, String param, TypeReference<T> typeReference){
        log.info("【"+name+"】================开始===="+ JSONObject.toJSONString(param));
        if ( StringUtils.isNotBlank(url)) {
server/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxUploadMediaResponse.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
package com.doumee.core.utils.qiyeweixin.model.response;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
 * @author æ±Ÿè¹„蹄
 * @date 2023/11/23 14:03
 */
@Data
@ApiModel("企业微信上传素材返回参数")
public class QywxUploadMediaResponse extends QywxBaseSingleResponse {
    @ApiModelProperty(value = "媒体文件类型,分别有图片(image)、语音(voice)、视频(video),普通文件(file)")
    private String type;//
    @ApiModelProperty(value = "媒体文件上传后获取的唯一标识,3天内有效")
    private String media_id    ;//
    @ApiModelProperty(value = "媒体文件上传时间戳")
    private String created_at;//
}
server/src/main/java/com/doumee/dao/business/dto/WebQwUploadDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,23 @@
package com.doumee.dao.business.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
 * Created by IntelliJ IDEA.
 *
 * @Author : Rk
 * @create 2023/7/13 10:40
 */
@Data
@ApiModel("企业微信素材上传入参")
public class WebQwUploadDto {
    @ApiModelProperty(value = "素材编码")
    private List<String> mediaIds;
    @ApiModelProperty(value = "素材存放目录字典编码")
    private  String folder;
}