|
|
|
@ -1,22 +1,36 @@ |
|
|
|
|
package com.cjy.back.ybsjMessageInfo.controller; |
|
|
|
|
|
|
|
|
|
import com.cjy.back.sysOrgan.entity.SysOrgan; |
|
|
|
|
import com.cjy.back.ybsjAppointment.service.impl.YbsjyAppointmentSettingServiceImpl; |
|
|
|
|
import com.cjy.back.ybsjMessageInfo.entity.YbsjMessageInfo; |
|
|
|
|
import com.cjy.back.ybsjMessageInfo.service.YbsjMessageInfoService; |
|
|
|
|
import com.cjy.util.ServerResponse; |
|
|
|
|
import org.apache.commons.io.FileUtils; |
|
|
|
|
import org.json.JSONArray; |
|
|
|
|
import org.json.JSONException; |
|
|
|
|
import org.json.JSONObject; |
|
|
|
|
import org.slf4j.Logger; |
|
|
|
|
import org.slf4j.LoggerFactory; |
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
|
|
import org.springframework.web.bind.annotation.RequestMapping; |
|
|
|
|
import org.springframework.web.bind.annotation.RestController; |
|
|
|
|
|
|
|
|
|
import javax.servlet.http.HttpServletRequest; |
|
|
|
|
import javax.servlet.http.HttpSession; |
|
|
|
|
import java.io.*; |
|
|
|
|
import java.net.HttpURLConnection; |
|
|
|
|
import java.net.URL; |
|
|
|
|
import java.util.regex.Matcher; |
|
|
|
|
import java.util.regex.Pattern; |
|
|
|
|
|
|
|
|
|
@RestController |
|
|
|
|
@RequestMapping("/messageInfo") |
|
|
|
|
public class YbsjMessageInfoController { |
|
|
|
|
|
|
|
|
|
private final static Logger logger = LoggerFactory.getLogger(YbsjMessageInfoController.class); |
|
|
|
|
@Autowired |
|
|
|
|
private YbsjMessageInfoService messageInfoService; |
|
|
|
|
private final String appId = "wx34d91f48f291a4d6"; |
|
|
|
|
private final String appSecret = "bc11e97b8e00841053cfc7ba8497c876"; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* |
|
|
|
@ -143,6 +157,7 @@ public class YbsjMessageInfoController { |
|
|
|
|
*/ |
|
|
|
|
@RequestMapping("/saveMessageInfo.do") |
|
|
|
|
public ServerResponse saveMessageInfo(YbsjMessageInfo messageInfo, HttpSession session){ |
|
|
|
|
pushMessage(messageInfo); |
|
|
|
|
return messageInfoService.saveMessageInfo(messageInfo,session); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -159,4 +174,220 @@ public class YbsjMessageInfoController { |
|
|
|
|
return messageInfoService.delMessageInfo(guids,session); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 通知公告推送至微信公众号 |
|
|
|
|
* |
|
|
|
|
* @param messageInfo |
|
|
|
|
* @return |
|
|
|
|
*/ |
|
|
|
|
@RequestMapping("/pushMessage.do") |
|
|
|
|
public void pushMessage(YbsjMessageInfo messageInfo) { |
|
|
|
|
try { |
|
|
|
|
logger.warn("接收通知公告推送数据" + messageInfo); |
|
|
|
|
//获取token
|
|
|
|
|
String accessToken = getAccessToken(appId, appSecret); |
|
|
|
|
logger.warn("获取token" + accessToken); |
|
|
|
|
// 步骤1: 处理内容中的图片
|
|
|
|
|
String processedContent = processContent(messageInfo.getContent(), accessToken); |
|
|
|
|
System.out.println("处理后的内容:" + processedContent); |
|
|
|
|
logger.warn("处理后的内容" + processedContent); |
|
|
|
|
// 步骤2: 创建草稿
|
|
|
|
|
createDraft(accessToken, messageInfo.getTitle(), processedContent); |
|
|
|
|
} catch (Exception e) { |
|
|
|
|
logger.error("通知公告推送至微信公众号异常:{}",e); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public String getAccessToken(String appId, String appSecret) throws IOException { |
|
|
|
|
try { |
|
|
|
|
// 目标 URL
|
|
|
|
|
URL url = new URL("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId + "&secret=" + appSecret); |
|
|
|
|
// 打开连接
|
|
|
|
|
HttpURLConnection conn = (HttpURLConnection) url.openConnection(); |
|
|
|
|
|
|
|
|
|
// 设置请求方法
|
|
|
|
|
conn.setRequestMethod("GET"); |
|
|
|
|
|
|
|
|
|
// 设置请求头
|
|
|
|
|
conn.setRequestProperty("Content-Type", "application/json"); |
|
|
|
|
|
|
|
|
|
// 获取响应
|
|
|
|
|
int responseCode = conn.getResponseCode(); |
|
|
|
|
System.out.println("Response Code: " + responseCode); |
|
|
|
|
|
|
|
|
|
BufferedReader in = new BufferedReader( |
|
|
|
|
new InputStreamReader(conn.getInputStream())); |
|
|
|
|
String inputLine; |
|
|
|
|
StringBuilder response = new StringBuilder(); |
|
|
|
|
|
|
|
|
|
while ((inputLine = in.readLine()) != null) { |
|
|
|
|
response.append(inputLine); |
|
|
|
|
} |
|
|
|
|
in.close(); |
|
|
|
|
|
|
|
|
|
JSONObject result = new JSONObject(response.toString()); |
|
|
|
|
return result.getString("access_token"); |
|
|
|
|
} catch (Exception e) { |
|
|
|
|
logger.error("获取token异常:{}",e); |
|
|
|
|
throw new RuntimeException(e); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 1. 下载网络图片(支持自动重试)
|
|
|
|
|
private static File downloadImage(String imageUrl) throws IOException, InterruptedException { |
|
|
|
|
File tempFile = File.createTempFile("wx_", ".tmp"); // 先创建临时文件
|
|
|
|
|
|
|
|
|
|
// 下载文件内容
|
|
|
|
|
FileUtils.copyURLToFile(new URL(imageUrl), tempFile); |
|
|
|
|
|
|
|
|
|
// 验证文件头
|
|
|
|
|
try (InputStream is = new FileInputStream(tempFile)) { |
|
|
|
|
byte[] header = new byte[8]; |
|
|
|
|
is.read(header); |
|
|
|
|
|
|
|
|
|
// PNG头: 89 50 4E 47 0D 0A 1A 0A
|
|
|
|
|
// JPEG头: FF D8 FF
|
|
|
|
|
if (!(header[0] == (byte) 0x89 && header[1] == 'P' && header[2] == 'N' && header[3] == 'G') && |
|
|
|
|
!(header[0] == (byte) 0xFF && header[1] == (byte) 0xD8 && header[2] == (byte) 0xFF)) { |
|
|
|
|
throw new IOException("无效的图片格式"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return tempFile; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 2. 微信图片上传(修复41005错误)
|
|
|
|
|
private static String uploadToWeChat(String accessToken, File file) throws IOException { |
|
|
|
|
String newName =""; |
|
|
|
|
// 1. 验证文件类型
|
|
|
|
|
String fileName = file.getName().toLowerCase(); |
|
|
|
|
if (!fileName.endsWith(".jpg") && !fileName.endsWith(".jpeg") && !fileName.endsWith(".png")) { |
|
|
|
|
// 重命名临时文件为有效扩展名
|
|
|
|
|
newName = fileName.split("\\.")[0] + ".jpg"; |
|
|
|
|
File newFile = new File(file.getParent(), newName); |
|
|
|
|
file.renameTo(newFile); |
|
|
|
|
file = newFile; |
|
|
|
|
} |
|
|
|
|
FileInputStream input = new FileInputStream(file); |
|
|
|
|
String url = "https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=" + accessToken + "&type=image"; |
|
|
|
|
|
|
|
|
|
String boundary = "----WebKitFormBoundary" + System.currentTimeMillis(); |
|
|
|
|
String lineEnd = "\r\n"; |
|
|
|
|
String twoHyphens = "--"; |
|
|
|
|
|
|
|
|
|
HttpURLConnection connection = null; |
|
|
|
|
try { |
|
|
|
|
URL requestUrl = new URL(url); |
|
|
|
|
connection = (HttpURLConnection) requestUrl.openConnection(); |
|
|
|
|
connection.setDoOutput(true); |
|
|
|
|
connection.setDoInput(true); |
|
|
|
|
connection.setUseCaches(false); |
|
|
|
|
connection.setRequestMethod("POST"); |
|
|
|
|
connection.setRequestProperty("Connection", "Keep-Alive"); |
|
|
|
|
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); |
|
|
|
|
|
|
|
|
|
OutputStream outputStream = connection.getOutputStream(); |
|
|
|
|
PrintWriter writer = new PrintWriter(new OutputStreamWriter(outputStream, "UTF-8"), true); |
|
|
|
|
|
|
|
|
|
// 添加文件部分
|
|
|
|
|
writer.append(twoHyphens + boundary + lineEnd); |
|
|
|
|
writer.append("Content-Disposition: form-data; name=\"media\"; filename=\"" + newName + "\"" + lineEnd); |
|
|
|
|
writer.append("Content-Type: image/*" + lineEnd); |
|
|
|
|
writer.append(lineEnd); |
|
|
|
|
writer.flush(); |
|
|
|
|
|
|
|
|
|
// 写入文件内容(使用 MultipartFile.getInputStream())
|
|
|
|
|
InputStream inputStream = input; // 关键修改点!
|
|
|
|
|
byte[] buffer = new byte[4096]; |
|
|
|
|
int bytesRead; |
|
|
|
|
while ((bytesRead = inputStream.read(buffer)) != -1) { |
|
|
|
|
outputStream.write(buffer, 0, bytesRead); |
|
|
|
|
} |
|
|
|
|
outputStream.flush(); |
|
|
|
|
inputStream.close(); |
|
|
|
|
|
|
|
|
|
// 结束部分
|
|
|
|
|
writer.append(lineEnd); |
|
|
|
|
writer.append(twoHyphens + boundary + twoHyphens + lineEnd); |
|
|
|
|
writer.close(); |
|
|
|
|
|
|
|
|
|
// 获取响应
|
|
|
|
|
int responseCode = connection.getResponseCode(); |
|
|
|
|
if (responseCode == HttpURLConnection.HTTP_OK) { |
|
|
|
|
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); |
|
|
|
|
StringBuilder response = new StringBuilder(); |
|
|
|
|
String line; |
|
|
|
|
while ((line = reader.readLine()) != null) { |
|
|
|
|
response.append(line); |
|
|
|
|
} |
|
|
|
|
reader.close(); |
|
|
|
|
|
|
|
|
|
JSONObject result = new JSONObject(response.toString()); |
|
|
|
|
return result.getString("url"); |
|
|
|
|
} else { |
|
|
|
|
throw new IOException("Server returned non-OK status: " + responseCode); |
|
|
|
|
} |
|
|
|
|
} finally { |
|
|
|
|
if (connection != null) { |
|
|
|
|
connection.disconnect(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 3. 替换内容中的图片链接
|
|
|
|
|
private static String processContent(String html, String accessToken) throws Exception { |
|
|
|
|
Pattern pattern = Pattern.compile("<img[^>]+src\\s*=\\s*['\"]([^'\"]+)['\"][^>]*>"); |
|
|
|
|
Matcher matcher = pattern.matcher(html); |
|
|
|
|
StringBuffer result = new StringBuffer(); |
|
|
|
|
|
|
|
|
|
while (matcher.find()) { |
|
|
|
|
String imgUrl = matcher.group(1); |
|
|
|
|
File tempFile = downloadImage(imgUrl); |
|
|
|
|
String wechatUrl = uploadToWeChat(accessToken, tempFile); |
|
|
|
|
matcher.appendReplacement(result, "<img src='" + wechatUrl + "'/>"); |
|
|
|
|
tempFile.delete(); |
|
|
|
|
} |
|
|
|
|
matcher.appendTail(result); |
|
|
|
|
return result.toString(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 4. 创建草稿
|
|
|
|
|
private static void createDraft(String accessToken, String title, String content) throws IOException { |
|
|
|
|
String url = "https://api.weixin.qq.com/cgi-bin/draft/add?access_token=" + accessToken; |
|
|
|
|
|
|
|
|
|
JSONObject article = new JSONObject() |
|
|
|
|
.put("title", title) |
|
|
|
|
.put("content", content) |
|
|
|
|
.put("thumb_media_id", "qR_BnS7D9o1TqpJLTGV3Pmbnz48dU3zFGu6Y_9ws5iKDXNFBGdIHIyRXJVuIjK1b") |
|
|
|
|
.put("show_cover_pic", 1); |
|
|
|
|
JSONArray articles = new JSONArray().put(article); |
|
|
|
|
String requestBody = new JSONObject().put("articles", articles).toString(); |
|
|
|
|
|
|
|
|
|
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection(); |
|
|
|
|
conn.setRequestMethod("POST"); |
|
|
|
|
conn.setDoOutput(true); |
|
|
|
|
conn.setRequestProperty("Content-Type", "application/json"); |
|
|
|
|
|
|
|
|
|
try (OutputStream os = conn.getOutputStream()) { |
|
|
|
|
os.write(requestBody.getBytes("UTF-8")); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()))) { |
|
|
|
|
String line; |
|
|
|
|
StringBuilder response = new StringBuilder(); |
|
|
|
|
while ((line = br.readLine()) != null) { |
|
|
|
|
response.append(line); |
|
|
|
|
} |
|
|
|
|
logger.warn("草稿创建结果: " + response); |
|
|
|
|
System.out.println("草稿创建结果: " + response); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|