Skip to content

Commit f43deff

Browse files
committed
feat:添加小程序码生成工具
1 parent f576faf commit f43deff

14 files changed

Lines changed: 431 additions & 0 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Default ignored files
2+
#/.gitignore
3+
/x-LiteappCode.iml
4+
/log/
5+
/target/
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
小程序码生成工具
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
LiteappCode
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
dependencies {
2+
api project(':xcore')
3+
}
4+
5+
group = 'com.xwintop'
6+
version = '0.0.1'
7+
description = 'x-LiteappCode'
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package com.xwintop.xJavaFxTool;
2+
3+
import com.xwintop.xcore.util.javafx.JavaFxSystemUtil;
4+
import javafx.application.Application;
5+
import javafx.event.EventHandler;
6+
import javafx.fxml.FXMLLoader;
7+
import javafx.scene.Parent;
8+
import javafx.scene.Scene;
9+
import javafx.stage.Stage;
10+
import javafx.stage.WindowEvent;
11+
import lombok.extern.slf4j.Slf4j;
12+
13+
import java.net.URL;
14+
import java.util.ResourceBundle;
15+
16+
@Slf4j
17+
public class LiteappCodeMain extends Application {
18+
public static void main(String[] args) {
19+
try {
20+
launch(args);
21+
} catch (Exception e) {
22+
e.printStackTrace();
23+
}
24+
}
25+
26+
@Override
27+
public void start(Stage primaryStage) throws Exception {
28+
FXMLLoader fXMLLoader = LiteappCodeMain.getFXMLLoader();
29+
ResourceBundle resourceBundle = fXMLLoader.getResources();
30+
Parent root = fXMLLoader.load();
31+
primaryStage.setResizable(true);
32+
primaryStage.setTitle(resourceBundle.getString("Title"));
33+
// primaryStage.getIcons().add(new Image("/images/icon.jpg"));
34+
double[] screenSize = JavaFxSystemUtil.getScreenSizeByScale(0.74D, 0.8D);
35+
primaryStage.setScene(new Scene(root, screenSize[0], screenSize[1]));
36+
primaryStage.show();
37+
primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
38+
@Override
39+
public void handle(WindowEvent event) {
40+
System.exit(0);
41+
}
42+
});
43+
}
44+
45+
public static FXMLLoader getFXMLLoader() {
46+
ResourceBundle resourceBundle = ResourceBundle.getBundle("locale.LiteappCode");
47+
URL url = Object.class.getResource("/com/xwintop/xJavaFxTool/fxmlView/littleTools/LiteappCode.fxml");
48+
FXMLLoader fXMLLoader = new FXMLLoader(url, resourceBundle);
49+
return fXMLLoader;
50+
}
51+
}
Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
package com.xwintop.xJavaFxTool.controller.liteappcode;
2+
3+
import java.awt.image.BufferedImage;
4+
import java.io.BufferedReader;
5+
import java.io.ByteArrayOutputStream;
6+
import java.io.DataOutputStream;
7+
import java.io.File;
8+
import java.io.IOException;
9+
import java.io.InputStream;
10+
import java.io.InputStreamReader;
11+
import java.net.HttpURLConnection;
12+
import java.net.URL;
13+
import java.util.HashMap;
14+
import java.util.Map;
15+
import java.util.ResourceBundle;
16+
17+
import javax.imageio.ImageIO;
18+
19+
import com.alibaba.fastjson2.JSON;
20+
import com.alibaba.fastjson2.JSONObject;
21+
import com.xwintop.xJavaFxTool.service.liteappcode.LiteappCodeService;
22+
import com.xwintop.xJavaFxTool.view.liteappcode.LiteappCodeView;
23+
import com.xwintop.xcore.util.javafx.AlertUtil;
24+
import com.xwintop.xcore.util.javafx.TooltipUtil;
25+
26+
import cn.hutool.core.io.FileUtil;
27+
import cn.hutool.core.util.NumberUtil;
28+
import cn.hutool.core.util.StrUtil;
29+
import cn.hutool.http.HttpUtil;
30+
import javafx.embed.swing.SwingFXUtils;
31+
import javafx.fxml.FXML;
32+
import javafx.scene.image.Image;
33+
import javafx.scene.paint.Color;
34+
import javafx.stage.FileChooser;
35+
import javafx.stage.Stage;
36+
import lombok.Getter;
37+
import lombok.Setter;
38+
import lombok.extern.slf4j.Slf4j;
39+
40+
@Getter
41+
@Setter
42+
@Slf4j
43+
public class LiteappCodeController extends LiteappCodeView {
44+
private LiteappCodeService liteappCodeService = new LiteappCodeService(this);
45+
46+
@Override
47+
public void initialize(URL location, ResourceBundle resources) {
48+
initView();
49+
initEvent();
50+
initService();
51+
}
52+
53+
private void initView() {
54+
55+
}
56+
57+
private void initEvent() {
58+
}
59+
60+
private void initService() {
61+
}
62+
63+
Map<String,String> accessTokens = new HashMap<>();
64+
65+
public InputStream getImageStream(String url) {
66+
try {
67+
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
68+
connection.setReadTimeout(5000);
69+
connection.setConnectTimeout(5000);
70+
connection.setRequestMethod("GET");
71+
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
72+
InputStream inputStream = connection.getInputStream();
73+
return inputStream;
74+
}
75+
} catch (IOException e) {
76+
System.out.println("获取网络图片出现异常,图片路径为:" + url);
77+
e.printStackTrace();
78+
}
79+
return null;
80+
}
81+
82+
@FXML
83+
public void download() {
84+
85+
FileChooser fileChooser = new FileChooser();
86+
// FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("TXT files (*.txt)", "*.txt");
87+
// fileChooser.getExtensionFilters().add(extFilter);
88+
Stage s = new Stage();
89+
File file = fileChooser.showSaveDialog(s);
90+
if (file == null)
91+
return;
92+
if(file.exists()){//文件已存在,则删除覆盖文件
93+
file.delete();
94+
}
95+
String exportFilePath = file.getAbsolutePath();
96+
System.out.println("导出文件的路径" + exportFilePath);
97+
98+
BufferedImage bImage = SwingFXUtils.fromFXImage(imgQrCode.getImage(), null);
99+
try {
100+
File outputFile = new File(exportFilePath);
101+
ImageIO.write(bImage, "png", outputFile);
102+
} catch (IOException e) {
103+
TooltipUtil.showToast("到处失败:"+e.getMessage());
104+
}
105+
//FileWriteUtil.WriteDocument(exportFilePath, sBuilder.toString());
106+
//AlertUtil.showConfirmAlert("导出成功!保存路径:\n"+exportFilePath);
107+
TooltipUtil.showToast("导出成功!保存路径:\n"+exportFilePath);
108+
}
109+
110+
static InputStream in = null;
111+
112+
@FXML
113+
public void genCode() {
114+
String appid = txtAppid.getText();
115+
String page = txtPath.getText();
116+
String secret = txtAppSecret.getText();
117+
String scence = txtScene.getText();
118+
if(StrUtil.isEmpty(appid) ||StrUtil.isEmpty(secret) ||StrUtil.isEmpty(page) ||StrUtil.isEmpty(scence)) {
119+
AlertUtil.showConfirmAlert("路径、appid、秘钥,scene都是必填参数");
120+
return;
121+
}
122+
Map<String, Object> requestParam = new HashMap<String,Object>();
123+
requestParam.put("grant_type", "client_credential");
124+
requestParam.put("appid", appid);
125+
requestParam.put("secret", secret);
126+
127+
String cacheKey = appid+"_"+secret;
128+
String accessToken = "";
129+
if(accessTokens.containsKey(cacheKey) && StrUtil.isNotBlank( accessTokens.get(cacheKey))) {
130+
accessToken = accessTokens.get(cacheKey);
131+
System.out.println("从缓存中获取"+cacheKey+" accessToken:"+accessToken);
132+
}else {
133+
String resp = HttpUtil.get("https://api.weixin.qq.com/cgi-bin/token", requestParam);
134+
135+
JSONObject jsonObject = JSON.parseObject(resp);
136+
if(!jsonObject.containsKey("access_token")) {
137+
AlertUtil.showConfirmAlert("获取access_token失败");
138+
return;
139+
}
140+
accessToken = jsonObject.getString("access_token");
141+
accessTokens.put(cacheKey,accessToken);
142+
}
143+
// sendPost 为一个请求各种接口而封装的函数,并转换JSON字符串为JSONObject
144+
145+
146+
String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token="+accessToken;
147+
148+
Map<String, Object> param = new HashMap<>();
149+
param.put("page", page); //跳转到查询物流(自定义)
150+
param.put("auto_color", true);
151+
param.put("is_hyaline", chkIsHyaline.isSelected());
152+
String widthStr = txtWidth.getText();
153+
if(NumberUtil.isInteger(widthStr)) {
154+
param.put("width", Integer.parseInt(widthStr));
155+
}else {
156+
param.put("width", 430);
157+
}
158+
159+
if(!StrUtil.isEmpty(scence)) {
160+
param.put("scene",scence);
161+
}
162+
Map<String, Object> line_color = new HashMap<>();
163+
Color c = pickColor.getValue();
164+
165+
line_color.put("r", c.getRed());
166+
line_color.put("g", c.getGreen());
167+
line_color.put("b", c.getBlue());
168+
System.out.println("调用生成微信URL接口传参:url"+url+" \r\n param:" + param);
169+
String codeRes = "";
170+
try {
171+
InputStream in = null;
172+
//{"errcode":41030,"errmsg":"invalid page hint: [AHNvcA08331090]"}
173+
Object res = send(url, JSONObject.toJSONString(param));
174+
if(res instanceof String) {
175+
JSONObject jo = JSONObject.parseObject(res.toString());
176+
if(jo.containsKey("errcode") && StrUtil.isNotBlank(jo.getString("errcode"))) {
177+
int errorCode = jo.getIntValue("errcode");
178+
switch(errorCode) {
179+
case 41030:
180+
AlertUtil.showConfirmAlert("所传page页面不存在,或者小程序没有发布");
181+
break;
182+
case 45009:
183+
AlertUtil.showConfirmAlert("调用分钟频率受限(目前5000次/分钟,会调整),如需大量小程序码,建议预生成。");
184+
break;
185+
default :
186+
AlertUtil.showConfirmAlert(jo.getString("errmsg"));
187+
}
188+
}
189+
}else{
190+
in = null;
191+
in = (InputStream)res;
192+
Image img = new Image(in);
193+
imgQrCode.setImage(img);
194+
}
195+
} catch (Exception e) {
196+
// TODO Auto-generated catch block
197+
e.printStackTrace();
198+
AlertUtil.showConfirmAlert(e.getMessage());
199+
}
200+
System.out.println(codeRes);
201+
//AlertUtil.showConfirmAlert(access_token);
202+
}
203+
204+
private Object send(String urlPath,String param) throws Exception {
205+
URL url=new URL(urlPath);
206+
HttpURLConnection httpConn=(HttpURLConnection)url.openConnection();
207+
208+
//设置参数
209+
httpConn.setDoOutput(true); //需要输出
210+
httpConn.setDoInput(true); //需要输入
211+
httpConn.setUseCaches(false); //不允许缓存
212+
httpConn.setRequestMethod("POST"); //设置POST方式连接
213+
214+
//设置请求属性
215+
httpConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
216+
httpConn.setRequestProperty("Connection", "Keep-Alive");// 维持长连接
217+
httpConn.setRequestProperty("Charset", "UTF-8");
218+
219+
//连接,也可以不用明文connect,使用下面的httpConn.getOutputStream()会自动connect
220+
httpConn.connect();
221+
222+
//建立输入流,向指向的URL传入参数
223+
DataOutputStream dos=new DataOutputStream(httpConn.getOutputStream());
224+
dos.writeBytes(param);
225+
dos.flush();
226+
dos.close();
227+
228+
//获得响应状态
229+
int resultCode=httpConn.getResponseCode();
230+
if(HttpURLConnection.HTTP_OK==resultCode){
231+
InputStream in1 = httpConn.getInputStream();
232+
long size = httpConn.getContentLengthLong();
233+
if(size<500) {
234+
BufferedReader in = new BufferedReader(new InputStreamReader(in1, "utf-8"));
235+
236+
String temp = null;
237+
StringBuffer sb = new StringBuffer();
238+
while ((temp = in.readLine()) != null) {
239+
sb.append(temp);
240+
}
241+
242+
in.close();
243+
return sb.toString();
244+
}else {
245+
return in1;
246+
}
247+
} else {
248+
return null;
249+
}
250+
}
251+
252+
public static byte[] toByteArray(InputStream input) throws IOException {
253+
ByteArrayOutputStream output = new ByteArrayOutputStream();
254+
byte[] buffer = new byte[1024*4];
255+
int n = 0;
256+
while (-1 != (n = input.read(buffer))) {
257+
output.write(buffer, 0, n);
258+
}
259+
return output.toByteArray();
260+
}
261+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.xwintop.xJavaFxTool.service.liteappcode;
2+
import com.xwintop.xJavaFxTool.controller.liteappcode.LiteappCodeController;
3+
import lombok.Getter;
4+
import lombok.Setter;
5+
import lombok.extern.slf4j.Slf4j;
6+
@Getter
7+
@Setter
8+
@Slf4j
9+
public class LiteappCodeService{
10+
private LiteappCodeController liteappCodeController;
11+
public LiteappCodeService(LiteappCodeController liteappCodeController) {
12+
this.liteappCodeController = liteappCodeController;
13+
}
14+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.xwintop.xJavaFxTool.view.liteappcode;
2+
import javafx.fxml.FXML;
3+
import javafx.fxml.Initializable;
4+
import javafx.scene.control.Button;
5+
import javafx.scene.control.CheckBox;
6+
import javafx.scene.control.ColorPicker;
7+
import javafx.scene.control.TextField;
8+
import javafx.scene.image.ImageView;
9+
import lombok.Getter;
10+
import lombok.Setter;
11+
@Getter
12+
@Setter
13+
public abstract class LiteappCodeView implements Initializable {
14+
@FXML
15+
protected TextField txtPath;
16+
17+
@FXML
18+
protected TextField txtWidth;
19+
20+
@FXML
21+
protected TextField txtAppid;
22+
@FXML
23+
protected TextField txtAppSecret;
24+
@FXML
25+
protected Button btnGen;
26+
@FXML
27+
protected ImageView imgQrCode;
28+
@FXML
29+
protected CheckBox chkIsHyaline;
30+
@FXML
31+
protected ColorPicker pickColor;
32+
@FXML
33+
protected TextField txtScene;
34+
35+
}

0 commit comments

Comments
 (0)