diff --git a/austin-common/src/main/java/com/java3y/austin/common/constant/CommonConstant.java b/austin-common/src/main/java/com/java3y/austin/common/constant/CommonConstant.java index 5e9cde5..15cd874 100644 --- a/austin-common/src/main/java/com/java3y/austin/common/constant/CommonConstant.java +++ b/austin-common/src/main/java/com/java3y/austin/common/constant/CommonConstant.java @@ -54,6 +54,7 @@ public class CommonConstant { public static final String CONTENT_TYPE_TEXT = "text/html;charset=utf-8"; public static final String CONTENT_TYPE_XML = "application/xml; charset=UTF-8"; public static final String CONTENT_TYPE_FORM_URL_ENCODE = "application/x-www-form-urlencoded;charset=utf-8;"; + public static final String CONTENT_TYPE_MULTIPART_FORM_DATA = "multipart/form-data"; /** * HTTP 请求方法 diff --git a/austin-common/src/main/java/com/java3y/austin/common/dto/model/EnterpriseWeChatContentModel.java b/austin-common/src/main/java/com/java3y/austin/common/dto/model/EnterpriseWeChatContentModel.java index 8c1f2c9..557ebd4 100644 --- a/austin-common/src/main/java/com/java3y/austin/common/dto/model/EnterpriseWeChatContentModel.java +++ b/austin-common/src/main/java/com/java3y/austin/common/dto/model/EnterpriseWeChatContentModel.java @@ -5,11 +5,10 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; -import java.util.Map; - /** * @author 3y * 企业微信 应用消息 + * https://developer.work.weixin.qq.com/document/path/90372#%E6%8E%A5%E5%8F%A3%E5%AE%9A%E4%B9%89 */ @Data @Builder diff --git a/austin-common/src/main/java/com/java3y/austin/common/enums/FileType.java b/austin-common/src/main/java/com/java3y/austin/common/enums/FileType.java index 54a93d0..fc95288 100644 --- a/austin-common/src/main/java/com/java3y/austin/common/enums/FileType.java +++ b/austin-common/src/main/java/com/java3y/austin/common/enums/FileType.java @@ -20,12 +20,12 @@ public enum FileType { VIDEO("40", "video"), ; private String code; - private String dingDingName; + private String name; - public static String dingDingNameByCode(String code) { + public static String getNameByCode(String code) { for (FileType fileType : FileType.values()) { if (fileType.getCode().equals(code)) { - return fileType.getDingDingName(); + return fileType.getName(); } } return null; diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/receipt/MessageReceipt.java b/austin-handler/src/main/java/com/java3y/austin/handler/receipt/MessageReceipt.java index a5cd6c9..5b80be1 100644 --- a/austin-handler/src/main/java/com/java3y/austin/handler/receipt/MessageReceipt.java +++ b/austin-handler/src/main/java/com/java3y/austin/handler/receipt/MessageReceipt.java @@ -29,12 +29,11 @@ public class MessageReceipt { while (true) { try { for (ReceiptMessageStater receiptMessageStater : receiptMessageStaterList) { - // 拉取回执需要打开下面一行注释 - //receiptMessageStater.start(); + receiptMessageStater.start(); } Thread.sleep(2000); } catch (Exception e) { - log.error("MessageReceiptApplication#fail:{}", Throwables.getStackTraceAsString(e)); + log.error("MessageReceipt#init fail:{}", Throwables.getStackTraceAsString(e)); } } }); diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/script/impl/TencentSmsScript.java b/austin-handler/src/main/java/com/java3y/austin/handler/script/impl/TencentSmsScript.java index 4681020..4baca75 100644 --- a/austin-handler/src/main/java/com/java3y/austin/handler/script/impl/TencentSmsScript.java +++ b/austin-handler/src/main/java/com/java3y/austin/handler/script/impl/TencentSmsScript.java @@ -65,7 +65,7 @@ public class TencentSmsScript implements SmsScript { PullSmsSendStatusResponse resp = client.PullSmsSendStatus(req); return assemblePullSmsRecord(account, resp); } catch (Exception e) { - log.error("TencentSmsReceipt#pull fail!{}", Throwables.getStackTraceAsString(e)); + // log.error("TencentSmsReceipt#pull fail!{}", Throwables.getStackTraceAsString(e)); return null; } } diff --git a/austin-web/src/main/java/com/java3y/austin/web/controller/MaterialController.java b/austin-web/src/main/java/com/java3y/austin/web/controller/MaterialController.java index bbd77c4..642ab1a 100644 --- a/austin-web/src/main/java/com/java3y/austin/web/controller/MaterialController.java +++ b/austin-web/src/main/java/com/java3y/austin/web/controller/MaterialController.java @@ -41,6 +41,10 @@ public class MaterialController { public BasicResultVO uploadMaterial(@RequestParam("file") MultipartFile file, String sendAccount, Integer sendChannel, String fileType) { if (ChannelType.DING_DING_WORK_NOTICE.getCode().equals(sendChannel)) { return materialService.dingDingMaterialUpload(file, sendAccount, fileType); + } else if (ChannelType.ENTERPRISE_WE_CHAT_ROBOT.getCode().equals(sendChannel)) { + return materialService.enterpriseWeChatRootMaterialUpload(file, sendAccount, fileType); + } else if (ChannelType.ENTERPRISE_WE_CHAT.getCode().equals(sendChannel)) { + return materialService.enterpriseWeChatMaterialUpload(file, sendAccount, fileType); } return BasicResultVO.success(); } diff --git a/austin-web/src/main/java/com/java3y/austin/web/service/MaterialService.java b/austin-web/src/main/java/com/java3y/austin/web/service/MaterialService.java index 8a8ffe8..dfeb0b7 100644 --- a/austin-web/src/main/java/com/java3y/austin/web/service/MaterialService.java +++ b/austin-web/src/main/java/com/java3y/austin/web/service/MaterialService.java @@ -2,12 +2,8 @@ package com.java3y.austin.web.service; import com.java3y.austin.common.vo.BasicResultVO; -import com.java3y.austin.support.domain.MessageTemplate; -import com.java3y.austin.web.vo.MessageTemplateParam; import org.springframework.web.multipart.MultipartFile; -import java.util.List; - /** * 素材接口 * @@ -26,5 +22,21 @@ public interface MaterialService { BasicResultVO dingDingMaterialUpload(MultipartFile file, String sendAccount, String fileType); + /** + * 企业微信(机器人)素材上传 + * @param file + * @param sendAccount + * @param fileType + * @return + */ + BasicResultVO enterpriseWeChatRootMaterialUpload(MultipartFile file, String sendAccount, String fileType); + /** + * 企业微信(应用消息)素材上传 + * @param file + * @param sendAccount + * @param fileType + * @return + */ + BasicResultVO enterpriseWeChatMaterialUpload(MultipartFile file, String sendAccount, String fileType); } diff --git a/austin-web/src/main/java/com/java3y/austin/web/service/impl/MaterialServiceImpl.java b/austin-web/src/main/java/com/java3y/austin/web/service/impl/MaterialServiceImpl.java index 5ceec77..3fabfdc 100644 --- a/austin-web/src/main/java/com/java3y/austin/web/service/impl/MaterialServiceImpl.java +++ b/austin-web/src/main/java/com/java3y/austin/web/service/impl/MaterialServiceImpl.java @@ -1,20 +1,30 @@ package com.java3y.austin.web.service.impl; import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.http.HttpRequest; import com.alibaba.fastjson.JSON; import com.dingtalk.api.DefaultDingTalkClient; import com.dingtalk.api.DingTalkClient; import com.dingtalk.api.request.OapiMediaUploadRequest; import com.dingtalk.api.response.OapiMediaUploadResponse; import com.google.common.base.Throwables; +import com.java3y.austin.common.constant.CommonConstant; import com.java3y.austin.common.constant.SendAccountConstant; +import com.java3y.austin.common.dto.account.EnterpriseWeChatRobotAccount; import com.java3y.austin.common.enums.FileType; import com.java3y.austin.common.enums.RespStatusEnum; import com.java3y.austin.common.vo.BasicResultVO; +import com.java3y.austin.handler.domain.wechat.robot.EnterpriseWeChatRootResult; +import com.java3y.austin.support.utils.AccountUtils; import com.java3y.austin.web.service.MaterialService; +import com.java3y.austin.web.utils.SpringFileUtils; import com.java3y.austin.web.vo.UploadResponseVo; import com.taobao.api.FileItem; import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; +import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl; +import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; @@ -30,7 +40,11 @@ public class MaterialServiceImpl implements MaterialService { @Autowired private StringRedisTemplate redisTemplate; + @Autowired + private AccountUtils accountUtils; + private static final String DING_DING_URL = "https://oapi.dingtalk.com/media/upload"; + private static final String ENTERPRISE_WE_CHAT_ROBOT_URL = "https://qyapi.weixin.qq.com/cgi-bin/webhook/upload_media?key=&type="; @Override public BasicResultVO dingDingMaterialUpload(MultipartFile file, String sendAccount, String fileType) { @@ -42,7 +56,7 @@ public class MaterialServiceImpl implements MaterialService { FileItem item = new FileItem(new StringBuilder().append(IdUtil.fastSimpleUUID()).append(file.getOriginalFilename()).toString(), file.getInputStream()); req.setMedia(item); - req.setType(FileType.dingDingNameByCode(fileType)); + req.setType(FileType.getNameByCode(fileType)); rsp = client.execute(req, accessToken); if (rsp.getErrcode() == 0L) { return new BasicResultVO(RespStatusEnum.SUCCESS, UploadResponseVo.builder().id(rsp.getMediaId()).build()); @@ -54,4 +68,40 @@ public class MaterialServiceImpl implements MaterialService { return BasicResultVO.fail("未知错误,联系管理员"); } + @Override + public BasicResultVO enterpriseWeChatRootMaterialUpload(MultipartFile multipartFile, String sendAccount, String fileType) { + try { + EnterpriseWeChatRobotAccount weChatRobotAccount = accountUtils.getAccountById(Integer.valueOf(sendAccount), EnterpriseWeChatRobotAccount.class); + String key = weChatRobotAccount.getWebhook().substring(weChatRobotAccount.getWebhook().indexOf(CommonConstant.EQUAL_STRING) + 1); + String url = ENTERPRISE_WE_CHAT_ROBOT_URL.replace("", key).replace("", "file"); + String response = HttpRequest.post(url) + .form(IdUtil.fastSimpleUUID(), SpringFileUtils.getFile(multipartFile)) + .execute().body(); + EnterpriseWeChatRootResult result = JSON.parseObject(response, EnterpriseWeChatRootResult.class); + if (result.getErrcode() == 0) { + return new BasicResultVO(RespStatusEnum.SUCCESS, UploadResponseVo.builder().id(result.getMediaId()).build()); + } + log.error("MaterialService#enterpriseWeChatRootMaterialUpload fail:{}", result.getErrmsg()); + } catch (Exception e) { + log.error("MaterialService#enterpriseWeChatRootMaterialUpload fail:{}", Throwables.getStackTraceAsString(e)); + } + return BasicResultVO.fail("未知错误,联系管理员"); + } + + @Override + public BasicResultVO enterpriseWeChatMaterialUpload(MultipartFile multipartFile, String sendAccount, String fileType) { + try { + WxCpDefaultConfigImpl accountConfig = accountUtils.getAccountById(Integer.valueOf(sendAccount), WxCpDefaultConfigImpl.class); + WxCpServiceImpl wxCpService = new WxCpServiceImpl(); + wxCpService.setWxCpConfigStorage(accountConfig); + WxMediaUploadResult result = wxCpService.getMediaService().upload(FileType.getNameByCode(fileType), SpringFileUtils.getFile(multipartFile)); + if (StrUtil.isNotBlank(result.getMediaId())) { + return new BasicResultVO(RespStatusEnum.SUCCESS, UploadResponseVo.builder().id(result.getMediaId()).build()); + } + log.error("MaterialService#enterpriseWeChatMaterialUpload fail:{}", JSON.toJSONString(result)); + } catch (Exception e) { + log.error("MaterialService#enterpriseWeChatMaterialUpload fail:{}", Throwables.getStackTraceAsString(e)); + } + return BasicResultVO.fail("未知错误,联系管理员"); + } } diff --git a/austin-web/src/main/java/com/java3y/austin/web/utils/SpringFileUtils.java b/austin-web/src/main/java/com/java3y/austin/web/utils/SpringFileUtils.java new file mode 100644 index 0000000..c5f480c --- /dev/null +++ b/austin-web/src/main/java/com/java3y/austin/web/utils/SpringFileUtils.java @@ -0,0 +1,48 @@ +package com.java3y.austin.web.utils; + +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; + + +/** + * @author 3y + * multipartFile 转成 File 对象 + * + */ +public class SpringFileUtils { + + + /** + * multipartFile 转成 File 对象 + * + * @param multipartFile + * @return + */ + public static File getFile(MultipartFile multipartFile) { + String fileName = multipartFile.getOriginalFilename(); + File file = new File(fileName); + OutputStream out = null; + try { + out = new FileOutputStream(file); + byte[] ss = multipartFile.getBytes(); + for (int i = 0; i < ss.length; i++) { + out.write(ss[i]); + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (out != null) { + try { + out.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return file; + } +} diff --git a/sql/austin.sql b/sql/austin.sql index ecee10f..0f7782e 100644 --- a/sql/austin.sql +++ b/sql/austin.sql @@ -21,7 +21,7 @@ CREATE TABLE `message_template` `template_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '10.运营类 20.技术类接口调用', `msg_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '10.通知类消息 20.营销类消息 30.验证码类消息', `shield_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '10.夜间不屏蔽 20.夜间屏蔽 30.夜间屏蔽(次日早上9点发送)', - `msg_content` varchar(600) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '消息内容 占位符用{$var}表示', + `msg_content` varchar(4096) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '消息内容 占位符用{$var}表示', `send_account` tinyint(4) NOT NULL DEFAULT '0' COMMENT '发送账号 一个渠道下可存在多个账号', `creator` varchar(45) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '创建者', `updator` varchar(45) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '更新者',