From 496bbbd89bbadc15ac54de302f0bab813fad2266 Mon Sep 17 00:00:00 2001 From: zhoubo58 Date: Wed, 17 Mar 2021 09:02:09 +0800 Subject: [PATCH 01/19] =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=85=B3=E9=97=AD=E7=AA=97=E5=8F=A3=E6=97=B6=E6=9C=80=E5=B0=8F?= =?UTF-8?q?=E5=8C=96=E5=88=B0=E6=89=98=E7=9B=98=E9=80=89=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fangxuele/tool/push/ui/form/SettingForm.form | 14 +++++++++++--- .../fangxuele/tool/push/ui/form/SettingForm.java | 11 ++++++++--- .../tool/push/ui/listener/FrameListener.java | 6 ++++-- .../tool/push/ui/listener/SettingListener.java | 5 +++++ .../com/fangxuele/tool/push/util/ConfigUtil.java | 10 ++++++++++ 5 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/fangxuele/tool/push/ui/form/SettingForm.form b/src/main/java/com/fangxuele/tool/push/ui/form/SettingForm.form index 5cc5d6377..8b448acc1 100644 --- a/src/main/java/com/fangxuele/tool/push/ui/form/SettingForm.form +++ b/src/main/java/com/fangxuele/tool/push/ui/form/SettingForm.form @@ -46,7 +46,7 @@ - + @@ -72,10 +72,18 @@ - + + + + + + + + + @@ -83,7 +91,7 @@ - + diff --git a/src/main/java/com/fangxuele/tool/push/ui/form/SettingForm.java b/src/main/java/com/fangxuele/tool/push/ui/form/SettingForm.java index 95a423d6c..5a5d0aaf9 100644 --- a/src/main/java/com/fangxuele/tool/push/ui/form/SettingForm.java +++ b/src/main/java/com/fangxuele/tool/push/ui/form/SettingForm.java @@ -130,6 +130,7 @@ public class SettingForm { private JTextField maxThreadsTextField; private JButton maxThreadsSaveButton; private JCheckBox defaultMaxWindowCheckBox; + private JCheckBox closeToTrayCheckBox; private static SettingForm settingForm; private static TWxAccountMapper wxAccountMapper = MybatisUtil.getSqlSession().getMapper(TWxAccountMapper.class); @@ -157,6 +158,7 @@ public static void init() { // 常规 settingForm.getAutoCheckUpdateCheckBox().setSelected(App.config.isAutoCheckUpdate()); settingForm.getUseTrayCheckBox().setSelected(App.config.isUseTray()); + settingForm.getCloseToTrayCheckBox().setSelected(App.config.isCloseToTray()); settingForm.getDefaultMaxWindowCheckBox().setSelected(App.config.isDefaultMaxWindow()); settingForm.getMaxThreadsTextField().setText(String.valueOf(App.config.getMaxThreads())); @@ -391,7 +393,7 @@ public static void toggleMpOutSideAccessTokenPanel() { panel3.setLayout(new GridLayoutManager(17, 1, new Insets(40, 60, 0, 330), -1, -1)); panel2.add(panel3, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, new Dimension(600, -1), null, 0, false)); final JPanel panel4 = new JPanel(); - panel4.setLayout(new GridLayoutManager(4, 1, new Insets(15, 15, 10, 0), -1, -1)); + panel4.setLayout(new GridLayoutManager(5, 1, new Insets(15, 15, 10, 0), -1, -1)); panel3.add(panel4, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); panel4.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(), "常规", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, this.$$$getFont$$$(null, Font.BOLD, -1, panel4.getFont()), null)); autoCheckUpdateCheckBox = new JCheckBox(); @@ -400,12 +402,15 @@ public static void toggleMpOutSideAccessTokenPanel() { useTrayCheckBox = new JCheckBox(); useTrayCheckBox.setText("显示系统托盘图标"); panel4.add(useTrayCheckBox, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + closeToTrayCheckBox = new JCheckBox(); + closeToTrayCheckBox.setText("关闭窗口时最小化到系统托盘"); + panel4.add(closeToTrayCheckBox, new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); defaultMaxWindowCheckBox = new JCheckBox(); defaultMaxWindowCheckBox.setText("默认最大化窗口"); - panel4.add(defaultMaxWindowCheckBox, new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + panel4.add(defaultMaxWindowCheckBox, new GridConstraints(3, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); final JPanel panel5 = new JPanel(); panel5.setLayout(new GridLayoutManager(1, 4, new Insets(0, 0, 0, 0), -1, -1)); - panel4.add(panel5, new GridConstraints(3, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); + panel4.add(panel5, new GridConstraints(4, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); final JLabel label1 = new JLabel(); label1.setText("最大线程数"); panel5.add(label1, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); diff --git a/src/main/java/com/fangxuele/tool/push/ui/listener/FrameListener.java b/src/main/java/com/fangxuele/tool/push/ui/listener/FrameListener.java index 6e203e1dc..b82ffc6a3 100644 --- a/src/main/java/com/fangxuele/tool/push/ui/listener/FrameListener.java +++ b/src/main/java/com/fangxuele/tool/push/ui/listener/FrameListener.java @@ -52,9 +52,11 @@ public void windowClosing(WindowEvent e) { "有推送任务正在进行!\n\n为避免数据丢失,请先停止!\n\n", "Sorry~", JOptionPane.WARNING_MESSAGE); } else { - App.sqlSession.close(); mainFrame.dispose(); - mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + if (!App.config.isCloseToTray()) { + App.sqlSession.close(); + mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + } } } diff --git a/src/main/java/com/fangxuele/tool/push/ui/listener/SettingListener.java b/src/main/java/com/fangxuele/tool/push/ui/listener/SettingListener.java index ef5e50be3..ca6f1b7e8 100644 --- a/src/main/java/com/fangxuele/tool/push/ui/listener/SettingListener.java +++ b/src/main/java/com/fangxuele/tool/push/ui/listener/SettingListener.java @@ -81,6 +81,11 @@ public static void addListeners() { App.tray = null; } }); + // 设置-常规-关闭窗口时最小化到系统托盘 + settingForm.getCloseToTrayCheckBox().addActionListener(e -> { + App.config.setCloseToTray(settingForm.getCloseToTrayCheckBox().isSelected()); + App.config.save(); + }); // 设置-常规-默认最大化窗口 settingForm.getDefaultMaxWindowCheckBox().addActionListener(e -> { App.config.setDefaultMaxWindow(settingForm.getDefaultMaxWindowCheckBox().isSelected()); diff --git a/src/main/java/com/fangxuele/tool/push/util/ConfigUtil.java b/src/main/java/com/fangxuele/tool/push/util/ConfigUtil.java index 02aed251e..c8c2f47fa 100644 --- a/src/main/java/com/fangxuele/tool/push/util/ConfigUtil.java +++ b/src/main/java/com/fangxuele/tool/push/util/ConfigUtil.java @@ -60,6 +60,8 @@ private ConfigUtil() { private boolean useTray; + private boolean closeToTray; + private boolean defaultMaxWindow; private Integer maxThreads; @@ -382,6 +384,14 @@ public void setUseTray(boolean useTray) { setting.put("setting.normal", "useTray", String.valueOf(useTray)); } + public boolean isCloseToTray() { + return setting.getBool("closeToTray", "setting.normal", true); + } + + public void setCloseToTray(boolean closeToTray) { + setting.put("setting.normal", "closeToTray", String.valueOf(closeToTray)); + } + public boolean isDefaultMaxWindow() { return setting.getBool("defaultMaxWindow", "setting.normal", true); } From d8d1c1b109843204f51b27fbfc775f43a9cd4885 Mon Sep 17 00:00:00 2001 From: zhoubo58 Date: Tue, 23 Mar 2021 14:35:37 +0800 Subject: [PATCH 02/19] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=85=AC=E4=BC=97?= =?UTF-8?q?=E5=8F=B7=E8=AE=A2=E9=98=85=E9=80=9A=E7=9F=A5-=E5=88=9D?= =?UTF-8?q?=E6=AD=A5-=E6=9B=B4=E6=96=B0=E4=BE=9D=E8=B5=96=E5=92=8C?= =?UTF-8?q?=E5=BB=BA=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 8 +- .../tool/push/dao/TMsgMpSubscribeMapper.java | 17 ++ .../tool/push/domain/TMsgMpSubscribe.java | 117 +++++++++++++ .../logic/msgmaker/WxMaSubscribeMsgMaker.java | 4 +- .../logic/msgsender/WxUniformMsgSender.java | 4 +- src/main/resources/db_init.sql | 19 ++ src/main/resources/generatorConfig.xml | 8 +- .../mapper/TMsgMpSubscribeMapper.xml | 164 ++++++++++++++++++ src/main/resources/mybatis-config.xml | 1 + src/main/resources/upgrade/47.sql | 18 ++ 10 files changed, 348 insertions(+), 12 deletions(-) create mode 100644 src/main/java/com/fangxuele/tool/push/dao/TMsgMpSubscribeMapper.java create mode 100644 src/main/java/com/fangxuele/tool/push/domain/TMsgMpSubscribe.java create mode 100644 src/main/resources/mapper/TMsgMpSubscribeMapper.xml create mode 100644 src/main/resources/upgrade/47.sql diff --git a/pom.xml b/pom.xml index afc44587b..73aaf80ee 100644 --- a/pom.xml +++ b/pom.xml @@ -20,9 +20,9 @@ 1.8 1.2.3 - 4.0.0 - 4.0.0 - 4.0.0 + 4.0.6.B + 4.0.6.B + 4.0.6.B 5.1.1 5.4.4 5.2 @@ -47,7 +47,7 @@ 1.1.0 0.10.134 7.3.0 - 1.0 + 1.1 diff --git a/src/main/java/com/fangxuele/tool/push/dao/TMsgMpSubscribeMapper.java b/src/main/java/com/fangxuele/tool/push/dao/TMsgMpSubscribeMapper.java new file mode 100644 index 000000000..5f3ac4a86 --- /dev/null +++ b/src/main/java/com/fangxuele/tool/push/dao/TMsgMpSubscribeMapper.java @@ -0,0 +1,17 @@ +package com.fangxuele.tool.push.dao; + +import com.fangxuele.tool.push.domain.TMsgMpSubscribe; + +public interface TMsgMpSubscribeMapper { + int deleteByPrimaryKey(Integer id); + + int insert(TMsgMpSubscribe record); + + int insertSelective(TMsgMpSubscribe record); + + TMsgMpSubscribe selectByPrimaryKey(Integer id); + + int updateByPrimaryKeySelective(TMsgMpSubscribe record); + + int updateByPrimaryKey(TMsgMpSubscribe record); +} \ No newline at end of file diff --git a/src/main/java/com/fangxuele/tool/push/domain/TMsgMpSubscribe.java b/src/main/java/com/fangxuele/tool/push/domain/TMsgMpSubscribe.java new file mode 100644 index 000000000..e302bf86d --- /dev/null +++ b/src/main/java/com/fangxuele/tool/push/domain/TMsgMpSubscribe.java @@ -0,0 +1,117 @@ +package com.fangxuele.tool.push.domain; + +import java.io.Serializable; + +public class TMsgMpSubscribe implements Serializable { + private Integer id; + + private Integer msgType; + + private String msgName; + + private String templateId; + + private String url; + + private String maAppid; + + private String maPagePath; + + private String previewUser; + + private Integer wxAccountId; + + private String createTime; + + private String modifiedTime; + + private static final long serialVersionUID = 1L; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public Integer getMsgType() { + return msgType; + } + + public void setMsgType(Integer msgType) { + this.msgType = msgType; + } + + public String getMsgName() { + return msgName; + } + + public void setMsgName(String msgName) { + this.msgName = msgName == null ? null : msgName.trim(); + } + + public String getTemplateId() { + return templateId; + } + + public void setTemplateId(String templateId) { + this.templateId = templateId == null ? null : templateId.trim(); + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url == null ? null : url.trim(); + } + + public String getMaAppid() { + return maAppid; + } + + public void setMaAppid(String maAppid) { + this.maAppid = maAppid == null ? null : maAppid.trim(); + } + + public String getMaPagePath() { + return maPagePath; + } + + public void setMaPagePath(String maPagePath) { + this.maPagePath = maPagePath == null ? null : maPagePath.trim(); + } + + public String getPreviewUser() { + return previewUser; + } + + public void setPreviewUser(String previewUser) { + this.previewUser = previewUser == null ? null : previewUser.trim(); + } + + public Integer getWxAccountId() { + return wxAccountId; + } + + public void setWxAccountId(Integer wxAccountId) { + this.wxAccountId = wxAccountId; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime == null ? null : createTime.trim(); + } + + public String getModifiedTime() { + return modifiedTime; + } + + public void setModifiedTime(String modifiedTime) { + this.modifiedTime = modifiedTime == null ? null : modifiedTime.trim(); + } +} \ No newline at end of file diff --git a/src/main/java/com/fangxuele/tool/push/logic/msgmaker/WxMaSubscribeMsgMaker.java b/src/main/java/com/fangxuele/tool/push/logic/msgmaker/WxMaSubscribeMsgMaker.java index 4c1b2c491..c28f0fa1e 100644 --- a/src/main/java/com/fangxuele/tool/push/logic/msgmaker/WxMaSubscribeMsgMaker.java +++ b/src/main/java/com/fangxuele/tool/push/logic/msgmaker/WxMaSubscribeMsgMaker.java @@ -67,9 +67,9 @@ public WxMaSubscribeMessage makeMsg(String[] msgData) { String templateUrlEvaluated = TemplateUtil.evaluate(templateUrl, velocityContext); wxMaSubscribeMessage.setPage(templateUrlEvaluated); - WxMaSubscribeMessage.Data wxMaSubscribeData; + WxMaSubscribeMessage.MsgData wxMaSubscribeData; for (TemplateData templateData : templateDataList) { - wxMaSubscribeData = new WxMaSubscribeMessage.Data(); + wxMaSubscribeData = new WxMaSubscribeMessage.MsgData(); wxMaSubscribeData.setName(templateData.getName()); wxMaSubscribeData.setValue(TemplateUtil.evaluate(templateData.getValue(), velocityContext)); wxMaSubscribeMessage.addData(wxMaSubscribeData); diff --git a/src/main/java/com/fangxuele/tool/push/logic/msgsender/WxUniformMsgSender.java b/src/main/java/com/fangxuele/tool/push/logic/msgsender/WxUniformMsgSender.java index 5f180c4bd..2c8396edf 100644 --- a/src/main/java/com/fangxuele/tool/push/logic/msgsender/WxUniformMsgSender.java +++ b/src/main/java/com/fangxuele/tool/push/logic/msgsender/WxUniformMsgSender.java @@ -58,9 +58,9 @@ public SendResult send(String[] msgData) { wxMaUniformMessage.setMiniProgram(miniProgram); List wxMaTemplateDataList = Lists.newArrayList(); - List data = wxMaSubscribeMessage.getData(); + List data = wxMaSubscribeMessage.getData(); WxMaTemplateData wxMaTemplateData; - for (WxMaSubscribeMessage.Data datum : data) { + for (WxMaSubscribeMessage.MsgData datum : data) { wxMaTemplateData = new WxMaTemplateData(); wxMaTemplateData.setName(datum.getName()); wxMaTemplateData.setValue(datum.getValue()); diff --git a/src/main/resources/db_init.sql b/src/main/resources/db_init.sql index 3a391ad7b..f60412a5c 100644 --- a/src/main/resources/db_init.sql +++ b/src/main/resources/db_init.sql @@ -292,3 +292,22 @@ create table if not exists t_msg_ma_subscribe create unique index if not exists t_msg_ma_subscribe_msg_type_msg_name_uindex on t_msg_ma_subscribe (msg_type, msg_name); +create table if not exists t_msg_mp_subscribe +( + id integer + constraint t_msg_mp_subscribe_pk + primary key autoincrement, + msg_type integer, + msg_name text, + template_id text, + url text, + ma_appid text, + ma_page_path text, + preview_user text, + wx_account_id int, + create_time datetime, + modified_time datetime +); +create unique index if not exists t_msg_mp_subscribe_msg_type_msg_name_uindex + on t_msg_mp_subscribe (msg_type, msg_name); + diff --git a/src/main/resources/generatorConfig.xml b/src/main/resources/generatorConfig.xml index 6e5ff7f32..12ec56d31 100644 --- a/src/main/resources/generatorConfig.xml +++ b/src/main/resources/generatorConfig.xml @@ -26,26 +26,26 @@ + targetProject="D:\IdeaCProjects\WePush\src\main\java"> + targetProject="D:\IdeaCProjects\WePush\src\main\resources"> + targetProject="D:\IdeaCProjects\WePush\src\main\java"> + tableName="t_msg_mp_subscribe" domainObjectName="TMsgMpSubscribe">
diff --git a/src/main/resources/mapper/TMsgMpSubscribeMapper.xml b/src/main/resources/mapper/TMsgMpSubscribeMapper.xml new file mode 100644 index 000000000..398df3e06 --- /dev/null +++ b/src/main/resources/mapper/TMsgMpSubscribeMapper.xml @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + id, msg_type, msg_name, template_id, url, ma_appid, ma_page_path, preview_user, wx_account_id, + create_time, modified_time + + + + delete from t_msg_mp_subscribe + where id = #{id,jdbcType=INTEGER} + + + insert into t_msg_mp_subscribe (id, msg_type, msg_name, + template_id, url, ma_appid, + ma_page_path, preview_user, wx_account_id, + create_time, modified_time) + values (#{id,jdbcType=INTEGER}, #{msgType,jdbcType=INTEGER}, #{msgName,jdbcType=VARCHAR}, + #{templateId,jdbcType=VARCHAR}, #{url,jdbcType=VARCHAR}, #{maAppid,jdbcType=VARCHAR}, + #{maPagePath,jdbcType=VARCHAR}, #{previewUser,jdbcType=VARCHAR}, #{wxAccountId,jdbcType=INTEGER}, + #{createTime,jdbcType=VARCHAR}, #{modifiedTime,jdbcType=VARCHAR}) + + + insert into t_msg_mp_subscribe + + + id, + + + msg_type, + + + msg_name, + + + template_id, + + + url, + + + ma_appid, + + + ma_page_path, + + + preview_user, + + + wx_account_id, + + + create_time, + + + modified_time, + + + + + #{id,jdbcType=INTEGER}, + + + #{msgType,jdbcType=INTEGER}, + + + #{msgName,jdbcType=VARCHAR}, + + + #{templateId,jdbcType=VARCHAR}, + + + #{url,jdbcType=VARCHAR}, + + + #{maAppid,jdbcType=VARCHAR}, + + + #{maPagePath,jdbcType=VARCHAR}, + + + #{previewUser,jdbcType=VARCHAR}, + + + #{wxAccountId,jdbcType=INTEGER}, + + + #{createTime,jdbcType=VARCHAR}, + + + #{modifiedTime,jdbcType=VARCHAR}, + + + + + update t_msg_mp_subscribe + + + msg_type = #{msgType,jdbcType=INTEGER}, + + + msg_name = #{msgName,jdbcType=VARCHAR}, + + + template_id = #{templateId,jdbcType=VARCHAR}, + + + url = #{url,jdbcType=VARCHAR}, + + + ma_appid = #{maAppid,jdbcType=VARCHAR}, + + + ma_page_path = #{maPagePath,jdbcType=VARCHAR}, + + + preview_user = #{previewUser,jdbcType=VARCHAR}, + + + wx_account_id = #{wxAccountId,jdbcType=INTEGER}, + + + create_time = #{createTime,jdbcType=VARCHAR}, + + + modified_time = #{modifiedTime,jdbcType=VARCHAR}, + + + where id = #{id,jdbcType=INTEGER} + + + update t_msg_mp_subscribe + set msg_type = #{msgType,jdbcType=INTEGER}, + msg_name = #{msgName,jdbcType=VARCHAR}, + template_id = #{templateId,jdbcType=VARCHAR}, + url = #{url,jdbcType=VARCHAR}, + ma_appid = #{maAppid,jdbcType=VARCHAR}, + ma_page_path = #{maPagePath,jdbcType=VARCHAR}, + preview_user = #{previewUser,jdbcType=VARCHAR}, + wx_account_id = #{wxAccountId,jdbcType=INTEGER}, + create_time = #{createTime,jdbcType=VARCHAR}, + modified_time = #{modifiedTime,jdbcType=VARCHAR} + where id = #{id,jdbcType=INTEGER} + + \ No newline at end of file diff --git a/src/main/resources/mybatis-config.xml b/src/main/resources/mybatis-config.xml index 920ef3791..e5e3e920d 100644 --- a/src/main/resources/mybatis-config.xml +++ b/src/main/resources/mybatis-config.xml @@ -31,5 +31,6 @@ + \ No newline at end of file diff --git a/src/main/resources/upgrade/47.sql b/src/main/resources/upgrade/47.sql new file mode 100644 index 000000000..23998d70b --- /dev/null +++ b/src/main/resources/upgrade/47.sql @@ -0,0 +1,18 @@ +create table if not exists t_msg_mp_subscribe +( + id integer + constraint t_msg_mp_subscribe_pk + primary key autoincrement, + msg_type integer, + msg_name text, + template_id text, + url text, + ma_appid text, + ma_page_path text, + preview_user text, + wx_account_id int, + create_time datetime, + modified_time datetime +); +create unique index if not exists t_msg_mp_subscribe_msg_type_msg_name_uindex + on t_msg_mp_subscribe (msg_type, msg_name); \ No newline at end of file From 30463a70512cbed6f63e0f9ba77f2fb8382f0cb2 Mon Sep 17 00:00:00 2001 From: zhoubo58 Date: Tue, 23 Mar 2021 17:10:33 +0800 Subject: [PATCH 03/19] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=85=AC=E4=BC=97?= =?UTF-8?q?=E5=8F=B7=E8=AE=A2=E9=98=85=E9=80=9A=E7=9F=A5-=E9=99=A4?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E6=A8=A1=E6=9D=BF=E5=88=97=E8=A1=A8=E4=BB=A5?= =?UTF-8?q?=E5=A4=96=E5=9D=87=E5=AE=8C=E6=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tool/push/dao/TMsgMpSubscribeMapper.java | 11 + .../tool/push/logic/MessageTypeEnum.java | 7 +- .../tool/push/logic/PushControl.java | 1 + .../push/logic/msgmaker/MsgMakerFactory.java | 3 + .../logic/msgmaker/WxMpSubscribeMsgMaker.java | 94 +++ .../logic/msgsender/MsgSenderFactory.java | 3 + .../msgsender/WxMpSubscribeMsgSender.java | 57 ++ .../tool/push/ui/form/MessageEditForm.java | 19 +- .../tool/push/ui/form/MessageManageForm.java | 36 +- .../tool/push/ui/form/MessageTypeForm.form | 53 +- .../tool/push/ui/form/MessageTypeForm.java | 58 +- .../tool/push/ui/form/ScheduleForm.java | 3 +- .../push/ui/form/msg/MpSubscribeMsgForm.form | 235 ++++++++ .../push/ui/form/msg/MpSubscribeMsgForm.java | 570 ++++++++++++++++++ .../tool/push/ui/form/msg/MsgFormFactory.java | 3 + .../tool/push/ui/listener/MemberListener.java | 3 +- .../push/ui/listener/MessageEditListener.java | 2 +- .../ui/listener/MessageManageListener.java | 17 +- .../push/ui/listener/MessageTypeListener.java | 4 + .../mapper/TMsgMpSubscribeMapper.xml | 336 ++++++----- 20 files changed, 1263 insertions(+), 252 deletions(-) create mode 100644 src/main/java/com/fangxuele/tool/push/logic/msgmaker/WxMpSubscribeMsgMaker.java create mode 100644 src/main/java/com/fangxuele/tool/push/logic/msgsender/WxMpSubscribeMsgSender.java create mode 100644 src/main/java/com/fangxuele/tool/push/ui/form/msg/MpSubscribeMsgForm.form create mode 100644 src/main/java/com/fangxuele/tool/push/ui/form/msg/MpSubscribeMsgForm.java diff --git a/src/main/java/com/fangxuele/tool/push/dao/TMsgMpSubscribeMapper.java b/src/main/java/com/fangxuele/tool/push/dao/TMsgMpSubscribeMapper.java index 5f3ac4a86..2c558c184 100644 --- a/src/main/java/com/fangxuele/tool/push/dao/TMsgMpSubscribeMapper.java +++ b/src/main/java/com/fangxuele/tool/push/dao/TMsgMpSubscribeMapper.java @@ -1,6 +1,9 @@ package com.fangxuele.tool.push.dao; import com.fangxuele.tool.push.domain.TMsgMpSubscribe; +import org.apache.ibatis.annotations.Param; + +import java.util.List; public interface TMsgMpSubscribeMapper { int deleteByPrimaryKey(Integer id); @@ -14,4 +17,12 @@ public interface TMsgMpSubscribeMapper { int updateByPrimaryKeySelective(TMsgMpSubscribe record); int updateByPrimaryKey(TMsgMpSubscribe record); + + List selectByMsgTypeAndWxAccountId(@Param("msgType") int msgType, @Param("wxAccountId") Integer wxAccountId); + + int deleteByMsgTypeAndName(int msgType, String msgName); + + List selectByMsgTypeAndMsgName(@Param("msgType") int msgType, @Param("msgName") String msgName); + + int updateByMsgTypeAndMsgName(TMsgMpSubscribe tMsgMpSubscribe); } \ No newline at end of file diff --git a/src/main/java/com/fangxuele/tool/push/logic/MessageTypeEnum.java b/src/main/java/com/fangxuele/tool/push/logic/MessageTypeEnum.java index 0c2444513..b1d1caa8d 100644 --- a/src/main/java/com/fangxuele/tool/push/logic/MessageTypeEnum.java +++ b/src/main/java/com/fangxuele/tool/push/logic/MessageTypeEnum.java @@ -28,7 +28,8 @@ public enum MessageTypeEnum { BD_YUN(15, "百度云短信"), QI_NIU_YUN(16, "七牛云短信"), WX_UNIFORM_MESSAGE(17, "小程序-统一服务消息"), - MA_SUBSCRIBE(18, "小程序-订阅消息"); + MA_SUBSCRIBE(18, "小程序-订阅消息"), + MP_SUBSCRIBE(19, "公众号-订阅通知"); private int code; @@ -51,6 +52,7 @@ public enum MessageTypeEnum { public static final int QI_NIU_YUN_CODE = 16; public static final int WX_UNIFORM_MESSAGE_CODE = 17; public static final int MA_SUBSCRIBE_CODE = 18; + public static final int MP_SUBSCRIBE_CODE = 19; MessageTypeEnum(int code, String name) { this.code = code; @@ -111,6 +113,9 @@ public static String getName(int code) { case 18: name = MA_SUBSCRIBE.name; break; + case 19: + name = MP_SUBSCRIBE.name; + break; default: name = ""; } diff --git a/src/main/java/com/fangxuele/tool/push/logic/PushControl.java b/src/main/java/com/fangxuele/tool/push/logic/PushControl.java index 11643e4b3..52fb4488d 100644 --- a/src/main/java/com/fangxuele/tool/push/logic/PushControl.java +++ b/src/main/java/com/fangxuele/tool/push/logic/PushControl.java @@ -144,6 +144,7 @@ public static boolean configCheck() { int msgType = App.config.getMsgType(); switch (msgType) { case MessageTypeEnum.MP_TEMPLATE_CODE: + case MessageTypeEnum.MP_SUBSCRIBE_CODE: case MessageTypeEnum.KEFU_CODE: case MessageTypeEnum.KEFU_PRIORITY_CODE: case MessageTypeEnum.WX_UNIFORM_MESSAGE_CODE: { diff --git a/src/main/java/com/fangxuele/tool/push/logic/msgmaker/MsgMakerFactory.java b/src/main/java/com/fangxuele/tool/push/logic/msgmaker/MsgMakerFactory.java index 3a06042b4..89a7b3b2b 100644 --- a/src/main/java/com/fangxuele/tool/push/logic/msgmaker/MsgMakerFactory.java +++ b/src/main/java/com/fangxuele/tool/push/logic/msgmaker/MsgMakerFactory.java @@ -63,6 +63,9 @@ public static IMsgMaker getMsgMaker() { case MessageTypeEnum.QI_NIU_YUN_CODE: iMsgMaker = new QiNiuYunMsgMaker(); break; + case MessageTypeEnum.MP_SUBSCRIBE_CODE: + iMsgMaker = new WxMpSubscribeMsgMaker(); + break; default: } return iMsgMaker; diff --git a/src/main/java/com/fangxuele/tool/push/logic/msgmaker/WxMpSubscribeMsgMaker.java b/src/main/java/com/fangxuele/tool/push/logic/msgmaker/WxMpSubscribeMsgMaker.java new file mode 100644 index 000000000..f22ae0ec7 --- /dev/null +++ b/src/main/java/com/fangxuele/tool/push/logic/msgmaker/WxMpSubscribeMsgMaker.java @@ -0,0 +1,94 @@ +package com.fangxuele.tool.push.logic.msgmaker; + +import com.fangxuele.tool.push.bean.TemplateData; +import com.fangxuele.tool.push.ui.form.msg.MpSubscribeMsgForm; +import com.fangxuele.tool.push.util.TemplateUtil; +import me.chanjar.weixin.mp.bean.subscribe.WxMpSubscribeMessage; +import org.apache.commons.compress.utils.Lists; +import org.apache.velocity.VelocityContext; + +import javax.swing.table.DefaultTableModel; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + *
+ * 公众号订阅通知加工器
+ * 
+ * + * @author Zhou Bo + * @since 2021/3/23. + */ +public class WxMpSubscribeMsgMaker extends BaseMsgMaker implements IMsgMaker { + + public static String templateId; + + private static String templateUrl; + + private static String miniAppId; + + private static String miniAppPagePath; + + public static List templateDataList; + + /** + * 准备(界面字段等) + */ + @Override + public void prepare() { + templateId = MpSubscribeMsgForm.getInstance().getMsgTemplateIdTextField().getText().trim(); + templateUrl = MpSubscribeMsgForm.getInstance().getMsgTemplateUrlTextField().getText().trim(); + miniAppId = MpSubscribeMsgForm.getInstance().getMsgTemplateMiniAppidTextField().getText().trim(); + miniAppPagePath = MpSubscribeMsgForm.getInstance().getMsgTemplateMiniPagePathTextField().getText().trim(); + + if (MpSubscribeMsgForm.getInstance().getTemplateMsgDataTable().getModel().getRowCount() == 0) { + MpSubscribeMsgForm.initTemplateDataTable(); + } + + DefaultTableModel tableModel = (DefaultTableModel) MpSubscribeMsgForm.getInstance().getTemplateMsgDataTable().getModel(); + int rowCount = tableModel.getRowCount(); + TemplateData templateData; + templateDataList = Lists.newArrayList(); + for (int i = 0; i < rowCount; i++) { + String name = ((String) tableModel.getValueAt(i, 0)).trim(); + String value = ((String) tableModel.getValueAt(i, 1)).trim(); + String color = ((String) tableModel.getValueAt(i, 2)).trim(); + templateData = new TemplateData(); + templateData.setName(name); + templateData.setValue(value); + templateData.setColor(color); + templateDataList.add(templateData); + } + + } + + /** + * 组织订阅通知-公众号 + * + * @param msgData 消息数据 + * @return WxMpSubscribeMessage + */ + @Override + public WxMpSubscribeMessage makeMsg(String[] msgData) { + // 拼模板 + WxMpSubscribeMessage wxMessageTemplate = new WxMpSubscribeMessage(); + wxMessageTemplate.setTemplateId(templateId); + + VelocityContext velocityContext = getVelocityContext(msgData); + String templateUrlEvaluated = TemplateUtil.evaluate(templateUrl, velocityContext); + wxMessageTemplate.setUrl(templateUrlEvaluated); + String miniAppPagePathEvaluated = TemplateUtil.evaluate(miniAppPagePath, velocityContext); + WxMpSubscribeMessage.MiniProgram miniProgram = new WxMpSubscribeMessage.MiniProgram(miniAppId, miniAppPagePathEvaluated, false); + wxMessageTemplate.setMiniProgram(miniProgram); + + Map dataMap = new HashMap<>(10); + for (TemplateData templateData : templateDataList) { + dataMap.put(templateData.getName(), TemplateUtil.evaluate(templateData.getValue(), velocityContext)); + } + + wxMessageTemplate.setDataMap(dataMap); + + return wxMessageTemplate; + } +} diff --git a/src/main/java/com/fangxuele/tool/push/logic/msgsender/MsgSenderFactory.java b/src/main/java/com/fangxuele/tool/push/logic/msgsender/MsgSenderFactory.java index a1543753f..383d79c81 100644 --- a/src/main/java/com/fangxuele/tool/push/logic/msgsender/MsgSenderFactory.java +++ b/src/main/java/com/fangxuele/tool/push/logic/msgsender/MsgSenderFactory.java @@ -69,6 +69,9 @@ public static IMsgSender getMsgSender() { case MessageTypeEnum.QI_NIU_YUN_CODE: iMsgSender = new QiNiuYunMsgSender(); break; + case MessageTypeEnum.MP_SUBSCRIBE_CODE: + iMsgSender = new WxMpSubscribeMsgSender(); + break; default: break; } diff --git a/src/main/java/com/fangxuele/tool/push/logic/msgsender/WxMpSubscribeMsgSender.java b/src/main/java/com/fangxuele/tool/push/logic/msgsender/WxMpSubscribeMsgSender.java new file mode 100644 index 000000000..ad67b170b --- /dev/null +++ b/src/main/java/com/fangxuele/tool/push/logic/msgsender/WxMpSubscribeMsgSender.java @@ -0,0 +1,57 @@ +package com.fangxuele.tool.push.logic.msgsender; + +import com.fangxuele.tool.push.logic.PushControl; +import com.fangxuele.tool.push.logic.msgmaker.WxMpSubscribeMsgMaker; +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.subscribe.WxMpSubscribeMessage; +import org.apache.commons.lang3.exception.ExceptionUtils; + +/** + *
+ * 微信公众号订阅通知发送器
+ * 
+ * + * @author RememBerBer + * @since 2021/3/23. + */ +@Slf4j +public class WxMpSubscribeMsgSender implements IMsgSender { + public volatile static WxMpService wxMpService; + private WxMpSubscribeMsgMaker wxMpSubscribeMsgMaker; + + public WxMpSubscribeMsgSender() { + wxMpSubscribeMsgMaker = new WxMpSubscribeMsgMaker(); + wxMpService = WxMpTemplateMsgSender.getWxMpService(); + } + + @Override + public SendResult send(String[] msgData) { + SendResult sendResult = new SendResult(); + + try { + String openId = msgData[0]; + WxMpSubscribeMessage wxMessageTemplate = wxMpSubscribeMsgMaker.makeMsg(msgData); + wxMessageTemplate.setToUser(openId); + if (PushControl.dryRun) { + sendResult.setSuccess(true); + return sendResult; + } else { + wxMpService.getSubscribeMsgService().send(wxMessageTemplate); + } + } catch (Exception e) { + sendResult.setSuccess(false); + sendResult.setInfo(e.getMessage()); + log.error(ExceptionUtils.getStackTrace(e)); + return sendResult; + } + + sendResult.setSuccess(true); + return sendResult; + } + + @Override + public SendResult asyncSend(String[] msgData) { + return null; + } +} diff --git a/src/main/java/com/fangxuele/tool/push/ui/form/MessageEditForm.java b/src/main/java/com/fangxuele/tool/push/ui/form/MessageEditForm.java index 93263e7e6..2275ac60f 100644 --- a/src/main/java/com/fangxuele/tool/push/ui/form/MessageEditForm.java +++ b/src/main/java/com/fangxuele/tool/push/ui/form/MessageEditForm.java @@ -1,21 +1,7 @@ package com.fangxuele.tool.push.ui.form; import com.fangxuele.tool.push.logic.MessageTypeEnum; -import com.fangxuele.tool.push.ui.form.msg.AliYunMsgForm; -import com.fangxuele.tool.push.ui.form.msg.BdYunMsgForm; -import com.fangxuele.tool.push.ui.form.msg.DingMsgForm; -import com.fangxuele.tool.push.ui.form.msg.HttpMsgForm; -import com.fangxuele.tool.push.ui.form.msg.HwYunMsgForm; -import com.fangxuele.tool.push.ui.form.msg.KefuMsgForm; -import com.fangxuele.tool.push.ui.form.msg.MaSubscribeMsgForm; -import com.fangxuele.tool.push.ui.form.msg.MailMsgForm; -import com.fangxuele.tool.push.ui.form.msg.MpTemplateMsgForm; -import com.fangxuele.tool.push.ui.form.msg.MsgFormFactory; -import com.fangxuele.tool.push.ui.form.msg.QiNiuYunMsgForm; -import com.fangxuele.tool.push.ui.form.msg.TxYunMsgForm; -import com.fangxuele.tool.push.ui.form.msg.UpYunMsgForm; -import com.fangxuele.tool.push.ui.form.msg.WxCpMsgForm; -import com.fangxuele.tool.push.ui.form.msg.YunpianMsgForm; +import com.fangxuele.tool.push.ui.form.msg.*; import com.fangxuele.tool.push.util.UndoUtil; import com.intellij.uiDesigner.core.GridConstraints; import com.intellij.uiDesigner.core.GridLayoutManager; @@ -90,6 +76,9 @@ public static void switchMsgType(int msgType) { case MessageTypeEnum.MP_TEMPLATE_CODE: messageEditForm.getMsgEditorPanel().add(MpTemplateMsgForm.getInstance().getTemplateMsgPanel(), gridConstraintsRow0); break; + case MessageTypeEnum.MP_SUBSCRIBE_CODE: + messageEditForm.getMsgEditorPanel().add(MpSubscribeMsgForm.getInstance().getTemplateMsgPanel(), gridConstraintsRow0); + break; case MessageTypeEnum.MA_TEMPLATE_CODE: case MessageTypeEnum.MA_SUBSCRIBE_CODE: messageEditForm.getMsgEditorPanel().add(MaSubscribeMsgForm.getInstance().getTemplateMsgPanel(), gridConstraintsRow0); diff --git a/src/main/java/com/fangxuele/tool/push/ui/form/MessageManageForm.java b/src/main/java/com/fangxuele/tool/push/ui/form/MessageManageForm.java index f0e4af8ad..0e39ff839 100644 --- a/src/main/java/com/fangxuele/tool/push/ui/form/MessageManageForm.java +++ b/src/main/java/com/fangxuele/tool/push/ui/form/MessageManageForm.java @@ -1,30 +1,8 @@ package com.fangxuele.tool.push.ui.form; import com.fangxuele.tool.push.App; -import com.fangxuele.tool.push.dao.TMsgDingMapper; -import com.fangxuele.tool.push.dao.TMsgHttpMapper; -import com.fangxuele.tool.push.dao.TMsgKefuMapper; -import com.fangxuele.tool.push.dao.TMsgKefuPriorityMapper; -import com.fangxuele.tool.push.dao.TMsgMaSubscribeMapper; -import com.fangxuele.tool.push.dao.TMsgMaTemplateMapper; -import com.fangxuele.tool.push.dao.TMsgMailMapper; -import com.fangxuele.tool.push.dao.TMsgMpTemplateMapper; -import com.fangxuele.tool.push.dao.TMsgSmsMapper; -import com.fangxuele.tool.push.dao.TMsgWxCpMapper; -import com.fangxuele.tool.push.dao.TMsgWxUniformMapper; -import com.fangxuele.tool.push.dao.TWxAccountMapper; -import com.fangxuele.tool.push.domain.TMsgDing; -import com.fangxuele.tool.push.domain.TMsgHttp; -import com.fangxuele.tool.push.domain.TMsgKefu; -import com.fangxuele.tool.push.domain.TMsgKefuPriority; -import com.fangxuele.tool.push.domain.TMsgMaSubscribe; -import com.fangxuele.tool.push.domain.TMsgMaTemplate; -import com.fangxuele.tool.push.domain.TMsgMail; -import com.fangxuele.tool.push.domain.TMsgMpTemplate; -import com.fangxuele.tool.push.domain.TMsgSms; -import com.fangxuele.tool.push.domain.TMsgWxCp; -import com.fangxuele.tool.push.domain.TMsgWxUniform; -import com.fangxuele.tool.push.domain.TWxAccount; +import com.fangxuele.tool.push.dao.*; +import com.fangxuele.tool.push.domain.*; import com.fangxuele.tool.push.logic.MessageTypeEnum; import com.fangxuele.tool.push.ui.UiConsts; import com.fangxuele.tool.push.util.JTableUtil; @@ -65,6 +43,7 @@ public class MessageManageForm { private static TMsgMaTemplateMapper msgMaTemplateMapper = MybatisUtil.getSqlSession().getMapper(TMsgMaTemplateMapper.class); private static TMsgMaSubscribeMapper msgMaSubscribeMapper = MybatisUtil.getSqlSession().getMapper(TMsgMaSubscribeMapper.class); private static TMsgMpTemplateMapper msgMpTemplateMapper = MybatisUtil.getSqlSession().getMapper(TMsgMpTemplateMapper.class); + private static TMsgMpSubscribeMapper msgMpSubscribeMapper = MybatisUtil.getSqlSession().getMapper(TMsgMpSubscribeMapper.class); private static TMsgSmsMapper msgSmsMapper = MybatisUtil.getSqlSession().getMapper(TMsgSmsMapper.class); private static TMsgMailMapper msgMailMapper = MybatisUtil.getSqlSession().getMapper(TMsgMailMapper.class); private static TMsgWxCpMapper msgWxCpMapper = MybatisUtil.getSqlSession().getMapper(TMsgWxCpMapper.class); @@ -157,6 +136,14 @@ public static void initMessageList() { model.addRow(data); } break; + case MessageTypeEnum.MP_SUBSCRIBE_CODE: + List tMsgMpSubscribeList = msgMpSubscribeMapper.selectByMsgTypeAndWxAccountId(msgType, wxAccountId); + for (TMsgMpSubscribe tMsgMpSubscribe : tMsgMpSubscribeList) { + data = new Object[1]; + data[0] = tMsgMpSubscribe.getMsgName(); + model.addRow(data); + } + break; case MessageTypeEnum.EMAIL_CODE: List tMsgMailList = msgMailMapper.selectByMsgType(msgType); for (TMsgMail tMsgMail : tMsgMailList) { @@ -210,6 +197,7 @@ public static void initSwitchMultiAccount() { switch (msgType) { case MessageTypeEnum.MP_TEMPLATE_CODE: + case MessageTypeEnum.MP_SUBSCRIBE_CODE: case MessageTypeEnum.KEFU_CODE: case MessageTypeEnum.KEFU_PRIORITY_CODE: // 多账号切换-公众号 diff --git a/src/main/java/com/fangxuele/tool/push/ui/form/MessageTypeForm.form b/src/main/java/com/fangxuele/tool/push/ui/form/MessageTypeForm.form index 0a61b8c9e..edd8953b1 100644 --- a/src/main/java/com/fangxuele/tool/push/ui/form/MessageTypeForm.form +++ b/src/main/java/com/fangxuele/tool/push/ui/form/MessageTypeForm.form @@ -19,7 +19,7 @@ - + @@ -36,10 +36,19 @@
- + + + + + + + + + + @@ -47,7 +56,7 @@ - + @@ -55,7 +64,7 @@ - + @@ -63,7 +72,7 @@ - + @@ -72,7 +81,7 @@ - + @@ -80,7 +89,7 @@ - + @@ -88,7 +97,7 @@ - + @@ -96,7 +105,7 @@ - + @@ -105,7 +114,7 @@ - + @@ -114,7 +123,7 @@ - + @@ -123,7 +132,7 @@ - + @@ -132,7 +141,7 @@ - + @@ -141,7 +150,7 @@ - + @@ -150,7 +159,7 @@ - + @@ -159,7 +168,7 @@ - + @@ -182,7 +191,7 @@ - + @@ -191,7 +200,7 @@ - + @@ -200,7 +209,7 @@ - + @@ -209,7 +218,7 @@ - + @@ -218,7 +227,7 @@ - + @@ -227,7 +236,7 @@ - + diff --git a/src/main/java/com/fangxuele/tool/push/ui/form/MessageTypeForm.java b/src/main/java/com/fangxuele/tool/push/ui/form/MessageTypeForm.java index b2b01ec59..2928ad7e1 100644 --- a/src/main/java/com/fangxuele/tool/push/ui/form/MessageTypeForm.java +++ b/src/main/java/com/fangxuele/tool/push/ui/form/MessageTypeForm.java @@ -46,6 +46,7 @@ public class MessageTypeForm { private JRadioButton bdYunRadioButton; private JRadioButton wxUniformMessageRadioButton; private JRadioButton maSubscribeRadioButton; + private JRadioButton mpSubscribeRadioButton; private static MessageTypeForm messageTypeForm; @@ -75,6 +76,9 @@ public static void init() { case MessageTypeEnum.MP_TEMPLATE_CODE: messageTypeForm.getMpTemplateRadioButton().setSelected(true); break; + case MessageTypeEnum.MP_SUBSCRIBE_CODE: + messageTypeForm.getMpSubscribeRadioButton().setSelected(true); + break; case MessageTypeEnum.MA_TEMPLATE_CODE: messageTypeForm.getMaTemplateRadioButton().setSelected(true); break; @@ -140,7 +144,8 @@ public static void init() { private static void initMessageManageFormLayOut(int msgType) { if (msgType == MessageTypeEnum.KEFU_CODE || msgType == MessageTypeEnum.KEFU_PRIORITY_CODE || msgType == MessageTypeEnum.MP_TEMPLATE_CODE - || msgType == MessageTypeEnum.MA_TEMPLATE_CODE || msgType == MessageTypeEnum.MA_SUBSCRIBE_CODE || msgType == MessageTypeEnum.WX_UNIFORM_MESSAGE_CODE) { + || msgType == MessageTypeEnum.MA_TEMPLATE_CODE || msgType == MessageTypeEnum.MA_SUBSCRIBE_CODE + || msgType == MessageTypeEnum.WX_UNIFORM_MESSAGE_CODE || msgType == MessageTypeEnum.MP_SUBSCRIBE_CODE) { MessageManageForm.getInstance().getAccountSwitchPanel().setVisible(true); } else { MessageManageForm.getInstance().getAccountSwitchPanel().setVisible(false); @@ -168,7 +173,8 @@ private static void initMemberFormLayOut(int msgType) { MemberForm.getInstance().getMemberTabCenterPanel().setVisible(true); if (msgType == MessageTypeEnum.MP_TEMPLATE_CODE || msgType == MessageTypeEnum.MA_TEMPLATE_CODE || msgType == MessageTypeEnum.KEFU_CODE || msgType == MessageTypeEnum.KEFU_PRIORITY_CODE - || msgType == MessageTypeEnum.WX_UNIFORM_MESSAGE_CODE || msgType == MessageTypeEnum.MA_SUBSCRIBE_CODE) { + || msgType == MessageTypeEnum.WX_UNIFORM_MESSAGE_CODE || msgType == MessageTypeEnum.MA_SUBSCRIBE_CODE + || msgType == MessageTypeEnum.MP_SUBSCRIBE_CODE) { MemberForm.getInstance().getImportFromWeixinPanel().setVisible(true); MemberForm.getInstance().getImportOptionPanel().setVisible(true); } @@ -227,68 +233,72 @@ public static void clearAllSelected() { messageTypeScrollPane.setAutoscrolls(true); messageTypePanel.add(messageTypeScrollPane, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false)); msgTypeListPanel = new JPanel(); - msgTypeListPanel.setLayout(new GridLayoutManager(22, 3, new Insets(20, 20, 0, 0), -1, -1)); + msgTypeListPanel.setLayout(new GridLayoutManager(23, 3, new Insets(20, 20, 0, 0), -1, -1)); msgTypeListPanel.setAutoscrolls(true); messageTypeScrollPane.setViewportView(msgTypeListPanel); mpTemplateRadioButton = new JRadioButton(); mpTemplateRadioButton.setEnabled(true); mpTemplateRadioButton.setText("公众号-模板消息"); msgTypeListPanel.add(mpTemplateRadioButton, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + mpSubscribeRadioButton = new JRadioButton(); + mpSubscribeRadioButton.setEnabled(true); + mpSubscribeRadioButton.setText("公众号-订阅通知"); + msgTypeListPanel.add(mpSubscribeRadioButton, new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); maTemplateRadioButton = new JRadioButton(); maTemplateRadioButton.setEnabled(false); maTemplateRadioButton.setText("小程序-模板消息"); - msgTypeListPanel.add(maTemplateRadioButton, new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + msgTypeListPanel.add(maTemplateRadioButton, new GridConstraints(3, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); maSubscribeRadioButton = new JRadioButton(); maSubscribeRadioButton.setText("小程序-订阅消息"); - msgTypeListPanel.add(maSubscribeRadioButton, new GridConstraints(3, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + msgTypeListPanel.add(maSubscribeRadioButton, new GridConstraints(4, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); kefuRadioButton = new JRadioButton(); kefuRadioButton.setText("公众号-客服消息"); - msgTypeListPanel.add(kefuRadioButton, new GridConstraints(4, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + msgTypeListPanel.add(kefuRadioButton, new GridConstraints(5, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); kefuPriorityRadioButton = new JRadioButton(); kefuPriorityRadioButton.setText("公众号-客服消息优先"); kefuPriorityRadioButton.setToolTipText("优先尝试发送客服消息,如果失败则发送模板消息"); - msgTypeListPanel.add(kefuPriorityRadioButton, new GridConstraints(5, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + msgTypeListPanel.add(kefuPriorityRadioButton, new GridConstraints(6, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); aliYunRadioButton = new JRadioButton(); aliYunRadioButton.setText("阿里云短信"); - msgTypeListPanel.add(aliYunRadioButton, new GridConstraints(9, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + msgTypeListPanel.add(aliYunRadioButton, new GridConstraints(10, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); txYunRadioButton = new JRadioButton(); txYunRadioButton.setText("腾讯云短信"); - msgTypeListPanel.add(txYunRadioButton, new GridConstraints(10, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + msgTypeListPanel.add(txYunRadioButton, new GridConstraints(11, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); yunPianRadioButton = new JRadioButton(); yunPianRadioButton.setText("云片网短信"); - msgTypeListPanel.add(yunPianRadioButton, new GridConstraints(13, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + msgTypeListPanel.add(yunPianRadioButton, new GridConstraints(14, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); 网易云信短信RadioButton = new JRadioButton(); 网易云信短信RadioButton.setEnabled(false); 网易云信短信RadioButton.setText("网易云信短信"); - msgTypeListPanel.add(网易云信短信RadioButton, new GridConstraints(17, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + msgTypeListPanel.add(网易云信短信RadioButton, new GridConstraints(18, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); 榛子云短信RadioButton = new JRadioButton(); 榛子云短信RadioButton.setEnabled(false); 榛子云短信RadioButton.setText("榛子云短信"); - msgTypeListPanel.add(榛子云短信RadioButton, new GridConstraints(18, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + msgTypeListPanel.add(榛子云短信RadioButton, new GridConstraints(19, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); luosimao短信RadioButton = new JRadioButton(); luosimao短信RadioButton.setEnabled(false); luosimao短信RadioButton.setText("Luosimao短信"); - msgTypeListPanel.add(luosimao短信RadioButton, new GridConstraints(19, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + msgTypeListPanel.add(luosimao短信RadioButton, new GridConstraints(20, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); 极光短信RadioButton = new JRadioButton(); 极光短信RadioButton.setEnabled(false); 极光短信RadioButton.setText("极光短信"); - msgTypeListPanel.add(极光短信RadioButton, new GridConstraints(20, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + msgTypeListPanel.add(极光短信RadioButton, new GridConstraints(21, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); 极光推送RadioButton = new JRadioButton(); 极光推送RadioButton.setEnabled(false); 极光推送RadioButton.setText("极光推送"); - msgTypeListPanel.add(极光推送RadioButton, new GridConstraints(21, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + msgTypeListPanel.add(极光推送RadioButton, new GridConstraints(22, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); kefuPriorityTipsLabel = new JLabel(); kefuPriorityTipsLabel.setIcon(new ImageIcon(getClass().getResource("/icon/helpButton.png"))); kefuPriorityTipsLabel.setText(""); - msgTypeListPanel.add(kefuPriorityTipsLabel, new GridConstraints(5, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + msgTypeListPanel.add(kefuPriorityTipsLabel, new GridConstraints(6, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); eMailRadioButton = new JRadioButton(); eMailRadioButton.setEnabled(true); eMailRadioButton.setText("E-Mail(BETA)"); - msgTypeListPanel.add(eMailRadioButton, new GridConstraints(16, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + msgTypeListPanel.add(eMailRadioButton, new GridConstraints(17, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); wxCpRadioButton = new JRadioButton(); wxCpRadioButton.setEnabled(true); wxCpRadioButton.setText("企业号/企业微信"); - msgTypeListPanel.add(wxCpRadioButton, new GridConstraints(7, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + msgTypeListPanel.add(wxCpRadioButton, new GridConstraints(8, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); httpRadioButton = new JRadioButton(); httpRadioButton.setEnabled(true); httpRadioButton.setText("HTTP请求"); @@ -298,26 +308,26 @@ public static void clearAllSelected() { dingRadioButton = new JRadioButton(); dingRadioButton.setEnabled(true); dingRadioButton.setText("钉钉"); - msgTypeListPanel.add(dingRadioButton, new GridConstraints(8, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + msgTypeListPanel.add(dingRadioButton, new GridConstraints(9, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); hwYunRadioButton = new JRadioButton(); hwYunRadioButton.setEnabled(true); hwYunRadioButton.setText("华为云短信(BETA)"); - msgTypeListPanel.add(hwYunRadioButton, new GridConstraints(11, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + msgTypeListPanel.add(hwYunRadioButton, new GridConstraints(12, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); bdYunRadioButton = new JRadioButton(); bdYunRadioButton.setEnabled(true); bdYunRadioButton.setText("百度云短信(BETA)"); - msgTypeListPanel.add(bdYunRadioButton, new GridConstraints(12, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + msgTypeListPanel.add(bdYunRadioButton, new GridConstraints(13, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); upYunRadioButton = new JRadioButton(); upYunRadioButton.setEnabled(true); upYunRadioButton.setText("又拍云短信(BETA)"); - msgTypeListPanel.add(upYunRadioButton, new GridConstraints(14, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + msgTypeListPanel.add(upYunRadioButton, new GridConstraints(15, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); qiniuRadioButton = new JRadioButton(); qiniuRadioButton.setEnabled(true); qiniuRadioButton.setText("七牛云短信(BETA)"); - msgTypeListPanel.add(qiniuRadioButton, new GridConstraints(15, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + msgTypeListPanel.add(qiniuRadioButton, new GridConstraints(16, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); wxUniformMessageRadioButton = new JRadioButton(); wxUniformMessageRadioButton.setText("小程序-统一服务消息(BETA)"); - msgTypeListPanel.add(wxUniformMessageRadioButton, new GridConstraints(6, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + msgTypeListPanel.add(wxUniformMessageRadioButton, new GridConstraints(7, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); final JPanel panel1 = new JPanel(); panel1.setLayout(new GridLayoutManager(2, 1, new Insets(8, 8, 8, 0), -1, -1)); messageTypePanel.add(panel1, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); diff --git a/src/main/java/com/fangxuele/tool/push/ui/form/ScheduleForm.java b/src/main/java/com/fangxuele/tool/push/ui/form/ScheduleForm.java index 9a85c04ca..de70a4d65 100644 --- a/src/main/java/com/fangxuele/tool/push/ui/form/ScheduleForm.java +++ b/src/main/java/com/fangxuele/tool/push/ui/form/ScheduleForm.java @@ -92,7 +92,8 @@ public static void fillReimportComboBox() { int msgType = App.config.getMsgType(); if (msgType == MessageTypeEnum.MP_TEMPLATE_CODE || msgType == MessageTypeEnum.MA_TEMPLATE_CODE || msgType == MessageTypeEnum.KEFU_CODE || msgType == MessageTypeEnum.KEFU_PRIORITY_CODE - || msgType == MessageTypeEnum.WX_UNIFORM_MESSAGE_CODE || msgType == MessageTypeEnum.MA_SUBSCRIBE_CODE) { + || msgType == MessageTypeEnum.WX_UNIFORM_MESSAGE_CODE || msgType == MessageTypeEnum.MA_SUBSCRIBE_CODE + || msgType == MessageTypeEnum.MP_SUBSCRIBE_CODE) { scheduleForm.getReimportComboBox().addItem("导入所有关注公众号的用户"); scheduleForm.getReimportComboBox().addItem("导入选择的标签分组"); scheduleForm.getReimportComboBox().addItem("导入选择的标签分组-取并集"); diff --git a/src/main/java/com/fangxuele/tool/push/ui/form/msg/MpSubscribeMsgForm.form b/src/main/java/com/fangxuele/tool/push/ui/form/msg/MpSubscribeMsgForm.form new file mode 100644 index 000000000..7a885ead0 --- /dev/null +++ b/src/main/java/com/fangxuele/tool/push/ui/form/msg/MpSubscribeMsgForm.form @@ -0,0 +1,235 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/fangxuele/tool/push/ui/form/msg/MpSubscribeMsgForm.java b/src/main/java/com/fangxuele/tool/push/ui/form/msg/MpSubscribeMsgForm.java new file mode 100644 index 000000000..a324b525e --- /dev/null +++ b/src/main/java/com/fangxuele/tool/push/ui/form/msg/MpSubscribeMsgForm.java @@ -0,0 +1,570 @@ +package com.fangxuele.tool.push.ui.form.msg; + +import com.fangxuele.tool.push.App; +import com.fangxuele.tool.push.dao.TMsgMpSubscribeMapper; +import com.fangxuele.tool.push.dao.TTemplateDataMapper; +import com.fangxuele.tool.push.domain.TMsgMpSubscribe; +import com.fangxuele.tool.push.domain.TTemplateData; +import com.fangxuele.tool.push.logic.MessageTypeEnum; +import com.fangxuele.tool.push.logic.msgsender.WxMpTemplateMsgSender; +import com.fangxuele.tool.push.ui.component.TableInCellButtonColumn; +import com.fangxuele.tool.push.ui.form.MainWindow; +import com.fangxuele.tool.push.ui.form.MessageEditForm; +import com.fangxuele.tool.push.util.MybatisUtil; +import com.fangxuele.tool.push.util.SqliteUtil; +import com.fangxuele.tool.push.util.UIUtil; +import com.google.common.collect.Maps; +import com.intellij.uiDesigner.core.GridConstraints; +import com.intellij.uiDesigner.core.GridLayoutManager; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.mp.bean.template.WxMpTemplate; +import org.apache.commons.compress.utils.Lists; +import org.apache.commons.lang3.StringUtils; + +import javax.swing.*; +import javax.swing.border.TitledBorder; +import javax.swing.plaf.FontUIResource; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableColumnModel; +import javax.swing.text.StyleContext; +import java.awt.*; +import java.awt.event.ItemEvent; +import java.util.List; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + *
+ * MpSubscribeMsgForm
+ * 
+ * + * @author Zhou Bo + * @since 2021/3/23. + */ +@Getter +@Slf4j +public class MpSubscribeMsgForm implements IMsgForm { + private JPanel templateMsgPanel; + private JLabel templateIdLabel; + private JTextField msgTemplateIdTextField; + private JLabel templateUrlLabel; + private JTextField msgTemplateUrlTextField; + private JPanel templateMsgDataPanel; + private JLabel templateMiniProgramAppidLabel; + private JTextField msgTemplateMiniAppidTextField; + private JLabel templateMiniProgramPagePathLabel; + private JTextField msgTemplateMiniPagePathTextField; + private JLabel templateMsgNameLabel; + private JTextField templateDataNameTextField; + private JLabel templateMsgValueLabel; + private JTextField templateDataValueTextField; + private JLabel templateMsgColorLabel; + private JTextField templateDataColorTextField; + private JButton templateMsgDataAddButton; + private JTable templateMsgDataTable; + private JComboBox templateListComboBox; + private JButton refreshTemplateListButton; + private JButton autoFillButton; + private JTextArea templateContentTextArea; + + private static MpSubscribeMsgForm mpSubscribeMsgForm; + + private static TMsgMpSubscribeMapper tMsgMpSubscribeMapper = MybatisUtil.getSqlSession().getMapper(TMsgMpSubscribeMapper.class); + + private static TTemplateDataMapper templateDataMapper = MybatisUtil.getSqlSession().getMapper(TTemplateDataMapper.class); + + /** + * 账号模板列表 + */ + public static List templateList; + + /** + * 模板账号map,key:templateId + */ + public static Map templateMap; + + /** + * (左侧列表中)所选消息对应的模板ID + */ + public static String selectedMsgTemplateId; + + /** + * 是否需要监听模板列表ComboBox + */ + public static boolean needListenTemplateListComboBox = false; + + private static final Pattern BRACE_PATTERN = Pattern.compile("\\{([^{}]+)\\}"); + + public MpSubscribeMsgForm() { + // 模板数据-添加 按钮事件 + templateMsgDataAddButton.addActionListener(e -> { + String[] data = new String[3]; + data[0] = getInstance().getTemplateDataNameTextField().getText(); + data[1] = getInstance().getTemplateDataValueTextField().getText(); + data[2] = getInstance().getTemplateDataColorTextField().getText(); + + if (getInstance().getTemplateMsgDataTable().getModel().getRowCount() == 0) { + initTemplateDataTable(); + } + + DefaultTableModel tableModel = (DefaultTableModel) getInstance().getTemplateMsgDataTable() + .getModel(); + int rowCount = tableModel.getRowCount(); + + Set keySet = new HashSet<>(); + String keyData; + for (int i = 0; i < rowCount; i++) { + keyData = (String) tableModel.getValueAt(i, 0); + keySet.add(keyData); + } + + if (StringUtils.isEmpty(data[0]) || StringUtils.isEmpty(data[1])) { + JOptionPane.showMessageDialog(MessageEditForm.getInstance().getMsgEditorPanel(), "Name或value不能为空!", "提示", + JOptionPane.INFORMATION_MESSAGE); + } else if (keySet.contains(data[0])) { + JOptionPane.showMessageDialog(MessageEditForm.getInstance().getMsgEditorPanel(), "Name不能重复!", "提示", + JOptionPane.INFORMATION_MESSAGE); + } else { + if (StringUtils.isEmpty(data[2])) { + data[2] = "#000000"; + } else if (!data[2].startsWith("#")) { + data[2] = "#" + data[2]; + } + tableModel.addRow(data); + } + }); + templateListComboBox.addItemListener(e -> { + if (needListenTemplateListComboBox && e.getStateChange() == ItemEvent.SELECTED) { + clearAllFieldExceptTemplateListAndContent(); + fillWxTemplateContentToField(); + } + }); + autoFillButton.addActionListener(e -> autoFillTemplateDataTable()); + refreshTemplateListButton.addActionListener(e -> { + initTemplateList(); + initTemplateDataTable(); + }); + } + + @Override + public void init(String msgName) { + MpSubscribeMsgForm mpTemplateMsgForm = getInstance(); + if (UIUtil.isDarkLaf()) { + Color bgColor = new Color(43, 43, 43); + mpTemplateMsgForm.getTemplateContentTextArea().setBackground(bgColor); + Color foreColor = new Color(187, 187, 187); + mpTemplateMsgForm.getTemplateContentTextArea().setForeground(foreColor); + } + + clearAllField(); + + Integer msgId = 0; + List tMsgMpSubscribeList = tMsgMpSubscribeMapper.selectByMsgTypeAndMsgName(MessageTypeEnum.MP_SUBSCRIBE_CODE, msgName); + if (tMsgMpSubscribeList.size() > 0) { + TMsgMpSubscribe tMsgMpSubscribe = tMsgMpSubscribeList.get(0); + msgId = tMsgMpSubscribe.getId(); + selectedMsgTemplateId = tMsgMpSubscribe.getTemplateId(); + initTemplateList(); + + mpTemplateMsgForm.getMsgTemplateIdTextField().setText(tMsgMpSubscribe.getTemplateId()); + mpTemplateMsgForm.getMsgTemplateUrlTextField().setText(tMsgMpSubscribe.getUrl()); + mpTemplateMsgForm.getMsgTemplateMiniAppidTextField().setText(tMsgMpSubscribe.getMaAppid()); + mpTemplateMsgForm.getMsgTemplateMiniPagePathTextField().setText(tMsgMpSubscribe.getMaPagePath()); + + MessageEditForm messageEditForm = MessageEditForm.getInstance(); + messageEditForm.getMsgNameField().setText(tMsgMpSubscribe.getMsgName()); + messageEditForm.getPreviewUserField().setText(tMsgMpSubscribe.getPreviewUser()); + } else { + initTemplateList(); + } + + initTemplateDataTable(); + fillTemplateDataTable(msgId); + } + + @Override + public void save(String msgName) { + int msgId = 0; + boolean existSameMsg = false; + + List tMsgMpSubscribeList = tMsgMpSubscribeMapper.selectByMsgTypeAndMsgName(MessageTypeEnum.MP_SUBSCRIBE_CODE, msgName); + if (tMsgMpSubscribeList.size() > 0) { + existSameMsg = true; + msgId = tMsgMpSubscribeList.get(0).getId(); + } + + int isCover = JOptionPane.NO_OPTION; + if (existSameMsg) { + // 如果存在,是否覆盖 + isCover = JOptionPane.showConfirmDialog(MainWindow.getInstance().getMessagePanel(), "已经存在同名的历史消息,\n是否覆盖?", "确认", + JOptionPane.YES_NO_OPTION); + } + + if (!existSameMsg || isCover == JOptionPane.YES_OPTION) { + String templateId = getInstance().getMsgTemplateIdTextField().getText(); + String templateUrl = getInstance().getMsgTemplateUrlTextField().getText(); + String templateMiniAppid = getInstance().getMsgTemplateMiniAppidTextField().getText(); + String templateMiniPagePath = getInstance().getMsgTemplateMiniPagePathTextField().getText(); + + String now = SqliteUtil.nowDateForSqlite(); + + TMsgMpSubscribe tMsgMpSubscribe = new TMsgMpSubscribe(); + tMsgMpSubscribe.setMsgType(MessageTypeEnum.MP_SUBSCRIBE_CODE); + tMsgMpSubscribe.setMsgName(msgName); + tMsgMpSubscribe.setTemplateId(templateId); + tMsgMpSubscribe.setUrl(templateUrl); + tMsgMpSubscribe.setMaAppid(templateMiniAppid); + tMsgMpSubscribe.setMaPagePath(templateMiniPagePath); + tMsgMpSubscribe.setCreateTime(now); + tMsgMpSubscribe.setModifiedTime(now); + + MessageEditForm messageEditForm = MessageEditForm.getInstance(); + tMsgMpSubscribe.setPreviewUser(messageEditForm.getPreviewUserField().getText()); + tMsgMpSubscribe.setWxAccountId(App.config.getWxAccountId()); + + if (existSameMsg) { + tMsgMpSubscribeMapper.updateByMsgTypeAndMsgName(tMsgMpSubscribe); + } else { + tMsgMpSubscribeMapper.insertSelective(tMsgMpSubscribe); + msgId = tMsgMpSubscribe.getId(); + } + + // 保存模板数据 + + // 如果是覆盖保存,则先清空之前的模板数据 + if (existSameMsg) { + templateDataMapper.deleteByMsgTypeAndMsgId(MessageTypeEnum.MP_SUBSCRIBE_CODE, msgId); + } + + // 如果table为空,则初始化 + if (getInstance().getTemplateMsgDataTable().getModel().getRowCount() == 0) { + initTemplateDataTable(); + } + + // 逐行读取 + DefaultTableModel tableModel = (DefaultTableModel) getInstance().getTemplateMsgDataTable() + .getModel(); + int rowCount = tableModel.getRowCount(); + for (int i = 0; i < rowCount; i++) { + String name = (String) tableModel.getValueAt(i, 0); + String value = (String) tableModel.getValueAt(i, 1); + String color = ((String) tableModel.getValueAt(i, 2)).trim(); + + TTemplateData tTemplateData = new TTemplateData(); + tTemplateData.setMsgType(MessageTypeEnum.MP_SUBSCRIBE_CODE); + tTemplateData.setMsgId(msgId); + tTemplateData.setName(name); + tTemplateData.setValue(value); + tTemplateData.setColor(color); + tTemplateData.setCreateTime(now); + tTemplateData.setModifiedTime(now); + + templateDataMapper.insert(tTemplateData); + } + + JOptionPane.showMessageDialog(MainWindow.getInstance().getMessagePanel(), "保存成功!", "成功", + JOptionPane.INFORMATION_MESSAGE); + } + } + + public static MpSubscribeMsgForm getInstance() { + if (mpSubscribeMsgForm == null) { + mpSubscribeMsgForm = new MpSubscribeMsgForm(); + } + return mpSubscribeMsgForm; + } + + /** + * 填充模板参数表Table(从数据库读取) + * + * @param msgId + */ + public static void fillTemplateDataTable(Integer msgId) { + // 模板消息Data表 + List templateDataList = templateDataMapper.selectByMsgTypeAndMsgId(MessageTypeEnum.MP_SUBSCRIBE_CODE, msgId); + String[] headerNames = {"Name", "Value", "Color", "操作"}; + Object[][] cellData = new String[templateDataList.size()][headerNames.length]; + for (int i = 0; i < templateDataList.size(); i++) { + TTemplateData tTemplateData = templateDataList.get(i); + cellData[i][0] = tTemplateData.getName(); + cellData[i][1] = tTemplateData.getValue(); + cellData[i][2] = tTemplateData.getColor(); + } + DefaultTableModel model = new DefaultTableModel(cellData, headerNames); + getInstance().getTemplateMsgDataTable().setModel(model); + TableColumnModel tableColumnModel = getInstance().getTemplateMsgDataTable().getColumnModel(); + tableColumnModel.getColumn(headerNames.length - 1). + setCellRenderer(new TableInCellButtonColumn(getInstance().getTemplateMsgDataTable(), headerNames.length - 1)); + tableColumnModel.getColumn(headerNames.length - 1). + setCellEditor(new TableInCellButtonColumn(getInstance().getTemplateMsgDataTable(), headerNames.length - 1)); + + // 设置列宽 + tableColumnModel.getColumn(3).setPreferredWidth(getInstance().getTemplateMsgDataAddButton().getWidth()); + tableColumnModel.getColumn(3).setMaxWidth(getInstance().getTemplateMsgDataAddButton().getWidth()); + } + + /** + * 初始化模板列表ComboBox + */ + public static void initTemplateList() { + needListenTemplateListComboBox = false; + try { + templateMap = Maps.newHashMap(); + templateList = WxMpTemplateMsgSender.getWxMpService().getTemplateMsgService().getAllPrivateTemplate(); + getInstance().getTemplateListComboBox().removeAllItems(); + int selectedIndex = 0; + for (int i = 0; i < templateList.size(); i++) { + WxMpTemplate wxMpTemplate = templateList.get(i); + getInstance().getTemplateListComboBox().addItem(wxMpTemplate.getTitle()); + templateMap.put(wxMpTemplate.getTemplateId(), wxMpTemplate); + if (wxMpTemplate.getTemplateId().equals(selectedMsgTemplateId)) { + selectedIndex = i; + } + } + + if (getInstance().getTemplateListComboBox().getItemCount() > 0) { + getInstance().getTemplateListComboBox().setSelectedIndex(selectedIndex); + fillWxTemplateContentToField(); + } + + } catch (Exception e) { + log.error(e.toString()); + } + needListenTemplateListComboBox = true; + } + + /** + * 根据模板内容获取模板中的参数list + * + * @param templateContent 模板内容 + * @return params 模板中的参数 + */ + public static List getTemplateParams(String templateContent) { + List params = Lists.newArrayList(); + Matcher matcher = BRACE_PATTERN.matcher(templateContent); + while (matcher.find()) { + params.add(matcher.group(1).replace(".DATA", "")); + } + return params; + } + + /** + * 根据模板id填充模板列表中对应的WxTemplate内容到表单 + */ + public static void fillWxTemplateContentToField() { + WxMpTemplate wxMpTemplate = templateList.get(getInstance().getTemplateListComboBox().getSelectedIndex()); + if (wxMpTemplate != null) { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("-----------模板ID-----------\n").append(wxMpTemplate.getTemplateId()).append("\n"); + stringBuilder.append("\n----------所属行业----------\n").append(wxMpTemplate.getPrimaryIndustry()).append("-").append(wxMpTemplate.getDeputyIndustry()).append("\n"); + stringBuilder.append("\n----------模板内容----------\n").append(wxMpTemplate.getContent()).append("\n"); + stringBuilder.append("\n----------模板示例----------\n").append(wxMpTemplate.getExample()); + getInstance().getTemplateContentTextArea().setText(stringBuilder.toString()); + getInstance().getMsgTemplateIdTextField().setText(wxMpTemplate.getTemplateId()); + } + } + + /** + * 自动填充模板数据Table + */ + private static void autoFillTemplateDataTable() { + if (templateList != null) { + WxMpTemplate wxMpTemplate = templateList.get(getInstance().getTemplateListComboBox().getSelectedIndex()); + if (wxMpTemplate != null) { + initTemplateDataTable(); + DefaultTableModel tableModel = (DefaultTableModel) getInstance().getTemplateMsgDataTable() + .getModel(); + List params = getTemplateParams(wxMpTemplate.getContent()); + for (int i = 0; i < params.size(); i++) { + String param = params.get(i); + String[] data = new String[3]; + data[0] = param; + data[1] = "示例值" + (i + 1); + data[2] = "#000000"; + tableModel.addRow(data); + } + } + } + } + + /** + * 初始化模板消息数据table + */ + public static void initTemplateDataTable() { + JTable msgDataTable = getInstance().getTemplateMsgDataTable(); + String[] headerNames = {"Name", "Value", "Color", "操作"}; + DefaultTableModel model = new DefaultTableModel(null, headerNames); + msgDataTable.setModel(model); + msgDataTable.updateUI(); + DefaultTableCellRenderer hr = (DefaultTableCellRenderer) msgDataTable.getTableHeader().getDefaultRenderer(); + // 表头列名居左 + hr.setHorizontalAlignment(DefaultTableCellRenderer.LEFT); + + TableColumnModel tableColumnModel = msgDataTable.getColumnModel(); + tableColumnModel.getColumn(headerNames.length - 1). + setCellRenderer(new TableInCellButtonColumn(msgDataTable, headerNames.length - 1)); + tableColumnModel.getColumn(headerNames.length - 1). + setCellEditor(new TableInCellButtonColumn(msgDataTable, headerNames.length - 1)); + + // 设置列宽 + tableColumnModel.getColumn(3).setPreferredWidth(getInstance().getTemplateMsgDataAddButton().getWidth()); + tableColumnModel.getColumn(3).setMaxWidth(getInstance().getTemplateMsgDataAddButton().getWidth()); + } + + /** + * 清空所有界面字段 + */ + public static void clearAllField() { + clearAllFieldExceptTemplateListAndContent(); + getInstance().getTemplateListComboBox().removeAllItems(); + getInstance().getTemplateContentTextArea().setText(""); + } + + /** + * 清空所有界面字段 + */ + public static void clearAllFieldExceptTemplateListAndContent() { + getInstance().getMsgTemplateIdTextField().setText(""); + getInstance().getMsgTemplateUrlTextField().setText(""); + getInstance().getMsgTemplateMiniAppidTextField().setText(""); + getInstance().getMsgTemplateMiniPagePathTextField().setText(""); + getInstance().getTemplateDataNameTextField().setText(""); + getInstance().getTemplateDataValueTextField().setText(""); + getInstance().getTemplateDataColorTextField().setText(""); + selectedMsgTemplateId = null; + initTemplateDataTable(); + } + + { +// GUI initializer generated by IntelliJ IDEA GUI Designer +// >>> IMPORTANT!! <<< +// DO NOT EDIT OR ADD ANY CODE HERE! + $$$setupUI$$$(); + } + + /** + * Method generated by IntelliJ IDEA GUI Designer + * >>> IMPORTANT!! <<< + * DO NOT edit this method OR call it in your code! + * + * @noinspection ALL + */ + private void $$$setupUI$$$() { + final JPanel panel1 = new JPanel(); + panel1.setLayout(new GridLayoutManager(1, 1, new Insets(0, 0, 0, 0), -1, -1)); + templateMsgPanel = new JPanel(); + templateMsgPanel.setLayout(new GridLayoutManager(2, 1, new Insets(10, 15, 0, 0), -1, -1)); + panel1.add(templateMsgPanel, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false)); + templateMsgPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(), "公众号-订阅通知编辑", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, this.$$$getFont$$$(null, Font.BOLD, -1, templateMsgPanel.getFont()), null)); + templateMsgDataPanel = new JPanel(); + templateMsgDataPanel.setLayout(new GridLayoutManager(3, 4, new Insets(10, 0, 0, 0), -1, -1)); + templateMsgPanel.add(templateMsgDataPanel, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false)); + templateMsgDataPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "模板变量(可使用\"${ENTER}\"作为换行符)", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, this.$$$getFont$$$(null, Font.BOLD, -1, templateMsgDataPanel.getFont()), null)); + templateDataNameTextField = new JTextField(); + templateDataNameTextField.setToolTipText("当消息类型是模板消息时的示例:first或者keyword1或者remark之类的"); + templateMsgDataPanel.add(templateDataNameTextField, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + templateDataValueTextField = new JTextField(); + templateMsgDataPanel.add(templateDataValueTextField, new GridConstraints(1, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + templateDataColorTextField = new JTextField(); + templateDataColorTextField.setToolTipText("示例值:FF0000"); + templateMsgDataPanel.add(templateDataColorTextField, new GridConstraints(1, 2, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + templateMsgDataAddButton = new JButton(); + templateMsgDataAddButton.setIcon(new ImageIcon(getClass().getResource("/icon/add.png"))); + templateMsgDataAddButton.setText(""); + templateMsgDataPanel.add(templateMsgDataAddButton, new GridConstraints(1, 3, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + templateMsgDataTable = new JTable(); + templateMsgDataTable.setAutoCreateColumnsFromModel(true); + templateMsgDataTable.setAutoCreateRowSorter(true); + templateMsgDataTable.setGridColor(new Color(-12236470)); + templateMsgDataTable.setRowHeight(36); + templateMsgDataPanel.add(templateMsgDataTable, new GridConstraints(2, 0, 1, 4, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false)); + templateMsgNameLabel = new JLabel(); + templateMsgNameLabel.setText("name"); + templateMsgNameLabel.setToolTipText("当消息类型是模板消息时的示例:first或者keyword1或者remark之类的"); + templateMsgDataPanel.add(templateMsgNameLabel, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + templateMsgValueLabel = new JLabel(); + templateMsgValueLabel.setText("value"); + templateMsgDataPanel.add(templateMsgValueLabel, new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + templateMsgColorLabel = new JLabel(); + templateMsgColorLabel.setText("color"); + templateMsgColorLabel.setToolTipText("示例值:FF0000"); + templateMsgDataPanel.add(templateMsgColorLabel, new GridConstraints(0, 2, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + autoFillButton = new JButton(); + autoFillButton.setText("自动填充"); + templateMsgDataPanel.add(autoFillButton, new GridConstraints(0, 3, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + final JPanel panel2 = new JPanel(); + panel2.setLayout(new GridLayoutManager(6, 3, new Insets(0, 0, 5, 0), -1, -1)); + templateMsgPanel.add(panel2, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); + templateIdLabel = new JLabel(); + templateIdLabel.setText("模板ID *"); + panel2.add(templateIdLabel, new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + msgTemplateIdTextField = new JTextField(); + panel2.add(msgTemplateIdTextField, new GridConstraints(2, 1, 1, 2, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0, false)); + templateUrlLabel = new JLabel(); + templateUrlLabel.setText("跳转URL"); + panel2.add(templateUrlLabel, new GridConstraints(3, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + msgTemplateUrlTextField = new JTextField(); + panel2.add(msgTemplateUrlTextField, new GridConstraints(3, 1, 1, 2, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0, false)); + templateMiniProgramAppidLabel = new JLabel(); + templateMiniProgramAppidLabel.setText("小程序appid"); + templateMiniProgramAppidLabel.setToolTipText("非必填"); + panel2.add(templateMiniProgramAppidLabel, new GridConstraints(4, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + msgTemplateMiniAppidTextField = new JTextField(); + msgTemplateMiniAppidTextField.setText(""); + msgTemplateMiniAppidTextField.setToolTipText("非必填"); + panel2.add(msgTemplateMiniAppidTextField, new GridConstraints(4, 1, 1, 2, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0, false)); + templateMiniProgramPagePathLabel = new JLabel(); + templateMiniProgramPagePathLabel.setText("小程序页面路径"); + templateMiniProgramPagePathLabel.setToolTipText("非必填"); + panel2.add(templateMiniProgramPagePathLabel, new GridConstraints(5, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + msgTemplateMiniPagePathTextField = new JTextField(); + msgTemplateMiniPagePathTextField.setText(""); + msgTemplateMiniPagePathTextField.setToolTipText("非必填"); + panel2.add(msgTemplateMiniPagePathTextField, new GridConstraints(5, 1, 1, 2, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0, false)); + final JLabel label1 = new JLabel(); + label1.setText("选择模板"); + panel2.add(label1, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + templateListComboBox = new JComboBox(); + panel2.add(templateListComboBox, new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + refreshTemplateListButton = new JButton(); + refreshTemplateListButton.setIcon(new ImageIcon(getClass().getResource("/icon/refresh.png"))); + refreshTemplateListButton.setText("刷新"); + panel2.add(refreshTemplateListButton, new GridConstraints(0, 2, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, 1, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + templateContentTextArea = new JTextArea(); + templateContentTextArea.setEditable(false); + panel2.add(templateContentTextArea, new GridConstraints(1, 0, 1, 3, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_WANT_GROW, null, new Dimension(150, 50), null, 0, false)); + templateMsgNameLabel.setLabelFor(templateDataNameTextField); + templateMsgValueLabel.setLabelFor(templateDataValueTextField); + templateMsgColorLabel.setLabelFor(templateDataColorTextField); + templateIdLabel.setLabelFor(msgTemplateIdTextField); + templateUrlLabel.setLabelFor(msgTemplateUrlTextField); + templateMiniProgramAppidLabel.setLabelFor(msgTemplateMiniAppidTextField); + templateMiniProgramPagePathLabel.setLabelFor(msgTemplateMiniPagePathTextField); + } + + /** + * @noinspection ALL + */ + private Font $$$getFont$$$(String fontName, int style, int size, Font currentFont) { + if (currentFont == null) return null; + String resultName; + if (fontName == null) { + resultName = currentFont.getName(); + } else { + Font testFont = new Font(fontName, Font.PLAIN, 10); + if (testFont.canDisplay('a') && testFont.canDisplay('1')) { + resultName = fontName; + } else { + resultName = currentFont.getName(); + } + } + Font font = new Font(resultName, style >= 0 ? style : currentFont.getStyle(), size >= 0 ? size : currentFont.getSize()); + boolean isMac = System.getProperty("os.name", "").toLowerCase(Locale.ENGLISH).startsWith("mac"); + Font fontWithFallback = isMac ? new Font(font.getFamily(), font.getStyle(), font.getSize()) : new StyleContext().getFont(font.getFamily(), font.getStyle(), font.getSize()); + return fontWithFallback instanceof FontUIResource ? fontWithFallback : new FontUIResource(fontWithFallback); + } + +} diff --git a/src/main/java/com/fangxuele/tool/push/ui/form/msg/MsgFormFactory.java b/src/main/java/com/fangxuele/tool/push/ui/form/msg/MsgFormFactory.java index d84ad8e36..80044d76b 100644 --- a/src/main/java/com/fangxuele/tool/push/ui/form/msg/MsgFormFactory.java +++ b/src/main/java/com/fangxuele/tool/push/ui/form/msg/MsgFormFactory.java @@ -71,6 +71,9 @@ public static IMsgForm getMsgForm() { case MessageTypeEnum.BD_YUN_CODE: iMsgForm = BdYunMsgForm.getInstance(); break; + case MessageTypeEnum.MP_SUBSCRIBE_CODE: + iMsgForm = MpSubscribeMsgForm.getInstance(); + break; case MessageTypeEnum.HTTP_CODE: default: iMsgForm = HttpMsgForm.getInstance(); diff --git a/src/main/java/com/fangxuele/tool/push/ui/listener/MemberListener.java b/src/main/java/com/fangxuele/tool/push/ui/listener/MemberListener.java index 8320acce1..b6c8ba403 100644 --- a/src/main/java/com/fangxuele/tool/push/ui/listener/MemberListener.java +++ b/src/main/java/com/fangxuele/tool/push/ui/listener/MemberListener.java @@ -1009,7 +1009,8 @@ public static void renderMemberListTable() { boolean isWeixinTypeMsg = false; if (msgType == MessageTypeEnum.MP_TEMPLATE_CODE || msgType == MessageTypeEnum.MA_TEMPLATE_CODE || msgType == MessageTypeEnum.KEFU_CODE || msgType == MessageTypeEnum.KEFU_PRIORITY_CODE - || msgType == MessageTypeEnum.WX_UNIFORM_MESSAGE_CODE || msgType == MessageTypeEnum.MA_SUBSCRIBE_CODE) { + || msgType == MessageTypeEnum.WX_UNIFORM_MESSAGE_CODE || msgType == MessageTypeEnum.MA_SUBSCRIBE_CODE + || msgType == MessageTypeEnum.MP_SUBSCRIBE_CODE) { isWeixinTypeMsg = true; } // 导入列表 diff --git a/src/main/java/com/fangxuele/tool/push/ui/listener/MessageEditListener.java b/src/main/java/com/fangxuele/tool/push/ui/listener/MessageEditListener.java index e5a984c85..00cec4f11 100644 --- a/src/main/java/com/fangxuele/tool/push/ui/listener/MessageEditListener.java +++ b/src/main/java/com/fangxuele/tool/push/ui/listener/MessageEditListener.java @@ -141,7 +141,7 @@ public void mousePressed(MouseEvent e) { String paraDemo = ""; if (msgType == MessageTypeEnum.MP_TEMPLATE_CODE || msgType == MessageTypeEnum.KEFU_PRIORITY_CODE || msgType == MessageTypeEnum.KEFU_CODE || msgType == MessageTypeEnum.WX_UNIFORM_MESSAGE_CODE - || msgType == MessageTypeEnum.MA_SUBSCRIBE_CODE) { + || msgType == MessageTypeEnum.MA_SUBSCRIBE_CODE || msgType == MessageTypeEnum.MP_SUBSCRIBE_CODE) { fillParaName = "预览消息用户的openId"; paraDemo = "ox_kxwS_gGt63adS-zemlETtuvw1;ox_kxwS_gGt63adS-zemlETtuvw2"; } else if (msgType == MessageTypeEnum.MA_TEMPLATE_CODE) { diff --git a/src/main/java/com/fangxuele/tool/push/ui/listener/MessageManageListener.java b/src/main/java/com/fangxuele/tool/push/ui/listener/MessageManageListener.java index caad195d5..5717eeba4 100644 --- a/src/main/java/com/fangxuele/tool/push/ui/listener/MessageManageListener.java +++ b/src/main/java/com/fangxuele/tool/push/ui/listener/MessageManageListener.java @@ -4,18 +4,7 @@ import cn.hutool.log.Log; import cn.hutool.log.LogFactory; import com.fangxuele.tool.push.App; -import com.fangxuele.tool.push.dao.TMsgDingMapper; -import com.fangxuele.tool.push.dao.TMsgHttpMapper; -import com.fangxuele.tool.push.dao.TMsgKefuMapper; -import com.fangxuele.tool.push.dao.TMsgKefuPriorityMapper; -import com.fangxuele.tool.push.dao.TMsgMaSubscribeMapper; -import com.fangxuele.tool.push.dao.TMsgMaTemplateMapper; -import com.fangxuele.tool.push.dao.TMsgMailMapper; -import com.fangxuele.tool.push.dao.TMsgMpTemplateMapper; -import com.fangxuele.tool.push.dao.TMsgSmsMapper; -import com.fangxuele.tool.push.dao.TMsgWxCpMapper; -import com.fangxuele.tool.push.dao.TMsgWxUniformMapper; -import com.fangxuele.tool.push.dao.TWxAccountMapper; +import com.fangxuele.tool.push.dao.*; import com.fangxuele.tool.push.domain.TWxAccount; import com.fangxuele.tool.push.logic.MessageTypeEnum; import com.fangxuele.tool.push.ui.UiConsts; @@ -54,6 +43,7 @@ public class MessageManageListener { private static TMsgMaTemplateMapper msgMaTemplateMapper = MybatisUtil.getSqlSession().getMapper(TMsgMaTemplateMapper.class); private static TMsgMaSubscribeMapper msgMaSubscribeMapper = MybatisUtil.getSqlSession().getMapper(TMsgMaSubscribeMapper.class); private static TMsgMpTemplateMapper msgMpTemplateMapper = MybatisUtil.getSqlSession().getMapper(TMsgMpTemplateMapper.class); + private static TMsgMpSubscribeMapper msgMpSubscribeMapper = MybatisUtil.getSqlSession().getMapper(TMsgMpSubscribeMapper.class); private static TMsgSmsMapper msgSmsMapper = MybatisUtil.getSqlSession().getMapper(TMsgSmsMapper.class); private static TMsgMailMapper msgMailMapper = MybatisUtil.getSqlSession().getMapper(TMsgMailMapper.class); private static TMsgHttpMapper msgHttpMapper = MybatisUtil.getSqlSession().getMapper(TMsgHttpMapper.class); @@ -111,6 +101,8 @@ public void mousePressed(MouseEvent e) { msgMaSubscribeMapper.deleteByMsgTypeAndName(msgType, msgName); } else if (msgType == MessageTypeEnum.MP_TEMPLATE_CODE) { msgMpTemplateMapper.deleteByMsgTypeAndName(msgType, msgName); + } else if (msgType == MessageTypeEnum.MP_SUBSCRIBE_CODE) { + msgMpSubscribeMapper.deleteByMsgTypeAndName(msgType, msgName); } else if (msgType == MessageTypeEnum.EMAIL_CODE) { msgMailMapper.deleteByMsgTypeAndName(msgType, msgName); } else if (msgType == MessageTypeEnum.HTTP_CODE) { @@ -155,6 +147,7 @@ public void mousePressed(MouseEvent e) { switch (msgType) { case MessageTypeEnum.MP_TEMPLATE_CODE: + case MessageTypeEnum.MP_SUBSCRIBE_CODE: MpTemplateMsgForm.clearAllField(); case MessageTypeEnum.KEFU_CODE: KefuMsgForm.clearAllField(); diff --git a/src/main/java/com/fangxuele/tool/push/ui/listener/MessageTypeListener.java b/src/main/java/com/fangxuele/tool/push/ui/listener/MessageTypeListener.java index 58b2930aa..74ee95828 100644 --- a/src/main/java/com/fangxuele/tool/push/ui/listener/MessageTypeListener.java +++ b/src/main/java/com/fangxuele/tool/push/ui/listener/MessageTypeListener.java @@ -27,6 +27,10 @@ public static void addListeners() { App.config.setMsgType(MessageTypeEnum.MP_TEMPLATE_CODE); saveType(); }); + messageTypeForm.getMpSubscribeRadioButton().addActionListener(e -> { + App.config.setMsgType(MessageTypeEnum.MP_SUBSCRIBE_CODE); + saveType(); + }); messageTypeForm.getMaTemplateRadioButton().addActionListener(e -> { App.config.setMsgType(MessageTypeEnum.MA_TEMPLATE_CODE); saveType(); diff --git a/src/main/resources/mapper/TMsgMpSubscribeMapper.xml b/src/main/resources/mapper/TMsgMpSubscribeMapper.xml index 398df3e06..1a325949d 100644 --- a/src/main/resources/mapper/TMsgMpSubscribeMapper.xml +++ b/src/main/resources/mapper/TMsgMpSubscribeMapper.xml @@ -1,164 +1,198 @@ - - - - - - - - - - - - - - - id, msg_type, msg_name, template_id, url, ma_appid, ma_page_path, preview_user, wx_account_id, - create_time, modified_time - - - - delete from t_msg_mp_subscribe - where id = #{id,jdbcType=INTEGER} - - - insert into t_msg_mp_subscribe (id, msg_type, msg_name, - template_id, url, ma_appid, - ma_page_path, preview_user, wx_account_id, - create_time, modified_time) - values (#{id,jdbcType=INTEGER}, #{msgType,jdbcType=INTEGER}, #{msgName,jdbcType=VARCHAR}, - #{templateId,jdbcType=VARCHAR}, #{url,jdbcType=VARCHAR}, #{maAppid,jdbcType=VARCHAR}, - #{maPagePath,jdbcType=VARCHAR}, #{previewUser,jdbcType=VARCHAR}, #{wxAccountId,jdbcType=INTEGER}, - #{createTime,jdbcType=VARCHAR}, #{modifiedTime,jdbcType=VARCHAR}) - - - insert into t_msg_mp_subscribe - - - id, - - - msg_type, - - - msg_name, - - - template_id, - - - url, - - - ma_appid, - - - ma_page_path, - - - preview_user, - - - wx_account_id, - - - create_time, - - - modified_time, - - - - - #{id,jdbcType=INTEGER}, - - - #{msgType,jdbcType=INTEGER}, - - - #{msgName,jdbcType=VARCHAR}, - - - #{templateId,jdbcType=VARCHAR}, - - - #{url,jdbcType=VARCHAR}, - - - #{maAppid,jdbcType=VARCHAR}, - - - #{maPagePath,jdbcType=VARCHAR}, - - - #{previewUser,jdbcType=VARCHAR}, - - - #{wxAccountId,jdbcType=INTEGER}, - - - #{createTime,jdbcType=VARCHAR}, - - - #{modifiedTime,jdbcType=VARCHAR}, - - - - - update t_msg_mp_subscribe - - - msg_type = #{msgType,jdbcType=INTEGER}, - - + + + + + + + + + + + + + + + id, msg_type, msg_name, template_id, url, ma_appid, ma_page_path, preview_user, wx_account_id, + create_time, modified_time + + + + delete from t_msg_mp_subscribe + where id = #{id,jdbcType=INTEGER} + + + insert into t_msg_mp_subscribe (id, msg_type, msg_name, + template_id, url, ma_appid, + ma_page_path, preview_user, wx_account_id, + create_time, modified_time) + values (#{id,jdbcType=INTEGER}, #{msgType,jdbcType=INTEGER}, #{msgName,jdbcType=VARCHAR}, + #{templateId,jdbcType=VARCHAR}, #{url,jdbcType=VARCHAR}, #{maAppid,jdbcType=VARCHAR}, + #{maPagePath,jdbcType=VARCHAR}, #{previewUser,jdbcType=VARCHAR}, #{wxAccountId,jdbcType=INTEGER}, + #{createTime,jdbcType=VARCHAR}, #{modifiedTime,jdbcType=VARCHAR}) + + + insert into t_msg_mp_subscribe + + + id, + + + msg_type, + + + msg_name, + + + template_id, + + + url, + + + ma_appid, + + + ma_page_path, + + + preview_user, + + + wx_account_id, + + + create_time, + + + modified_time, + + + + + #{id,jdbcType=INTEGER}, + + + #{msgType,jdbcType=INTEGER}, + + + #{msgName,jdbcType=VARCHAR}, + + + #{templateId,jdbcType=VARCHAR}, + + + #{url,jdbcType=VARCHAR}, + + + #{maAppid,jdbcType=VARCHAR}, + + + #{maPagePath,jdbcType=VARCHAR}, + + + #{previewUser,jdbcType=VARCHAR}, + + + #{wxAccountId,jdbcType=INTEGER}, + + + #{createTime,jdbcType=VARCHAR}, + + + #{modifiedTime,jdbcType=VARCHAR}, + + + + + update t_msg_mp_subscribe + + + msg_type = #{msgType,jdbcType=INTEGER}, + + + msg_name = #{msgName,jdbcType=VARCHAR}, + + + template_id = #{templateId,jdbcType=VARCHAR}, + + + url = #{url,jdbcType=VARCHAR}, + + + ma_appid = #{maAppid,jdbcType=VARCHAR}, + + + ma_page_path = #{maPagePath,jdbcType=VARCHAR}, + + + preview_user = #{previewUser,jdbcType=VARCHAR}, + + + wx_account_id = #{wxAccountId,jdbcType=INTEGER}, + + + create_time = #{createTime,jdbcType=VARCHAR}, + + + modified_time = #{modifiedTime,jdbcType=VARCHAR}, + + + where id = #{id,jdbcType=INTEGER} + + + update t_msg_mp_subscribe + set msg_type = #{msgType,jdbcType=INTEGER}, msg_name = #{msgName,jdbcType=VARCHAR}, - - template_id = #{templateId,jdbcType=VARCHAR}, - - url = #{url,jdbcType=VARCHAR}, - - ma_appid = #{maAppid,jdbcType=VARCHAR}, - - ma_page_path = #{maPagePath,jdbcType=VARCHAR}, - - preview_user = #{previewUser,jdbcType=VARCHAR}, - - wx_account_id = #{wxAccountId,jdbcType=INTEGER}, - - create_time = #{createTime,jdbcType=VARCHAR}, - - + modified_time = #{modifiedTime,jdbcType=VARCHAR} + where id = #{id,jdbcType=INTEGER} + + + + update t_msg_mp_subscribe + set template_id = #{templateId,jdbcType=VARCHAR}, + url = #{url,jdbcType=VARCHAR}, + ma_appid = #{maAppid,jdbcType=VARCHAR}, + ma_page_path = #{maPagePath,jdbcType=VARCHAR}, modified_time = #{modifiedTime,jdbcType=VARCHAR}, - - - where id = #{id,jdbcType=INTEGER} - - - update t_msg_mp_subscribe - set msg_type = #{msgType,jdbcType=INTEGER}, - msg_name = #{msgName,jdbcType=VARCHAR}, - template_id = #{templateId,jdbcType=VARCHAR}, - url = #{url,jdbcType=VARCHAR}, - ma_appid = #{maAppid,jdbcType=VARCHAR}, - ma_page_path = #{maPagePath,jdbcType=VARCHAR}, - preview_user = #{previewUser,jdbcType=VARCHAR}, - wx_account_id = #{wxAccountId,jdbcType=INTEGER}, - create_time = #{createTime,jdbcType=VARCHAR}, - modified_time = #{modifiedTime,jdbcType=VARCHAR} - where id = #{id,jdbcType=INTEGER} - + preview_user = #{previewUser,jdbcType=VARCHAR}, + wx_account_id = #{wxAccountId,jdbcType=INTEGER} + where msg_type = #{msgType,jdbcType=INTEGER} + and msg_name = #{msgName,jdbcType=VARCHAR} + + + delete + from t_msg_mp_subscribe + where msg_type = #{msgType,jdbcType=INTEGER} + and msg_name = #{msgName,jdbcType=VARCHAR} + + \ No newline at end of file From 10c7f6d1648327d22cb9392be9ede1c380cc58d2 Mon Sep 17 00:00:00 2001 From: zhoubo58 Date: Tue, 23 Mar 2021 17:21:03 +0800 Subject: [PATCH 04/19] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=85=AC=E4=BC=97?= =?UTF-8?q?=E5=8F=B7=E8=AE=A2=E9=98=85=E9=80=9A=E7=9F=A5-=E5=AE=8C?= =?UTF-8?q?=E6=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../push/ui/form/msg/MpSubscribeMsgForm.java | 44 +++++++++++-------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/fangxuele/tool/push/ui/form/msg/MpSubscribeMsgForm.java b/src/main/java/com/fangxuele/tool/push/ui/form/msg/MpSubscribeMsgForm.java index a324b525e..e62f2f699 100644 --- a/src/main/java/com/fangxuele/tool/push/ui/form/msg/MpSubscribeMsgForm.java +++ b/src/main/java/com/fangxuele/tool/push/ui/form/msg/MpSubscribeMsgForm.java @@ -18,7 +18,7 @@ import com.intellij.uiDesigner.core.GridLayoutManager; import lombok.Getter; import lombok.extern.slf4j.Slf4j; -import me.chanjar.weixin.mp.bean.template.WxMpTemplate; +import me.chanjar.weixin.common.bean.subscribemsg.TemplateInfo; import org.apache.commons.compress.utils.Lists; import org.apache.commons.lang3.StringUtils; @@ -79,12 +79,12 @@ public class MpSubscribeMsgForm implements IMsgForm { /** * 账号模板列表 */ - public static List templateList; + public static List templateList; /** * 模板账号map,key:templateId */ - public static Map templateMap; + public static Map templateMap; /** * (左侧列表中)所选消息对应的模板ID @@ -313,14 +313,14 @@ public static void initTemplateList() { needListenTemplateListComboBox = false; try { templateMap = Maps.newHashMap(); - templateList = WxMpTemplateMsgSender.getWxMpService().getTemplateMsgService().getAllPrivateTemplate(); + templateList = WxMpTemplateMsgSender.getWxMpService().getSubscribeMsgService().getTemplateList(); getInstance().getTemplateListComboBox().removeAllItems(); int selectedIndex = 0; for (int i = 0; i < templateList.size(); i++) { - WxMpTemplate wxMpTemplate = templateList.get(i); - getInstance().getTemplateListComboBox().addItem(wxMpTemplate.getTitle()); - templateMap.put(wxMpTemplate.getTemplateId(), wxMpTemplate); - if (wxMpTemplate.getTemplateId().equals(selectedMsgTemplateId)) { + TemplateInfo templateInfo = templateList.get(i); + getInstance().getTemplateListComboBox().addItem(templateInfo.getTitle()); + templateMap.put(templateInfo.getPriTmplId(), templateInfo); + if (templateInfo.getPriTmplId().equals(selectedMsgTemplateId)) { selectedIndex = i; } } @@ -355,15 +355,23 @@ public static List getTemplateParams(String templateContent) { * 根据模板id填充模板列表中对应的WxTemplate内容到表单 */ public static void fillWxTemplateContentToField() { - WxMpTemplate wxMpTemplate = templateList.get(getInstance().getTemplateListComboBox().getSelectedIndex()); - if (wxMpTemplate != null) { + TemplateInfo templateInfo = templateList.get(getInstance().getTemplateListComboBox().getSelectedIndex()); + if (templateInfo != null) { StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append("-----------模板ID-----------\n").append(wxMpTemplate.getTemplateId()).append("\n"); - stringBuilder.append("\n----------所属行业----------\n").append(wxMpTemplate.getPrimaryIndustry()).append("-").append(wxMpTemplate.getDeputyIndustry()).append("\n"); - stringBuilder.append("\n----------模板内容----------\n").append(wxMpTemplate.getContent()).append("\n"); - stringBuilder.append("\n----------模板示例----------\n").append(wxMpTemplate.getExample()); + stringBuilder.append("-----------模板ID-----------\n").append(templateInfo.getPriTmplId()).append("\n"); + stringBuilder.append("\n----------模板标题----------\n").append(templateInfo.getTitle()).append("\n"); + int type = templateInfo.getType(); + String templateType = "未知"; + if (type == 2) { + templateType = "一次性订阅"; + } else if (type == 3) { + templateType = "长期订阅"; + } + stringBuilder.append("\n----------模板类型----------\n").append(templateType).append("\n"); + stringBuilder.append("\n----------模板内容----------\n").append(templateInfo.getContent()).append("\n"); + stringBuilder.append("\n----------模板示例----------\n").append(templateInfo.getExample()); getInstance().getTemplateContentTextArea().setText(stringBuilder.toString()); - getInstance().getMsgTemplateIdTextField().setText(wxMpTemplate.getTemplateId()); + getInstance().getMsgTemplateIdTextField().setText(templateInfo.getPriTmplId()); } } @@ -372,12 +380,12 @@ public static void fillWxTemplateContentToField() { */ private static void autoFillTemplateDataTable() { if (templateList != null) { - WxMpTemplate wxMpTemplate = templateList.get(getInstance().getTemplateListComboBox().getSelectedIndex()); - if (wxMpTemplate != null) { + TemplateInfo templateInfo = templateList.get(getInstance().getTemplateListComboBox().getSelectedIndex()); + if (templateInfo != null) { initTemplateDataTable(); DefaultTableModel tableModel = (DefaultTableModel) getInstance().getTemplateMsgDataTable() .getModel(); - List params = getTemplateParams(wxMpTemplate.getContent()); + List params = getTemplateParams(templateInfo.getContent()); for (int i = 0; i < params.size(); i++) { String param = params.get(i); String[] data = new String[3]; From 776e7c2351c45497b284cb11d25f51a3bcb29845 Mon Sep 17 00:00:00 2001 From: zhoubo58 Date: Tue, 23 Mar 2021 17:28:04 +0800 Subject: [PATCH 05/19] release:v_4.4.1_210323 --- src/main/java/com/fangxuele/tool/push/ui/UiConsts.java | 2 +- src/main/resources/version_summary.json | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/fangxuele/tool/push/ui/UiConsts.java b/src/main/java/com/fangxuele/tool/push/ui/UiConsts.java index 26049602f..5aac2ece5 100644 --- a/src/main/java/com/fangxuele/tool/push/ui/UiConsts.java +++ b/src/main/java/com/fangxuele/tool/push/ui/UiConsts.java @@ -16,7 +16,7 @@ public class UiConsts { * 软件名称,版本 */ public final static String APP_NAME = "WePush"; - public final static String APP_VERSION = "v_4.4.0_210221"; + public final static String APP_VERSION = "v_4.4.1_210323"; /** * Logo-1024*1024 diff --git a/src/main/resources/version_summary.json b/src/main/resources/version_summary.json index a20ddb4bc..bdf479071 100644 --- a/src/main/resources/version_summary.json +++ b/src/main/resources/version_summary.json @@ -1,5 +1,5 @@ { - "currentVersion": "v_4.4.0_210221", + "currentVersion": "v_4.4.1_210323", "versionIndex": { "v_1.1.0_170701": "0", "v_1.2.0_170831": "1", @@ -47,7 +47,8 @@ "v_4.2.4_201222": "43", "v_4.2.5_210117": "44", "v_4.3.0_210123": "45", - "v_4.4.0_210221": "46" + "v_4.4.0_210221": "46", + "v_4.4.1_210323": "47" }, "versionDetailList": [ { @@ -284,6 +285,11 @@ "version": "v_4.4.0_210221", "title": "客服消息小程序卡片类型支持上传图片", "log": "● feature:客服消息小程序卡片类型支持上传图片\n● feature:邮件消息支持添加多个附件\n● optimization:调整邮件html在线编辑器为kindeditor\n● optimization:调整默认推荐主题,修复窗口自动最大化表现异常的问题,修复点击消息管理列表经常报错的问题,优化Linux系统兼容性等各种细节优化\n" + }, + { + "version": "v_4.4.1_210323", + "title": "新增支持公众号订阅通知", + "log": "● feature:新增支持公众号订阅通知\n● feature:支持可设置关闭窗口时最小化到系统托盘\n" } ] } \ No newline at end of file From 0556696fd7ae013148ed74a2186aebc8b7d22668 Mon Sep 17 00:00:00 2001 From: zhoubo58 Date: Tue, 23 Mar 2021 20:17:32 +0800 Subject: [PATCH 06/19] =?UTF-8?q?=E6=B6=88=E6=81=AF=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E6=9E=9A=E4=B8=BE=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tool/push/logic/MessageTypeEnum.java | 18 ++++++++++++++++++ .../tool/push/ui/form/MessageTypeForm.java | 9 ++------- .../tool/push/ui/form/ScheduleForm.java | 5 +---- .../tool/push/ui/listener/MemberListener.java | 16 ++++------------ .../push/ui/listener/MessageEditListener.java | 4 +--- 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/main/java/com/fangxuele/tool/push/logic/MessageTypeEnum.java b/src/main/java/com/fangxuele/tool/push/logic/MessageTypeEnum.java index b1d1caa8d..4695f262d 100644 --- a/src/main/java/com/fangxuele/tool/push/logic/MessageTypeEnum.java +++ b/src/main/java/com/fangxuele/tool/push/logic/MessageTypeEnum.java @@ -121,4 +121,22 @@ public static String getName(int code) { } return name; } + + public static boolean isWxMpType(int msgType) { + return msgType == MessageTypeEnum.KEFU_CODE + || msgType == MessageTypeEnum.KEFU_PRIORITY_CODE + || msgType == MessageTypeEnum.MP_TEMPLATE_CODE + || msgType == MessageTypeEnum.MP_SUBSCRIBE_CODE; + } + + public static boolean isWxMaType(int msgType) { + return msgType == MessageTypeEnum.MA_TEMPLATE_CODE + || msgType == MessageTypeEnum.MA_SUBSCRIBE_CODE + || msgType == MessageTypeEnum.WX_UNIFORM_MESSAGE_CODE; + } + + public static boolean isWxMaOrMpType(int msgType) { + return isWxMaType(msgType) + || isWxMpType(msgType); + } } diff --git a/src/main/java/com/fangxuele/tool/push/ui/form/MessageTypeForm.java b/src/main/java/com/fangxuele/tool/push/ui/form/MessageTypeForm.java index 2928ad7e1..d6c7ec89a 100644 --- a/src/main/java/com/fangxuele/tool/push/ui/form/MessageTypeForm.java +++ b/src/main/java/com/fangxuele/tool/push/ui/form/MessageTypeForm.java @@ -143,9 +143,7 @@ public static void init() { } private static void initMessageManageFormLayOut(int msgType) { - if (msgType == MessageTypeEnum.KEFU_CODE || msgType == MessageTypeEnum.KEFU_PRIORITY_CODE || msgType == MessageTypeEnum.MP_TEMPLATE_CODE - || msgType == MessageTypeEnum.MA_TEMPLATE_CODE || msgType == MessageTypeEnum.MA_SUBSCRIBE_CODE - || msgType == MessageTypeEnum.WX_UNIFORM_MESSAGE_CODE || msgType == MessageTypeEnum.MP_SUBSCRIBE_CODE) { + if (MessageTypeEnum.isWxMaOrMpType(msgType)) { MessageManageForm.getInstance().getAccountSwitchPanel().setVisible(true); } else { MessageManageForm.getInstance().getAccountSwitchPanel().setVisible(false); @@ -171,10 +169,7 @@ private static void initMemberFormLayOut(int msgType) { } MemberForm.getInstance().getMemberTabDownPanel().setVisible(true); MemberForm.getInstance().getMemberTabCenterPanel().setVisible(true); - if (msgType == MessageTypeEnum.MP_TEMPLATE_CODE || msgType == MessageTypeEnum.MA_TEMPLATE_CODE - || msgType == MessageTypeEnum.KEFU_CODE || msgType == MessageTypeEnum.KEFU_PRIORITY_CODE - || msgType == MessageTypeEnum.WX_UNIFORM_MESSAGE_CODE || msgType == MessageTypeEnum.MA_SUBSCRIBE_CODE - || msgType == MessageTypeEnum.MP_SUBSCRIBE_CODE) { + if (MessageTypeEnum.isWxMaOrMpType(msgType)) { MemberForm.getInstance().getImportFromWeixinPanel().setVisible(true); MemberForm.getInstance().getImportOptionPanel().setVisible(true); } diff --git a/src/main/java/com/fangxuele/tool/push/ui/form/ScheduleForm.java b/src/main/java/com/fangxuele/tool/push/ui/form/ScheduleForm.java index de70a4d65..1ed8dec27 100644 --- a/src/main/java/com/fangxuele/tool/push/ui/form/ScheduleForm.java +++ b/src/main/java/com/fangxuele/tool/push/ui/form/ScheduleForm.java @@ -90,10 +90,7 @@ public static void fillReimportComboBox() { scheduleForm.getReimportComboBox().addItem("通过SQL导入"); scheduleForm.getReimportComboBox().addItem("通过文件导入"); int msgType = App.config.getMsgType(); - if (msgType == MessageTypeEnum.MP_TEMPLATE_CODE || msgType == MessageTypeEnum.MA_TEMPLATE_CODE - || msgType == MessageTypeEnum.KEFU_CODE || msgType == MessageTypeEnum.KEFU_PRIORITY_CODE - || msgType == MessageTypeEnum.WX_UNIFORM_MESSAGE_CODE || msgType == MessageTypeEnum.MA_SUBSCRIBE_CODE - || msgType == MessageTypeEnum.MP_SUBSCRIBE_CODE) { + if (MessageTypeEnum.isWxMaOrMpType(msgType)) { scheduleForm.getReimportComboBox().addItem("导入所有关注公众号的用户"); scheduleForm.getReimportComboBox().addItem("导入选择的标签分组"); scheduleForm.getReimportComboBox().addItem("导入选择的标签分组-取并集"); diff --git a/src/main/java/com/fangxuele/tool/push/ui/listener/MemberListener.java b/src/main/java/com/fangxuele/tool/push/ui/listener/MemberListener.java index b6c8ba403..509301335 100644 --- a/src/main/java/com/fangxuele/tool/push/ui/listener/MemberListener.java +++ b/src/main/java/com/fangxuele/tool/push/ui/listener/MemberListener.java @@ -1005,18 +1005,10 @@ public static void renderMemberListTable() { int msgType = App.config.getMsgType(); - // 是否是微信平台类消息 - boolean isWeixinTypeMsg = false; - if (msgType == MessageTypeEnum.MP_TEMPLATE_CODE || msgType == MessageTypeEnum.MA_TEMPLATE_CODE - || msgType == MessageTypeEnum.KEFU_CODE || msgType == MessageTypeEnum.KEFU_PRIORITY_CODE - || msgType == MessageTypeEnum.WX_UNIFORM_MESSAGE_CODE || msgType == MessageTypeEnum.MA_SUBSCRIBE_CODE - || msgType == MessageTypeEnum.MP_SUBSCRIBE_CODE) { - isWeixinTypeMsg = true; - } // 导入列表 List headerNameList = Lists.newArrayList(); headerNameList.add("Data"); - if (isWeixinTypeMsg) { + if (MessageTypeEnum.isWxMaOrMpType(msgType)) { if (memberForm.getImportOptionAvatarCheckBox().isSelected()) { headerNameList.add("头像"); } @@ -1035,7 +1027,7 @@ public static void renderMemberListTable() { headerNameList.toArray(headerNames); DefaultTableModel model = new DefaultTableModel(null, headerNames); memberListTable.setModel(model); - if (isWeixinTypeMsg && memberForm.getImportOptionAvatarCheckBox().isSelected()) { + if (MessageTypeEnum.isWxMaOrMpType(msgType) && memberForm.getImportOptionAvatarCheckBox().isSelected()) { memberListTable.getColumn("头像").setCellRenderer(new TableInCellImageLabelRenderer()); } @@ -1048,7 +1040,7 @@ public static void renderMemberListTable() { JTableUtil.hideColumn(memberListTable, 0); // 设置行高 - if (isWeixinTypeMsg && memberForm.getImportOptionAvatarCheckBox().isSelected()) { + if (MessageTypeEnum.isWxMaOrMpType(msgType) && memberForm.getImportOptionAvatarCheckBox().isSelected()) { memberListTable.setRowHeight(66); } else { memberListTable.setRowHeight(36); @@ -1057,7 +1049,7 @@ public static void renderMemberListTable() { List rowDataList; WxMpService wxMpService = null; boolean needToGetInfoFromWeiXin = false; - if (isWeixinTypeMsg && (memberForm.getImportOptionBasicInfoCheckBox().isSelected() || + if (MessageTypeEnum.isWxMaOrMpType(msgType) && (memberForm.getImportOptionBasicInfoCheckBox().isSelected() || memberForm.getImportOptionAvatarCheckBox().isSelected())) { needToGetInfoFromWeiXin = true; } diff --git a/src/main/java/com/fangxuele/tool/push/ui/listener/MessageEditListener.java b/src/main/java/com/fangxuele/tool/push/ui/listener/MessageEditListener.java index 00cec4f11..3628618ab 100644 --- a/src/main/java/com/fangxuele/tool/push/ui/listener/MessageEditListener.java +++ b/src/main/java/com/fangxuele/tool/push/ui/listener/MessageEditListener.java @@ -139,9 +139,7 @@ public void mousePressed(MouseEvent e) { int msgType = App.config.getMsgType(); String fillParaName = ""; String paraDemo = ""; - if (msgType == MessageTypeEnum.MP_TEMPLATE_CODE || msgType == MessageTypeEnum.KEFU_PRIORITY_CODE - || msgType == MessageTypeEnum.KEFU_CODE || msgType == MessageTypeEnum.WX_UNIFORM_MESSAGE_CODE - || msgType == MessageTypeEnum.MA_SUBSCRIBE_CODE || msgType == MessageTypeEnum.MP_SUBSCRIBE_CODE) { + if (MessageTypeEnum.isWxMaOrMpType(msgType)) { fillParaName = "预览消息用户的openId"; paraDemo = "ox_kxwS_gGt63adS-zemlETtuvw1;ox_kxwS_gGt63adS-zemlETtuvw2"; } else if (msgType == MessageTypeEnum.MA_TEMPLATE_CODE) { From 9c8ce946102ffe4ac060f30ca063a3db42daffcc Mon Sep 17 00:00:00 2001 From: zhoubo58 Date: Mon, 28 Jun 2021 16:43:00 +0800 Subject: [PATCH 07/19] =?UTF-8?q?=E5=85=AC=E4=BC=97=E5=8F=B7=E8=AE=A2?= =?UTF-8?q?=E9=98=85=E6=B6=88=E6=81=AFbug=20fix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 6 +++--- .../tool/push/logic/msgmaker/WxMpSubscribeMsgMaker.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 73aaf80ee..cf1175da3 100644 --- a/pom.xml +++ b/pom.xml @@ -20,9 +20,9 @@ 1.8 1.2.3 - 4.0.6.B - 4.0.6.B - 4.0.6.B + 4.1.0 + 4.1.0 + 4.1.0 5.1.1 5.4.4 5.2 diff --git a/src/main/java/com/fangxuele/tool/push/logic/msgmaker/WxMpSubscribeMsgMaker.java b/src/main/java/com/fangxuele/tool/push/logic/msgmaker/WxMpSubscribeMsgMaker.java index f22ae0ec7..40325fe1d 100644 --- a/src/main/java/com/fangxuele/tool/push/logic/msgmaker/WxMpSubscribeMsgMaker.java +++ b/src/main/java/com/fangxuele/tool/push/logic/msgmaker/WxMpSubscribeMsgMaker.java @@ -77,7 +77,7 @@ public WxMpSubscribeMessage makeMsg(String[] msgData) { VelocityContext velocityContext = getVelocityContext(msgData); String templateUrlEvaluated = TemplateUtil.evaluate(templateUrl, velocityContext); - wxMessageTemplate.setUrl(templateUrlEvaluated); + wxMessageTemplate.setPage(templateUrlEvaluated); String miniAppPagePathEvaluated = TemplateUtil.evaluate(miniAppPagePath, velocityContext); WxMpSubscribeMessage.MiniProgram miniProgram = new WxMpSubscribeMessage.MiniProgram(miniAppId, miniAppPagePathEvaluated, false); wxMessageTemplate.setMiniProgram(miniProgram); From 94e77006a9b63bd3d1682af3ca87fba5a11d14fb Mon Sep 17 00:00:00 2001 From: zhoubo58 Date: Mon, 28 Jun 2021 17:10:34 +0800 Subject: [PATCH 08/19] =?UTF-8?q?=E9=80=9A=E8=BF=87=E5=85=AC=E4=BC=97?= =?UTF-8?q?=E5=8F=B7=E5=AF=BC=E5=85=A5=E6=94=AF=E6=8C=81=E6=8E=92=E9=99=A4?= =?UTF-8?q?=E5=88=86=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/fangxuele/tool/push/ui/UiConsts.java | 2 +- .../tool/push/ui/form/MemberForm.form | 14 +++- .../tool/push/ui/form/MemberForm.java | 12 ++- .../tool/push/ui/listener/MemberListener.java | 84 +++++++++++++++++++ src/main/resources/version_summary.json | 10 ++- 5 files changed, 115 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/fangxuele/tool/push/ui/UiConsts.java b/src/main/java/com/fangxuele/tool/push/ui/UiConsts.java index 5aac2ece5..40b85c1c1 100644 --- a/src/main/java/com/fangxuele/tool/push/ui/UiConsts.java +++ b/src/main/java/com/fangxuele/tool/push/ui/UiConsts.java @@ -16,7 +16,7 @@ public class UiConsts { * 软件名称,版本 */ public final static String APP_NAME = "WePush"; - public final static String APP_VERSION = "v_4.4.1_210323"; + public final static String APP_VERSION = "v_4.4.2_210628"; /** * Logo-1024*1024 diff --git a/src/main/java/com/fangxuele/tool/push/ui/form/MemberForm.form b/src/main/java/com/fangxuele/tool/push/ui/form/MemberForm.form index 619b0b286..1d40c5ea2 100644 --- a/src/main/java/com/fangxuele/tool/push/ui/form/MemberForm.form +++ b/src/main/java/com/fangxuele/tool/push/ui/form/MemberForm.form @@ -287,7 +287,7 @@ - + @@ -307,7 +307,7 @@ - + @@ -345,6 +345,16 @@ + + + + + + + + + + diff --git a/src/main/java/com/fangxuele/tool/push/ui/form/MemberForm.java b/src/main/java/com/fangxuele/tool/push/ui/form/MemberForm.java index ddd652b0a..d4611d18a 100644 --- a/src/main/java/com/fangxuele/tool/push/ui/form/MemberForm.java +++ b/src/main/java/com/fangxuele/tool/push/ui/form/MemberForm.java @@ -82,6 +82,7 @@ public class MemberForm { private JButton dingDeptsImportButton; private JComboBox dingDeptsComboBox; private JButton dingDeptsRefreshButton; + private JButton memberImportTagExceptButton; private static MemberForm memberForm; @@ -269,7 +270,7 @@ public static void clearMember() { importFromSqlTextArea = new JTextArea(); memberTabCenterPanel.add(importFromSqlTextArea, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_WANT_GROW, null, new Dimension(40, 50), null, 0, false)); importFromWeixinPanel = new JPanel(); - importFromWeixinPanel.setLayout(new GridLayoutManager(4, 3, new Insets(0, 15, 0, 5), -1, -1)); + importFromWeixinPanel.setLayout(new GridLayoutManager(5, 3, new Insets(0, 15, 0, 5), -1, -1)); importWayPanel.add(importFromWeixinPanel, new GridConstraints(3, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); importFromWeixinPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "通过微信公众平台导入", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, this.$$$getFont$$$(null, Font.BOLD, -1, importFromWeixinPanel.getFont()), null)); memberImportTagComboBox = new JComboBox(); @@ -281,7 +282,7 @@ public static void clearMember() { if (memberImportAllButtonFont != null) memberImportAllButton.setFont(memberImportAllButtonFont); memberImportAllButton.setIcon(new ImageIcon(getClass().getResource("/icon/import_dark.png"))); memberImportAllButton.setText("导入所有关注公众号的用户"); - importFromWeixinPanel.add(memberImportAllButton, new GridConstraints(3, 0, 1, 3, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); + importFromWeixinPanel.add(memberImportAllButton, new GridConstraints(4, 0, 1, 3, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); memberImportTagFreshButton = new JButton(); Font memberImportTagFreshButtonFont = this.$$$getFont$$$(null, Font.PLAIN, -1, memberImportTagFreshButton.getFont()); if (memberImportTagFreshButtonFont != null) memberImportTagFreshButton.setFont(memberImportTagFreshButtonFont); @@ -301,6 +302,13 @@ public static void clearMember() { memberImportTagRetainButton.setIcon(new ImageIcon(getClass().getResource("/icon/import_dark.png"))); memberImportTagRetainButton.setText("导入选择的标签分组-取交集"); importFromWeixinPanel.add(memberImportTagRetainButton, new GridConstraints(2, 0, 1, 3, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + memberImportTagExceptButton = new JButton(); + Font memberImportTagExceptButtonFont = this.$$$getFont$$$(null, Font.PLAIN, -1, memberImportTagExceptButton.getFont()); + if (memberImportTagExceptButtonFont != null) + memberImportTagExceptButton.setFont(memberImportTagExceptButtonFont); + memberImportTagExceptButton.setIcon(new ImageIcon(getClass().getResource("/icon/remove_dark.png"))); + memberImportTagExceptButton.setText("排除选择的标签分组"); + importFromWeixinPanel.add(memberImportTagExceptButton, new GridConstraints(3, 0, 1, 3, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); final JLabel label2 = new JLabel(); label2.setText("标签分组"); importFromWeixinPanel.add(label2, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); diff --git a/src/main/java/com/fangxuele/tool/push/ui/listener/MemberListener.java b/src/main/java/com/fangxuele/tool/push/ui/listener/MemberListener.java index 509301335..b70e46ba5 100644 --- a/src/main/java/com/fangxuele/tool/push/ui/listener/MemberListener.java +++ b/src/main/java/com/fangxuele/tool/push/ui/listener/MemberListener.java @@ -247,6 +247,33 @@ public void keyReleased(KeyEvent evt) { } })); + // 公众号-排除选择的标签分组用户按钮事件 + memberForm.getMemberImportTagExceptButton().addActionListener(e -> ThreadUtil.execute(() -> { + try { + if (memberForm.getMemberImportTagComboBox().getSelectedItem() != null + && StringUtils.isNotEmpty(memberForm.getMemberImportTagComboBox().getSelectedItem().toString())) { + + long selectedTagId = userTagMap.get(memberForm.getMemberImportTagComboBox().getSelectedItem()); + removeMpUserListByTag(selectedTagId); + renderMemberListTable(); + JOptionPane.showMessageDialog(memberPanel, "导入完成!", "完成", + JOptionPane.INFORMATION_MESSAGE); + } else { + JOptionPane.showMessageDialog(memberPanel, "请先选择需要导入的标签!", "提示", + JOptionPane.INFORMATION_MESSAGE); + } + } catch (WxErrorException e1) { + JOptionPane.showMessageDialog(memberPanel, "导入失败!\n\n" + e1.getMessage(), "失败", + JOptionPane.ERROR_MESSAGE); + logger.error(e1); + e1.printStackTrace(); + } finally { + progressBar.setIndeterminate(false); + progressBar.setValue(progressBar.getMaximum()); + progressBar.setVisible(false); + } + })); + // 公众号-清空本地缓存按钮事件 memberForm.getClearDbCacheButton().addActionListener(e -> { int count = tWxMpUserMapper.deleteAll(); @@ -989,6 +1016,63 @@ public static void getMpUserListByTag(Long tagId, boolean retain) throws WxError } + /** + * 排除所选标签 + * + * @param tagId + * @throws WxErrorException + */ + private static void removeMpUserListByTag(long tagId) throws WxErrorException { + JProgressBar progressBar = MemberForm.getInstance().getMemberTabImportProgressBar(); + JLabel memberCountLabel = MemberForm.getInstance().getMemberTabCountLabel(); + + progressBar.setVisible(true); + progressBar.setIndeterminate(true); + + WxMpService wxMpService = WxMpTemplateMsgSender.getWxMpService(); + if (wxMpService.getWxMpConfigStorage() == null) { + return; + } + + WxTagListUser wxTagListUser = wxMpService.getUserTagService().tagListUser(tagId, ""); + + ConsoleUtil.consoleWithLog("拉取的OPENID个数:" + wxTagListUser.getCount()); + + if (wxTagListUser.getCount() == 0) { + return; + } + + List openIds = wxTagListUser.getData().getOpenidList(); + + if (tagUserSet == null) { + tagUserSet = Collections.synchronizedSet(new HashSet<>()); + openIds.forEach(tagUserSet::remove); + } + + while (StringUtils.isNotEmpty(wxTagListUser.getNextOpenid())) { + wxTagListUser = wxMpService.getUserTagService().tagListUser(tagId, wxTagListUser.getNextOpenid()); + + ConsoleUtil.consoleWithLog("拉取的OPENID个数:" + wxTagListUser.getCount()); + + if (wxTagListUser.getCount() == 0) { + break; + } + openIds = wxTagListUser.getData().getOpenidList(); + + openIds.forEach(tagUserSet::remove); + } + + PushData.allUser = Collections.synchronizedList(new ArrayList<>()); + for (String openId : tagUserSet) { + PushData.allUser.add(new String[]{openId}); + } + + memberCountLabel.setText(String.valueOf(PushData.allUser.size())); + progressBar.setIndeterminate(false); + progressBar.setValue(progressBar.getMaximum()); + + } + /** * 获取导入数据信息列表 */ diff --git a/src/main/resources/version_summary.json b/src/main/resources/version_summary.json index bdf479071..94ef24418 100644 --- a/src/main/resources/version_summary.json +++ b/src/main/resources/version_summary.json @@ -1,5 +1,5 @@ { - "currentVersion": "v_4.4.1_210323", + "currentVersion": "v_4.4.2_210628", "versionIndex": { "v_1.1.0_170701": "0", "v_1.2.0_170831": "1", @@ -48,7 +48,8 @@ "v_4.2.5_210117": "44", "v_4.3.0_210123": "45", "v_4.4.0_210221": "46", - "v_4.4.1_210323": "47" + "v_4.4.1_210323": "47", + "v_4.4.2_210628": "48" }, "versionDetailList": [ { @@ -290,6 +291,11 @@ "version": "v_4.4.1_210323", "title": "新增支持公众号订阅通知", "log": "● feature:新增支持公众号订阅通知\n● feature:支持可设置关闭窗口时最小化到系统托盘\n" + }, + { + "version": "v_4.4.2_210628", + "title": "通过公众号导入支持排除分组", + "log": "● feature:通过公众号导入支持排除分组\n" } ] } \ No newline at end of file From 742898be72d14493590095553c26ddb93e365196 Mon Sep 17 00:00:00 2001 From: zhoubo58 Date: Fri, 2 Jul 2021 10:50:06 +0800 Subject: [PATCH 09/19] =?UTF-8?q?=E9=80=9A=E8=BF=87=E5=85=AC=E4=BC=97?= =?UTF-8?q?=E5=8F=B7=E5=AF=BC=E5=85=A5=E6=94=AF=E6=8C=81=E6=8E=92=E9=99=A4?= =?UTF-8?q?=E5=88=86=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tool/push/ui/listener/MemberListener.java | 28 ++++--------------- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/src/main/java/com/fangxuele/tool/push/ui/listener/MemberListener.java b/src/main/java/com/fangxuele/tool/push/ui/listener/MemberListener.java index b70e46ba5..c7dc83aa8 100644 --- a/src/main/java/com/fangxuele/tool/push/ui/listener/MemberListener.java +++ b/src/main/java/com/fangxuele/tool/push/ui/listener/MemberListener.java @@ -35,11 +35,7 @@ import com.fangxuele.tool.push.ui.form.MemberForm; import com.fangxuele.tool.push.ui.form.msg.DingMsgForm; import com.fangxuele.tool.push.ui.form.msg.WxCpMsgForm; -import com.fangxuele.tool.push.util.ConsoleUtil; -import com.fangxuele.tool.push.util.FileCharSetUtil; -import com.fangxuele.tool.push.util.HikariUtil; -import com.fangxuele.tool.push.util.JTableUtil; -import com.fangxuele.tool.push.util.MybatisUtil; +import com.fangxuele.tool.push.util.*; import com.google.common.collect.Maps; import com.opencsv.CSVReader; import com.opencsv.CSVWriter; @@ -65,21 +61,10 @@ import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; -import java.io.BufferedReader; -import java.io.DataInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStreamReader; +import java.io.*; import java.sql.Connection; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; /** @@ -890,7 +875,6 @@ public static void getMpUserList() throws WxErrorException { * 按标签拉取公众平台用户列表 * * @param tagId - * @param retain 是否取交集 * @throws WxErrorException */ public static void getMpUserListByTag(Long tagId) throws WxErrorException { @@ -1044,10 +1028,8 @@ private static void removeMpUserListByTag(long tagId) throws WxErrorException { List openIds = wxTagListUser.getData().getOpenidList(); - if (tagUserSet == null) { - tagUserSet = Collections.synchronizedSet(new HashSet<>()); - openIds.forEach(tagUserSet::remove); - } + tagUserSet = PushData.allUser.stream().map(e -> e[0]).collect(Collectors.toSet()); + openIds.forEach(tagUserSet::remove); while (StringUtils.isNotEmpty(wxTagListUser.getNextOpenid())) { wxTagListUser = wxMpService.getUserTagService().tagListUser(tagId, wxTagListUser.getNextOpenid()); From ade1f914995d94041c3534ad4d0dfae09dc3cbe1 Mon Sep 17 00:00:00 2001 From: zhoubo58 Date: Mon, 5 Jul 2021 09:41:01 +0800 Subject: [PATCH 10/19] =?UTF-8?q?=E5=8D=87=E7=BA=A7flatlaf=E7=89=88?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index cf1175da3..caf35d546 100644 --- a/pom.xml +++ b/pom.xml @@ -47,7 +47,7 @@ 1.1.0 0.10.134 7.3.0 - 1.1 + 1.3 From e462b7efc5738bf5c9bf5e1d7b401612dae3ac32 Mon Sep 17 00:00:00 2001 From: RememBerBer Date: Fri, 26 Nov 2021 23:10:28 +0800 Subject: [PATCH 11/19] =?UTF-8?q?=E6=9B=B4=E6=8D=A2=E6=89=93=E5=8C=85?= =?UTF-8?q?=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/linux/WePush.png | Bin 0 -> 39936 bytes assets/mac/WePush.icns | Bin 0 -> 40789 bytes assets/windows/WePush.ico | Bin 0 -> 67646 bytes pom.xml | 90 +++++++++++------- .../fangxuele/tool/push/util/ConfigUtil.java | 2 +- 5 files changed, 55 insertions(+), 37 deletions(-) create mode 100644 assets/linux/WePush.png create mode 100644 assets/mac/WePush.icns create mode 100644 assets/windows/WePush.ico diff --git a/assets/linux/WePush.png b/assets/linux/WePush.png new file mode 100644 index 0000000000000000000000000000000000000000..95e911a3968ee5239385823fd5cada7dc9a25d71 GIT binary patch literal 39936 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 literal 0 HcmV?d00001 diff --git a/assets/mac/WePush.icns b/assets/mac/WePush.icns new file mode 100644 index 0000000000000000000000000000000000000000..5a369256d5ddd0ffee0280ec5205b99830aba885 GIT binary patch literal 40789 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 F|Jjia8Djtd literal 0 HcmV?d00001 diff --git a/assets/windows/WePush.ico b/assets/windows/WePush.ico new file mode 100644 index 0000000000000000000000000000000000000000..e02dd461def2ca446d1ca3d3889dce9663eb87ae GIT binary patch literal 67646 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 literal 0 HcmV?d00001 diff --git a/pom.xml b/pom.xml index afc44587b..5825205a1 100644 --- a/pom.xml +++ b/pom.xml @@ -36,7 +36,7 @@ 1.0.6 1.2.7 2.2 - 1.18.14 + 1.18.22 3.5.6 3.34.0 4.13.1 @@ -47,7 +47,7 @@ 1.1.0 0.10.134 7.3.0 - 1.0 + 1.6.4 @@ -410,52 +410,70 @@ - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.1 - - 1.8 - 1.8 - UTF-8 - - - org.apache.maven.plugins - maven-javadoc-plugin - 3.1.0 - - - - org.apache.maven.plugins - maven-jar-plugin - 3.1.2 + io.github.fvarrui + javapackager + 1.6.2 - - - true - lib/ - com.fangxuele.tool.push.App - - + true + com.fangxuele.tool.push.App + true - - - org.apache.maven.plugins - maven-dependency-plugin - 3.1.1 - copy-dependencies + bundling-for-windows package - copy-dependencies + package - ${project.build.directory}/lib + windows + true + + + + + true + true + true + + + installForAllUsers + true + false + false + + compiler:Default.isl + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/fangxuele/tool/push/util/ConfigUtil.java b/src/main/java/com/fangxuele/tool/push/util/ConfigUtil.java index 02aed251e..5315236a9 100644 --- a/src/main/java/com/fangxuele/tool/push/util/ConfigUtil.java +++ b/src/main/java/com/fangxuele/tool/push/util/ConfigUtil.java @@ -663,7 +663,7 @@ public void setMysqlPassword(String mysqlPassword) { } public String getTheme() { - return setting.getStr("theme", "setting.appearance", "Darcula(推荐)"); + return setting.getStr("theme", "setting.appearance", "Flat Dark"); } public void setTheme(String theme) { From 4ae487c080fdf3597848c047ce4478969a72f820 Mon Sep 17 00:00:00 2001 From: rememberber Date: Sat, 27 Nov 2021 09:22:33 +0800 Subject: [PATCH 12/19] =?UTF-8?q?=E6=9B=B4=E6=8D=A2=E6=89=93=E5=8C=85?= =?UTF-8?q?=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 83 ++++++++++--------- .../tool/push/ui/frame/MainFrame.java | 33 ++------ 2 files changed, 51 insertions(+), 65 deletions(-) diff --git a/pom.xml b/pom.xml index 5825205a1..d3a9f9a96 100644 --- a/pom.xml +++ b/pom.xml @@ -421,35 +421,35 @@ true - - bundling-for-windows - package - - package - - - windows - true - - - - - true - true - true - - - installForAllUsers - true - false - false - - compiler:Default.isl - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -462,18 +462,19 @@ - - - - - - - - - - - - + + bundling-for-mac + package + + package + + + mac + true + false + + + diff --git a/src/main/java/com/fangxuele/tool/push/ui/frame/MainFrame.java b/src/main/java/com/fangxuele/tool/push/ui/frame/MainFrame.java index 47043fca3..ec9ae5dce 100644 --- a/src/main/java/com/fangxuele/tool/push/ui/frame/MainFrame.java +++ b/src/main/java/com/fangxuele/tool/push/ui/frame/MainFrame.java @@ -1,24 +1,9 @@ package com.fangxuele.tool.push.ui.frame; import cn.hutool.core.thread.ThreadUtil; -import com.apple.eawt.Application; import com.fangxuele.tool.push.ui.UiConsts; -import com.fangxuele.tool.push.ui.listener.AboutListener; -import com.fangxuele.tool.push.ui.listener.BoostListener; -import com.fangxuele.tool.push.ui.listener.FrameListener; -import com.fangxuele.tool.push.ui.listener.HelpListener; -import com.fangxuele.tool.push.ui.listener.InfinityListener; -import com.fangxuele.tool.push.ui.listener.MemberListener; -import com.fangxuele.tool.push.ui.listener.MessageEditListener; -import com.fangxuele.tool.push.ui.listener.MessageManageListener; -import com.fangxuele.tool.push.ui.listener.MessageTypeListener; -import com.fangxuele.tool.push.ui.listener.PushHisListener; -import com.fangxuele.tool.push.ui.listener.PushListener; -import com.fangxuele.tool.push.ui.listener.ScheduleListener; -import com.fangxuele.tool.push.ui.listener.SettingListener; -import com.fangxuele.tool.push.ui.listener.TabListener; +import com.fangxuele.tool.push.ui.listener.*; import com.fangxuele.tool.push.util.ComponentUtil; -import com.fangxuele.tool.push.util.SystemUtil; import org.apache.commons.compress.utils.Lists; import javax.swing.*; @@ -52,14 +37,14 @@ public void init() { images.add(UiConsts.IMAGE_LOGO_16); this.setIconImages(images); // Mac系统Dock图标 - if (SystemUtil.isMacOs()) { - Application application = Application.getApplication(); - application.setDockIconImage(UiConsts.IMAGE_LOGO_1024); - if (!SystemUtil.isMacM1()) { - application.setEnabledAboutMenu(false); - application.setEnabledPreferencesMenu(false); - } - } +// if (SystemUtil.isMacOs()) { +// Application application = Application.getApplication(); +// application.setDockIconImage(UiConsts.IMAGE_LOGO_1024); +// if (!SystemUtil.isMacM1()) { +// application.setEnabledAboutMenu(false); +// application.setEnabledPreferencesMenu(false); +// } +// } ComponentUtil.setPreferSizeAndLocateToCenter(this, 0.8, 0.88); } From 7ff45245f0becf83e76ef531eadb96ee71af2191 Mon Sep 17 00:00:00 2001 From: RememBerBer Date: Thu, 2 Dec 2021 13:15:58 +0800 Subject: [PATCH 13/19] =?UTF-8?q?=E6=9B=B4=E6=8D=A2=E6=89=93=E5=8C=85?= =?UTF-8?q?=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 100 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 52 insertions(+), 48 deletions(-) diff --git a/pom.xml b/pom.xml index d3a9f9a96..e7cffa8ee 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.fangxuele.tool WePush - 1.0 + 4.4.0 jar WePush @@ -285,11 +285,11 @@ httpasyncclient ${httpasyncclient.version} - - com.zaxxer - HikariCP - ${HikariCP.version} - + + + + + org.quartz-scheduler quartz @@ -391,6 +391,10 @@ hbase-client org.apache.hbase + + bcprov-jdk15on + org.bouncycastle + @@ -421,35 +425,35 @@ true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + bundling-for-windows + package + + package + + + windows + true + + + + + true + true + true + + + installForAllUsers + true + false + false + + compiler:Default.isl + + + + + @@ -462,19 +466,19 @@ - - bundling-for-mac - package - - package - - - mac - true - false - - - + + + + + + + + + + + + + From e981a161bbf5265b5ce8cb21dc02c9af856a9e9a Mon Sep 17 00:00:00 2001 From: RememBerBer Date: Wed, 22 Dec 2021 14:40:50 +0800 Subject: [PATCH 14/19] =?UTF-8?q?=E5=8D=87=E7=BA=A7flatlaf=E8=87=B32.0-rc1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e7cffa8ee..60d70f230 100644 --- a/pom.xml +++ b/pom.xml @@ -47,7 +47,7 @@ 1.1.0 0.10.134 7.3.0 - 1.6.4 + 2.0-rc1 From 836fd78853acb12fcb1eccd9ae96d376157b0aea Mon Sep 17 00:00:00 2001 From: rememberber Date: Thu, 6 Jan 2022 23:49:35 +0800 Subject: [PATCH 15/19] =?UTF-8?q?MacOS=E4=B8=8B=E7=AA=97=E5=8F=A3=E9=A2=9C?= =?UTF-8?q?=E8=89=B2=E8=B7=9F=E9=9A=8F=E7=B3=BB=E7=BB=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/fangxuele/tool/push/App.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/com/fangxuele/tool/push/App.java b/src/main/java/com/fangxuele/tool/push/App.java index 0ec0a54a2..5434250a2 100644 --- a/src/main/java/com/fangxuele/tool/push/App.java +++ b/src/main/java/com/fangxuele/tool/push/App.java @@ -1,12 +1,14 @@ package com.fangxuele.tool.push; import com.fangxuele.tool.push.ui.Init; +import com.fangxuele.tool.push.ui.UiConsts; import com.fangxuele.tool.push.ui.form.LoadingForm; import com.fangxuele.tool.push.ui.form.MainWindow; import com.fangxuele.tool.push.ui.frame.MainFrame; import com.fangxuele.tool.push.util.ConfigUtil; import com.fangxuele.tool.push.util.MybatisUtil; import com.fangxuele.tool.push.util.UpgradeUtil; +import com.formdev.flatlaf.util.SystemInfo; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.session.SqlSession; @@ -34,6 +36,15 @@ public class App { public static TrayIcon trayIcon; public static void main(String[] args) { + if (SystemInfo.isMacOS) { +// java -Xdock:name="WePush" -Xdock:icon=WePush.jpg ... (whatever else you normally specify here) +// java -Xms64m -Xmx256m -Dapple.awt.application.name="WePush" -Dcom.apple.mrj.application.apple.menu.about.name="WePush" -cp "./lib/*" com.luoboduner.moo.tool.App + System.setProperty("apple.laf.useScreenMenuBar", "true"); + System.setProperty("apple.awt.application.name", UiConsts.APP_NAME); + System.setProperty("com.apple.mrj.application.apple.menu.about.name", UiConsts.APP_NAME); + System.setProperty("apple.awt.application.appearance", "system"); + } + Init.initTheme(); mainFrame = new MainFrame(); mainFrame.init(); From 15f4f09029c4a90a62afe0582f976bf33ebafde2 Mon Sep 17 00:00:00 2001 From: rememberber Date: Fri, 7 Jan 2022 22:21:16 +0800 Subject: [PATCH 16/19] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E9=83=A8=E5=88=86?= =?UTF-8?q?=E4=B8=BB=E9=A2=98=E9=A3=8E=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 42 ---------------- .../java/com/fangxuele/tool/push/ui/Init.java | 48 +++++++++---------- 2 files changed, 24 insertions(+), 66 deletions(-) diff --git a/pom.xml b/pom.xml index 0f91f3c2d..d910e3c9e 100644 --- a/pom.xml +++ b/pom.xml @@ -221,18 +221,6 @@ - - com.darcula - darcula-lnf - 1.0 - - - - com.beautyeye - beautyeye-lnf - 1.0 - - net.sourceforge.cpdetector @@ -487,36 +475,6 @@ maven-install-plugin 2.5.2 - - install-beautyeye - clean - - lib/beautyeye_lnf.jar - com.beautyeye - beautyeye-lnf - 1.0 - jar - true - - - install-file - - - - install-darcula - clean - - lib/darcula.jar - com.darcula - darcula-lnf - 1.0 - jar - true - - - install-file - - install-taobao-sdk-auto clean diff --git a/src/main/java/com/fangxuele/tool/push/ui/Init.java b/src/main/java/com/fangxuele/tool/push/ui/Init.java index bd8096b83..06ab0e71a 100644 --- a/src/main/java/com/fangxuele/tool/push/ui/Init.java +++ b/src/main/java/com/fangxuele/tool/push/ui/Init.java @@ -5,19 +5,7 @@ import cn.hutool.log.LogFactory; import com.fangxuele.tool.push.App; import com.fangxuele.tool.push.ui.dialog.FontSizeAdjustDialog; -import com.fangxuele.tool.push.ui.form.AboutForm; -import com.fangxuele.tool.push.ui.form.BoostForm; -import com.fangxuele.tool.push.ui.form.HelpForm; -import com.fangxuele.tool.push.ui.form.InfinityForm; -import com.fangxuele.tool.push.ui.form.MainWindow; -import com.fangxuele.tool.push.ui.form.MemberForm; -import com.fangxuele.tool.push.ui.form.MessageEditForm; -import com.fangxuele.tool.push.ui.form.MessageManageForm; -import com.fangxuele.tool.push.ui.form.MessageTypeForm; -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; +import com.fangxuele.tool.push.ui.form.*; import com.fangxuele.tool.push.ui.listener.AboutListener; import com.fangxuele.tool.push.util.SystemUtil; import com.fangxuele.tool.push.util.UIUtil; @@ -26,7 +14,6 @@ import com.formdev.flatlaf.IntelliJTheme; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.exception.ExceptionUtils; -import org.jb2011.lnf.beautyeye.BeautyEyeLNFHelper; import javax.swing.*; import javax.swing.plaf.FontUIResource; @@ -115,21 +102,13 @@ public static void initTheme() { return; } + UIManager.put("TitlePane.unifiedBackground", true); + try { switch (App.config.getTheme()) { - case "BeautyEye": - BeautyEyeLNFHelper.launchBeautyEyeLNF(); - UIManager.put("RootPane.setupButtonVisible", false); - break; case "系统默认": UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); break; - case "weblaf": - case "Darcula": - JFrame.setDefaultLookAndFeelDecorated(false); - JDialog.setDefaultLookAndFeelDecorated(false); - UIManager.setLookAndFeel("com.bulenkov.darcula.DarculaLaf"); - break; case "Flat Light": if (SystemUtil.isJBR()) { JFrame.setDefaultLookAndFeelDecorated(true); @@ -157,6 +136,23 @@ public static void initTheme() { JDialog.setDefaultLookAndFeelDecorated(true); } UIManager.setLookAndFeel("com.formdev.flatlaf.FlatDarculaLaf"); +// UIManager.put( "TitlePane.unifiedBackground", true ); +/** + If you don't like/want it, you can disable it with: + UIManager.put( "TitlePane.useWindowDecorations", false ); + + It is also possible to disable only the embedded menu bar (and keep the dark title pane) with: + UIManager.put( "TitlePane.menuBarEmbedded", false ); + + It is also possible to disable this on command line with following VM options: + -Dflatlaf.useWindowDecorations=false + -Dflatlaf.menuBarEmbedded=false + + If you have following code in your app, you can remove it (no longer necessary): + // enable window decorations + JFrame.setDefaultLookAndFeelDecorated( true ); + JDialog.setDefaultLookAndFeelDecorated( true ); + **/ break; case "Dark purple": if (SystemUtil.isJBR()) { @@ -183,6 +179,10 @@ public static void initTheme() { "/theme/Light.theme.json")); break; + case "BeautyEye": + case "weblaf": + case "Darcula": + case "Darcula(推荐)": default: if (SystemUtil.isJBR()) { JFrame.setDefaultLookAndFeelDecorated(true); From ef887d10aeb376a1d714b17e6a3af3a6dd669a2e Mon Sep 17 00:00:00 2001 From: rememberber Date: Fri, 7 Jan 2022 22:33:25 +0800 Subject: [PATCH 17/19] 4.5.0 release --- pom.xml | 2 +- src/main/java/com/fangxuele/tool/push/ui/UiConsts.java | 2 +- src/main/resources/version_summary.json | 10 ++++++++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index d910e3c9e..0b7f6dcd0 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.fangxuele.tool WePush - 4.4.0 + 4.5.0 jar WePush diff --git a/src/main/java/com/fangxuele/tool/push/ui/UiConsts.java b/src/main/java/com/fangxuele/tool/push/ui/UiConsts.java index 26049602f..9c822cd29 100644 --- a/src/main/java/com/fangxuele/tool/push/ui/UiConsts.java +++ b/src/main/java/com/fangxuele/tool/push/ui/UiConsts.java @@ -16,7 +16,7 @@ public class UiConsts { * 软件名称,版本 */ public final static String APP_NAME = "WePush"; - public final static String APP_VERSION = "v_4.4.0_210221"; + public final static String APP_VERSION = "v_4.5.0_220107"; /** * Logo-1024*1024 diff --git a/src/main/resources/version_summary.json b/src/main/resources/version_summary.json index a20ddb4bc..15408020c 100644 --- a/src/main/resources/version_summary.json +++ b/src/main/resources/version_summary.json @@ -1,5 +1,5 @@ { - "currentVersion": "v_4.4.0_210221", + "currentVersion": "v_4.5.0_220107", "versionIndex": { "v_1.1.0_170701": "0", "v_1.2.0_170831": "1", @@ -47,7 +47,8 @@ "v_4.2.4_201222": "43", "v_4.2.5_210117": "44", "v_4.3.0_210123": "45", - "v_4.4.0_210221": "46" + "v_4.4.0_210221": "46", + "v_4.5.0_220107": "47" }, "versionDetailList": [ { @@ -284,6 +285,11 @@ "version": "v_4.4.0_210221", "title": "客服消息小程序卡片类型支持上传图片", "log": "● feature:客服消息小程序卡片类型支持上传图片\n● feature:邮件消息支持添加多个附件\n● optimization:调整邮件html在线编辑器为kindeditor\n● optimization:调整默认推荐主题,修复窗口自动最大化表现异常的问题,修复点击消息管理列表经常报错的问题,优化Linux系统兼容性等各种细节优化\n" + }, + { + "version": "v_4.5.0_220107", + "title": "调整打包方式", + "log": "● 调整打包方式,内置运行环境,各平台安装更便捷\n● 移除了一部分不好用的主题风格\n" } ] } \ No newline at end of file From 84b2e07e5b6e5cc69afad171af8b21a7bcec2c00 Mon Sep 17 00:00:00 2001 From: rememberber Date: Sun, 9 Jan 2022 09:26:49 +0800 Subject: [PATCH 18/19] sync with gitee --- assets/linux/WePush.png | Bin 0 -> 39936 bytes assets/mac/WePush.icns | Bin 0 -> 40789 bytes assets/windows/WePush.ico | Bin 0 -> 67646 bytes pom.xml | 105 +++++++++++------- .../tool/push/ui/frame/MainFrame.java | 33 ++---- .../fangxuele/tool/push/util/ConfigUtil.java | 2 +- 6 files changed, 72 insertions(+), 68 deletions(-) create mode 100644 assets/linux/WePush.png create mode 100644 assets/mac/WePush.icns create mode 100644 assets/windows/WePush.ico diff --git a/assets/linux/WePush.png b/assets/linux/WePush.png new file mode 100644 index 0000000000000000000000000000000000000000..95e911a3968ee5239385823fd5cada7dc9a25d71 GIT binary patch literal 39936 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 literal 0 HcmV?d00001 diff --git a/assets/mac/WePush.icns b/assets/mac/WePush.icns new file mode 100644 index 0000000000000000000000000000000000000000..5a369256d5ddd0ffee0280ec5205b99830aba885 GIT binary patch literal 40789 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 F|Jjia8Djtd literal 0 HcmV?d00001 diff --git a/assets/windows/WePush.ico b/assets/windows/WePush.ico new file mode 100644 index 0000000000000000000000000000000000000000..e02dd461def2ca446d1ca3d3889dce9663eb87ae GIT binary patch literal 67646 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 literal 0 HcmV?d00001 diff --git a/pom.xml b/pom.xml index afc44587b..d3a9f9a96 100644 --- a/pom.xml +++ b/pom.xml @@ -36,7 +36,7 @@ 1.0.6 1.2.7 2.2 - 1.18.14 + 1.18.22 3.5.6 3.34.0 4.13.1 @@ -47,7 +47,7 @@ 1.1.0 0.10.134 7.3.0 - 1.0 + 1.6.4 @@ -410,52 +410,71 @@ - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.1 - - 1.8 - 1.8 - UTF-8 - - - org.apache.maven.plugins - maven-javadoc-plugin - 3.1.0 - - - - org.apache.maven.plugins - maven-jar-plugin - 3.1.2 + io.github.fvarrui + javapackager + 1.6.2 - - - true - lib/ - com.fangxuele.tool.push.App - - + true + com.fangxuele.tool.push.App + true - - - org.apache.maven.plugins - maven-dependency-plugin - 3.1.1 - - copy-dependencies - package - - copy-dependencies - - - ${project.build.directory}/lib - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bundling-for-mac + package + + package + + + mac + true + false + + + diff --git a/src/main/java/com/fangxuele/tool/push/ui/frame/MainFrame.java b/src/main/java/com/fangxuele/tool/push/ui/frame/MainFrame.java index 47043fca3..ec9ae5dce 100644 --- a/src/main/java/com/fangxuele/tool/push/ui/frame/MainFrame.java +++ b/src/main/java/com/fangxuele/tool/push/ui/frame/MainFrame.java @@ -1,24 +1,9 @@ package com.fangxuele.tool.push.ui.frame; import cn.hutool.core.thread.ThreadUtil; -import com.apple.eawt.Application; import com.fangxuele.tool.push.ui.UiConsts; -import com.fangxuele.tool.push.ui.listener.AboutListener; -import com.fangxuele.tool.push.ui.listener.BoostListener; -import com.fangxuele.tool.push.ui.listener.FrameListener; -import com.fangxuele.tool.push.ui.listener.HelpListener; -import com.fangxuele.tool.push.ui.listener.InfinityListener; -import com.fangxuele.tool.push.ui.listener.MemberListener; -import com.fangxuele.tool.push.ui.listener.MessageEditListener; -import com.fangxuele.tool.push.ui.listener.MessageManageListener; -import com.fangxuele.tool.push.ui.listener.MessageTypeListener; -import com.fangxuele.tool.push.ui.listener.PushHisListener; -import com.fangxuele.tool.push.ui.listener.PushListener; -import com.fangxuele.tool.push.ui.listener.ScheduleListener; -import com.fangxuele.tool.push.ui.listener.SettingListener; -import com.fangxuele.tool.push.ui.listener.TabListener; +import com.fangxuele.tool.push.ui.listener.*; import com.fangxuele.tool.push.util.ComponentUtil; -import com.fangxuele.tool.push.util.SystemUtil; import org.apache.commons.compress.utils.Lists; import javax.swing.*; @@ -52,14 +37,14 @@ public void init() { images.add(UiConsts.IMAGE_LOGO_16); this.setIconImages(images); // Mac系统Dock图标 - if (SystemUtil.isMacOs()) { - Application application = Application.getApplication(); - application.setDockIconImage(UiConsts.IMAGE_LOGO_1024); - if (!SystemUtil.isMacM1()) { - application.setEnabledAboutMenu(false); - application.setEnabledPreferencesMenu(false); - } - } +// if (SystemUtil.isMacOs()) { +// Application application = Application.getApplication(); +// application.setDockIconImage(UiConsts.IMAGE_LOGO_1024); +// if (!SystemUtil.isMacM1()) { +// application.setEnabledAboutMenu(false); +// application.setEnabledPreferencesMenu(false); +// } +// } ComponentUtil.setPreferSizeAndLocateToCenter(this, 0.8, 0.88); } diff --git a/src/main/java/com/fangxuele/tool/push/util/ConfigUtil.java b/src/main/java/com/fangxuele/tool/push/util/ConfigUtil.java index 02aed251e..5315236a9 100644 --- a/src/main/java/com/fangxuele/tool/push/util/ConfigUtil.java +++ b/src/main/java/com/fangxuele/tool/push/util/ConfigUtil.java @@ -663,7 +663,7 @@ public void setMysqlPassword(String mysqlPassword) { } public String getTheme() { - return setting.getStr("theme", "setting.appearance", "Darcula(推荐)"); + return setting.getStr("theme", "setting.appearance", "Flat Dark"); } public void setTheme(String theme) { From cddce7715e879d2d6c779733715a4fbc7fd12085 Mon Sep 17 00:00:00 2001 From: rememberber Date: Sun, 9 Jan 2022 09:53:12 +0800 Subject: [PATCH 19/19] mac os package --- pom.xml | 80 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/pom.xml b/pom.xml index 590f87d24..822c9004d 100644 --- a/pom.xml +++ b/pom.xml @@ -413,35 +413,35 @@ true - - bundling-for-windows - package - - package - - - windows - true - - + + + + + + + + + + + - - true - true - true + + + + - - installForAllUsers - true - false - false - - compiler:Default.isl - - - - - + + + + + + + + + + + + @@ -454,19 +454,19 @@ - - - - - - - - - - - - - + + bundling-for-mac + package + + package + + + mac + true + + + +