Skip to content

Commit

Permalink
Merge pull request #180 from rememberber/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
rememberber committed Jul 14, 2019
2 parents ed999fc + 44a32f3 commit 5abfd88
Show file tree
Hide file tree
Showing 45 changed files with 1,308 additions and 272 deletions.
4 changes: 4 additions & 0 deletions download.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
<details>
<summary>Windows</summary>

[WePush-v3.5.0_190713-x64-Setup.exe](http://download.zhoubochina.com/exe/WePush-v3.5.0_190713-x64-Setup.exe)
[WePush-with-jre-v3.5.0_190713-x64-Setup.exe](http://download.zhoubochina.com/exe/WePush-with-jre-v3.5.0_190713-x64-Setup.exe)
[WePush-v3.4.2_190630-x64-Setup.exe](http://download.zhoubochina.com/exe/WePush-v3.4.2_190630-x64-Setup.exe)
[WePush-with-jre-v3.4.2_190630-x64-Setup.exe](http://download.zhoubochina.com/exe/WePush-with-jre-v3.4.2_190630-x64-Setup.exe)
[WePush-v3.4.1_190624-x64-Setup.exe](http://download.zhoubochina.com/exe/WePush-v3.4.1_190624-x64-Setup.exe)
Expand Down Expand Up @@ -59,6 +61,7 @@
<details>
<summary>Mac OS</summary>

[v_3.5.0_190713.app](http://download.zhoubochina.com/mac/3.5.0.zip)
[v_3.4.1_190624.app](http://download.zhoubochina.com/mac/3.4.1.zip)
[v_3.4.2_190630.app](http://download.zhoubochina.com/mac/3.4.2.zip)
[v_3.4.0_190619.app](http://download.zhoubochina.com/mac/3.4.0.zip)
Expand Down Expand Up @@ -95,6 +98,7 @@
<details>
<summary>Linux</summary>

[v3.5.0_190713](http://download.zhoubochina.com/linux/WePush-3.5.0.zip)
[v3.4.2_190630](http://download.zhoubochina.com/linux/WePush-3.4.2.zip)
[v3.4.1_190624](http://download.zhoubochina.com/linux/WePush-3.4.1.zip)
[v3.4.0_190619](http://download.zhoubochina.com/linux/WePush-3.4.0.zip)
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/com/fangxuele/tool/push/bean/MailMsg.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ public class MailMsg implements Serializable {
*/
private String mailTitle;

/**
* 抄送
*/
private String mailCc;

/**
* 附件
*/
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/com/fangxuele/tool/push/domain/TMsgMail.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ public class TMsgMail implements Serializable {

private String modifiedTime;

private String cc;

private static final long serialVersionUID = 1L;

public Integer getId() {
Expand Down Expand Up @@ -84,4 +86,12 @@ public String getModifiedTime() {
public void setModifiedTime(String modifiedTime) {
this.modifiedTime = modifiedTime == null ? null : modifiedTime.trim();
}

public String getCc() {
return cc;
}

public void setCc(String cc) {
this.cc = cc == null ? null : cc.trim();
}
}
10 changes: 10 additions & 0 deletions src/main/java/com/fangxuele/tool/push/domain/TMsgWxCp.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ public class TMsgWxCp implements Serializable {

private String modifiedTime;

private String btnTxt;

private static final long serialVersionUID = 1L;

public Integer getId() {
Expand Down Expand Up @@ -124,4 +126,12 @@ public String getModifiedTime() {
public void setModifiedTime(String modifiedTime) {
this.modifiedTime = modifiedTime == null ? null : modifiedTime.trim();
}

public String getBtnTxt() {
return btnTxt;
}

public void setBtnTxt(String btnTxt) {
this.btnTxt = btnTxt == null ? null : btnTxt.trim();
}
}
178 changes: 178 additions & 0 deletions src/main/java/com/fangxuele/tool/push/logic/BoostPushRunThread.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
package com.fangxuele.tool.push.logic;

import cn.hutool.core.date.BetweenFormater;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.cron.pattern.CronPattern;
import cn.hutool.cron.pattern.CronPatternUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.fangxuele.tool.push.App;
import com.fangxuele.tool.push.logic.msgsender.IMsgSender;
import com.fangxuele.tool.push.logic.msgsender.MsgSenderFactory;
import com.fangxuele.tool.push.logic.msgthread.MsgAsyncSendThread;
import com.fangxuele.tool.push.ui.form.BoostForm;
import com.fangxuele.tool.push.util.ConsoleUtil;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.http.HttpResponse;

import javax.swing.*;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Future;

/**
* <pre>
* 性能模式推送执行控制线程
* </pre>
*
* @author <a href="https://github.com/rememberber">RememBerBer</a>
* @since 2019/7/7.
*/
public class BoostPushRunThread extends Thread {

private static final Log logger = LogFactory.get();

public static List<Future<HttpResponse>> futureList = Lists.newArrayList();

@Override
public void run() {
BoostForm.boostForm.getProcessedProgressBar().setIndeterminate(true);
BoostForm.boostForm.getCompletedProgressBar().setIndeterminate(true);
// 准备推送
preparePushRun();
BoostForm.boostForm.getProcessedProgressBar().setIndeterminate(false);
BoostForm.boostForm.getCompletedProgressBar().setIndeterminate(false);
ConsoleUtil.boostConsoleWithLog("推送开始……");
// 消息数据分片以及线程纷发
shardingAndMsgThread();
// 时间监控
timeMonitor();
}

/**
* 准备推送
*/
private void preparePushRun() {
// 按钮状态
BoostForm.boostForm.getScheduledRunButton().setEnabled(false);
BoostForm.boostForm.getStartButton().setEnabled(false);
BoostForm.boostForm.getStopButton().setEnabled(true);

BoostForm.boostForm.getStopButton().setText("停止");
// 初始化
BoostForm.boostForm.getProcessedCountLabel().setText("0");
BoostForm.boostForm.getSuccessCountLabel().setText("0");
BoostForm.boostForm.getFailCountLabel().setText("0");

// 设置是否空跑
PushControl.dryRun = BoostForm.boostForm.getDryRunCheckBox().isSelected();

// 执行前重新导入目标用户
PushControl.reimportMembers();

// 重置推送数据
PushData.reset();
PushData.startTime = System.currentTimeMillis();

// 拷贝准备的目标用户
PushData.toSendList.addAll(PushData.allUser);
PushData.toSendCount.set(PushData.allUser.size());
// 总记录数
PushData.totalRecords = PushData.toSendList.size();

BoostForm.boostForm.getMemberCountLabel().setText("消息总数:" + PushData.totalRecords);
BoostForm.boostForm.getProcessedProgressBar().setMaximum((int) PushData.totalRecords);
BoostForm.boostForm.getCompletedProgressBar().setMaximum((int) PushData.totalRecords);
ConsoleUtil.boostConsoleWithLog("消息总数:" + PushData.totalRecords);
// 可用处理器核心数量
BoostForm.boostForm.getProcessorCountLabel().setText("可用处理器核心:" + Runtime.getRuntime().availableProcessors());
ConsoleUtil.boostConsoleWithLog("可用处理器核心:" + Runtime.getRuntime().availableProcessors());

// 准备消息构造器
PushControl.prepareMsgMaker();
}

/**
* 消息数据分片以及线程纷发
*/
private static void shardingAndMsgThread() {

MsgAsyncSendThread msgAsyncSendThread;

IMsgSender msgSender = MsgSenderFactory.getMsgSender();
msgAsyncSendThread = new MsgAsyncSendThread(msgSender);

ThreadUtil.execute(msgAsyncSendThread);
ConsoleUtil.boostConsoleWithLog("线程启动完毕……");
}

/**
* 时间监控
*/
private void timeMonitor() {
long startTimeMillis = System.currentTimeMillis();
// 计时
while (true) {
if (PushData.toSendCount.get() <= PushData.successRecords.longValue() + PushData.failRecords.longValue()) {
if (!PushData.fixRateScheduling) {
BoostForm.boostForm.getStopButton().setEnabled(false);
BoostForm.boostForm.getStopButton().updateUI();
BoostForm.boostForm.getStartButton().setEnabled(true);
BoostForm.boostForm.getStartButton().updateUI();
BoostForm.boostForm.getScheduledRunButton().setEnabled(true);
BoostForm.boostForm.getScheduledRunButton().updateUI();
BoostForm.boostForm.getScheduledTaskLabel().setText("");
String finishTip = "发送完毕!\n";
JOptionPane.showMessageDialog(BoostForm.boostForm.getBoostPanel(), finishTip, "提示",
JOptionPane.INFORMATION_MESSAGE);
BoostForm.boostForm.getScheduledTaskLabel().setVisible(false);
} else {
if (App.config.isRadioCron()) {
Date nextDate = CronPatternUtil.nextDateAfter(new CronPattern(App.config.getTextCron()), new Date(), true);
BoostForm.boostForm.getScheduledTaskLabel().setText("计划任务执行中,下一次执行时间:" + DateFormatUtils.format(nextDate, "yyyy-MM-dd HH:mm:ss"));
}
BoostForm.boostForm.getStopButton().setText("停止计划任务");
}

PushData.endTime = System.currentTimeMillis();

// 保存停止前的数据
try {
// 空跑控制
if (!BoostForm.boostForm.getDryRunCheckBox().isSelected()) {
ConsoleUtil.boostConsoleWithLog("正在保存结果数据……");
BoostForm.boostForm.getCompletedProgressBar().setIndeterminate(true);
PushControl.savePushData();
ConsoleUtil.boostConsoleWithLog("结果数据保存完毕!");
}
} catch (IOException e) {
logger.error(e);
} finally {
BoostForm.boostForm.getCompletedProgressBar().setIndeterminate(false);
}
break;
}

long currentTimeMillis = System.currentTimeMillis();
long lastTimeMillis = currentTimeMillis - startTimeMillis;
long leftTimeMillis = (long) ((double) lastTimeMillis / (PushData.sendSuccessList.size() + PushData.sendFailList.size()) * (PushData.allUser.size() - PushData.sendSuccessList.size() - PushData.sendFailList.size()));

// 耗时
String formatBetweenLast = DateUtil.formatBetween(lastTimeMillis, BetweenFormater.Level.SECOND);
BoostForm.boostForm.getLastTimeLabel().setText("".equals(formatBetweenLast) ? "0s" : formatBetweenLast);

// 预计剩余
String formatBetweenLeft = DateUtil.formatBetween(leftTimeMillis, BetweenFormater.Level.SECOND);
BoostForm.boostForm.getLeftTimeLabel().setText("".equals(formatBetweenLeft) ? "0s" : formatBetweenLeft);

BoostForm.boostForm.getJvmMemoryLabel().setText("JVM内存占用:" + FileUtil.readableFileSize(Runtime.getRuntime().totalMemory()) + "/" + FileUtil.readableFileSize(Runtime.getRuntime().maxMemory()));

ThreadUtil.safeSleep(100);
}
}

}
69 changes: 66 additions & 3 deletions src/main/java/com/fangxuele/tool/push/logic/PushControl.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@
import com.fangxuele.tool.push.logic.msgsender.MailMsgSender;
import com.fangxuele.tool.push.logic.msgsender.MsgSenderFactory;
import com.fangxuele.tool.push.logic.msgsender.SendResult;
import com.fangxuele.tool.push.ui.UiConsts;
import com.fangxuele.tool.push.ui.form.MainWindow;
import com.fangxuele.tool.push.ui.form.MessageEditForm;
import com.fangxuele.tool.push.ui.form.PushForm;
import com.fangxuele.tool.push.ui.form.PushHisForm;
import com.fangxuele.tool.push.ui.form.ScheduleForm;
import com.fangxuele.tool.push.ui.form.SettingForm;
Expand Down Expand Up @@ -68,7 +71,7 @@ public class PushControl {
*/
public static List<SendResult> preview() {
List<SendResult> sendResultList = new ArrayList<>();
if (!pushCheck()) {
if (!configCheck()) {
return null;
}
List<String[]> msgDataList = new ArrayList<>();
Expand Down Expand Up @@ -97,7 +100,44 @@ public static List<SendResult> preview() {
*
* @return boolean
*/
static boolean pushCheck() {
public static boolean pushCheck() {
if (StringUtils.isEmpty(MessageEditForm.messageEditForm.getMsgNameField().getText())) {
JOptionPane.showMessageDialog(MainWindow.mainWindow.getMainPanel(), "请先选择一条消息!", "提示",
JOptionPane.INFORMATION_MESSAGE);
MainWindow.mainWindow.getTabbedPane().setSelectedIndex(2);

return false;
}
if (PushData.allUser == null || PushData.allUser.size() == 0) {
JOptionPane.showMessageDialog(MainWindow.mainWindow.getMainPanel(), "请先准备目标用户!", "提示",
JOptionPane.INFORMATION_MESSAGE);

return false;
}
if (!PushData.boostMode) {
if ("0".equals(PushForm.pushForm.getMaxThreadPoolTextField().getText()) || StringUtils.isEmpty(PushForm.pushForm.getMaxThreadPoolTextField().getText())) {
JOptionPane.showMessageDialog(PushForm.pushForm.getPushPanel(), "请设置每页分配用户数!", "提示",
JOptionPane.INFORMATION_MESSAGE);

return false;
}
if ("0".equals(PushForm.pushForm.getThreadCountTextField().getText()) || StringUtils.isEmpty(PushForm.pushForm.getThreadCountTextField().getText())) {
JOptionPane.showMessageDialog(PushForm.pushForm.getPushPanel(), "请设置每个线程分配的页数!", "提示",
JOptionPane.INFORMATION_MESSAGE);

return false;
}
}

return configCheck();
}

/**
* 配置检查
*
* @return
*/
public static boolean configCheck() {
int msgType = App.config.getMsgType();
switch (msgType) {
case MessageTypeEnum.MP_TEMPLATE_CODE:
Expand Down Expand Up @@ -293,7 +333,7 @@ static void savePushData() throws IOException {
contentBuilder.append("<br/>");
contentBuilder.append("<hr/>");
contentBuilder.append("<p>来自WePush,一款专注于批量推送的小而美的工具</p>");
contentBuilder.append("<img alt=\"WePush\" src=\"http://download.zhoubochina.com/file/wx-zanshang.jpg\">");
contentBuilder.append("<img alt=\"WePush\" src=\"" + UiConsts.INTRODUCE_QRCODE_URL + "\">");

File[] files = new File[fileList.size()];
fileList.toArray(files);
Expand Down Expand Up @@ -363,4 +403,27 @@ static void prepareMsgMaker() {
}
}

/**
* 重新导入目标用户(定时任务)
*/
public static void reimportMembers() {
if (PushData.fixRateScheduling && ScheduleForm.scheduleForm.getReimportCheckBox().isSelected()) {
switch ((String) ScheduleForm.scheduleForm.getReimportComboBox().getSelectedItem()) {
case "通过SQL导入":
MemberListener.importFromSql();
break;
case "通过文件导入":
MemberListener.importFromFile();
break;
case "导入所有关注公众号的用户":
MemberListener.importWxAll();
break;
case "导入企业通讯录中所有用户":
MemberListener.importWxCpAll();
break;
default:
}
}
}

}
Loading

0 comments on commit 5abfd88

Please sign in to comment.