当前位置: 首页> 房产> 家装 > 全栈工程师工作干货总结(二)

全栈工程师工作干货总结(二)

时间:2025/7/15 9:40:53来源:https://blog.csdn.net/SJshenjian/article/details/139877647 浏览次数:0次

1. linux允许ROOT登录ftp

# 进入vsftpd目录
cd /etc/vsftpd# 查看该目录包含的文件
ls# 进入文件vsftpd.ftpusers,在root前加#注释root
vi  vsftpd.ftpusers# 进入文件vsftpd.user_list,在root前加#注释root
vi vsftpd.user_list

2. 关于只能IP访问,域名不能访问网站的解决

我买的是腾讯云的服务器Cenos 6.5系统,自己配置的DNS域名服务器,nslookup www.xuefeng66.cn能够正常解析为115.159.201.119(若是非权威解析为该结果证明解析还存在问题,需要更改/etc/resolv.conf中的服务器地址,添加你买的域名服务器地址),解析成功后,发现通过IP可以访问,但是通过域名不能访问,终于发现时tomcat的问题

在这里插入图片描述

​​3. RSA简单加密与解密

import java.io.*;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;public class RSADemo {/** 产生秘钥*/public static void generateKey() {try {// 指定算法KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");// 确定密钥大小kpg.initialize(1024);// 产生密钥对KeyPair kp = kpg.genKeyPair();// 获取公钥PublicKey publicKey = kp.getPublic();// 获取私钥PrivateKey privateKey = kp.getPrivate();// 保存公钥FileOutputStream f1 = new FileOutputStream("publicKey.dat");ObjectOutputStream o1 = new ObjectOutputStream(f1);o1.writeObject(publicKey);o1.close();f1.close();// 保存私钥FileOutputStream f2 = new FileOutputStream("privateKey.dat");ObjectOutputStream o2 = new ObjectOutputStream(f2);o2.writeObject(privateKey);o2.close();f2.close();} catch (Exception e) {e.printStackTrace();}}/** 加密*/public static void encrypt() {// 明文String s = "Hello World!";try {// 获取公钥及参数e,nFileInputStream f = new FileInputStream("publicKey.dat");ObjectInputStream oos = new ObjectInputStream(f);RSAPublicKey publicKey = (RSAPublicKey) oos.readObject();BigInteger e = publicKey.getPublicExponent();BigInteger n = publicKey.getModulus();System.out.println("参数e= " + e);System.out.println("参数n= " + n);// 获取明文byte[] content = s.getBytes("UTF-8");BigInteger m = new BigInteger(content);// 计算密文BigInteger c = m.modPow(e, n);System.out.println("密文为:" + c);// 保存密文String c1 = c.toString();BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("encrypt.dat")));out.write(c1, 0, c1.length());out.close();//一定要记得关闭,否则会出现空指针异常} catch (Exception e) {e.printStackTrace();}}public static void decrypt() {try {// 读取密文BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("encrypt.dat")));String content = br.readLine();BigInteger c = new BigInteger(content);// 读取私钥FileInputStream f1 = new FileInputStream("privateKey.dat");ObjectInputStream o1 = new ObjectInputStream(f1);RSAPrivateKey privateKey = (RSAPrivateKey) o1.readObject();// 获取私钥参数及解密BigInteger d = privateKey.getPrivateExponent();BigInteger n = privateKey.getModulus();System.out.println("参数d=" + d);System.out.println("参数n=" + n);BigInteger m = c.modPow(d, n);// 显示解密结果byte[] mt = m.toByteArray();for (int i = 0; i < mt.length; i++) {System.out.print((char) mt[i]);}} catch (Exception e) {e.printStackTrace();}}public static void main(String[] args) {try {generateKey();encrypt();decrypt();} catch (Exception e) {e.printStackTrace();}}
}

在这里插入图片描述

4. DES对称密码体系加密解密

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;public class DESDemo {/** 将字节数组转换为十六进制字符串*/public static String byteToHexString(byte[] bytes) {StringBuffer stringBuffer = new StringBuffer();for (int i = 0; i < bytes.length; i++) {String string = Integer.toHexString(0XFF & bytes[i]);if (string.length() == 1) { // 十六进制占四个字节,stringBuffer.append(0);}stringBuffer.append(string.toUpperCase());}return stringBuffer.toString();}/** 加密方法*/public static byte[] DES_CBC_Encrypt(byte[] content, byte[] keyBytes) {try {// 创建一个 DESKeySpec 对象,使用 key 中的前 8 个字节作为 DES 密钥的密钥内容DESKeySpec keySpec = new DESKeySpec(keyBytes);// 返回转换指定算法的秘密密钥的 SecretKeyFactory 对象SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");// 根据提供的密钥规范(密钥材料)生成 SecretKey 对象。SecretKey key = keyFactory.generateSecret(keySpec);// 返回实现指定转换的 Cipher 对象。Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");// 用密钥和一组算法参数初始化此 Cipher。cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(keySpec.getKey()));// 按单部分操作加密数据byte[] result = cipher.doFinal(content);return result;} catch (Exception e) {e.printStackTrace();}return null;}/** 解密方法*/public static byte[] DES_CBC_Decrypt(byte[] content, byte[] keyBytes) {try {DESKeySpec keySpec = new DESKeySpec(keyBytes);SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");SecretKey key = keyFactory.generateSecret(keySpec);Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(keyBytes));byte[] result = cipher.doFinal(content);return result;} catch (Exception e) {e.printStackTrace();}return null;}public static void main(String[] args) {String content = "aaaaaaaabbbbbbbbaaaaaaaa";String key = "01234567";System.out.println("加密前:" + byteToHexString(content.getBytes()));byte[] encrypted = DES_CBC_Encrypt(content.getBytes(), key.getBytes());System.out.println("加密后:" + byteToHexString(encrypted));byte[] decrypted = DES_CBC_Decrypt(encrypted, key.getBytes());System.out.println("解密后:" + byteToHexString(decrypted));}
}

5. 基于TCP的客户端与服务器端之间的通信

使用说明:把服务器IP地址更改为自己的服务器主机IP地址即可

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;import javax.swing.JFrame;public class Chat extends JFrame implements Runnable, ActionListener {private Panel topPanel_1, downPanel_1, midPanel_left, midPanel_right;private Label ipLabel, localNameLabel;private TextField ipTextField, localNameField;private Button createServer, searchServer, sendMessage;private TextArea text1, text2, text3, text4;private ServerSocket server;private Socket serverSocket, clientSocket;private DataOutputStream outputFromClient, outputFromServer;private DataInputStream inputToClient, inputToServer;private int scan = 2;// scan:便于区分0客户端与1服务器端的文本内容private int lock=0;//0:创建服务器  1:停止服务器/***************************** 获取主机IP 与 名称 ******************************/public String getIp() {String ip = null;try {InetAddress myLocalHost = InetAddress.getLocalHost();ip = myLocalHost.getHostAddress();} catch (UnknownHostException e) {e.printStackTrace();}return ip;}public String getName() {String name = null;try {InetAddress myLocalHost = InetAddress.getLocalHost();name = myLocalHost.getHostName();} catch (UnknownHostException e) {e.printStackTrace();}return name;}/***************************** 事件监听 *****************************/public void message() {createServer.addActionListener(this);searchServer.addActionListener(this);sendMessage.addActionListener(this);}@Overridepublic void actionPerformed(ActionEvent e) {if (e.getSource() == createServer && lock==0) {text3.setText("");text3.append("服务器名称为:" + getName() + "\n");text3.append("服务器IP为:" + getIp() + "\n");text3.append("端口号为:6666\n");text3.append("服务器已经启动,正在监听.......\n");this.startServer();scan=1;} else if(e.getSource() == createServer && lock==1){try {serverSocket.close();text3.setText("");text3.append("服务器关闭成功");lock=0;} catch (IOException e1) {text3.append("服务器关闭异常");e1.printStackTrace();}			}else if (e.getSource() == searchServer) {text4.setText("");text4.append("正在搜索服务器,请稍等.....\n");this.startClient();scan=0;} else if (e.getSource() == sendMessage) {if (scan == 1) {// 服务器端try {outputFromServer = new DataOutputStream(serverSocket.getOutputStream());String name = getName();if (text2.getText().length() > 0) {text1.append(name + "说:   " + text2.getText()+ "\n");outputFromServer.writeUTF(this.getName()+","+text2.getText());// 写入消息text2.setText("");} else {text2.setText("\n\n请输入内容\n\n");Thread.sleep(1000);text2.setText("");}} catch (InterruptedException | IOException e1) {e1.printStackTrace();}} else if (scan == 0 ) {// 客户端try {outputFromClient = new DataOutputStream(clientSocket.getOutputStream());String name = getName();if (text2.getText().length() > 0 ) {text1.append(name + "说:   " + text2.getText()+ "\n");outputFromClient.writeUTF(this.getName()+","+text2.getText());// 写入消息text2.setText("");} else if(text2.getText().length() <= 0) {text2.setText("\n\n请输入内容\n\n");Thread.sleep(1000);text2.setText("");}} catch (InterruptedException | IOException e1) {e1.printStackTrace();}}}}/***************************** 启动服务器 *************************************/public void startServer() {try {if(lock==0){server = new ServerSocket(6666);serverSocket = server.accept();createServer.setLabel("停止服务器");lock=1;}} catch (IOException e) {text3.setText("");text3.append("服务器启动错误,请重新设置后启动!\n可能是由于:\n");text3.append("1.端口被占用。\n");text3.append("2.服务器已经启动。\n");e.printStackTrace();}}/***************************** 启动客户端 *************************************/public void startClient() {try {clientSocket = new Socket("192.168.31.125",6666);//更改为自己服务器主机的IP地址即可text4.append("连接成功 ");searchServer.setLabel("断开连接");} catch (Exception e) {text4.append("无法连接网络");e.printStackTrace();}}/******************************* 对话内容互相显示 *****************************/public void messageDisplay() throws IOException {// 接收消息if (scan == 1) {// 客户端inputToClient = new DataInputStream(serverSocket.getInputStream());String receive = inputToClient.readUTF();String[] message=receive.split(",");text1.append(message[0]+"说:   "+message[1]+"\n");}else if(scan == 0){//服务器端inputToServer = new DataInputStream(clientSocket.getInputStream());String receive = inputToServer.readUTF();String[] message=receive.split(",");text1.append(message[0]+"说:   "+message[1]+"\n");}}/***************************** 创建主界面 *************************************/private void launchFrame() {// /上面部分/topPanel_1 = new Panel();ipLabel = new Label("IP地址");// 标签ipTextField = new TextField(getIp(), 19);localNameLabel = new Label("本机名称");localNameField = new TextField(getName(), 19);createServer = new Button("创建服务器");searchServer = new Button("搜索服务器");// /中部部分/midPanel_left = new Panel();midPanel_right = new Panel();text1 = new TextArea(20, 68);text2 = new TextArea(3, 68);text3 = new TextArea(14, 25);text4 = new TextArea(9, 25);// /底部部分/downPanel_1 = new Panel();sendMessage = new Button("发送");topPanel_1.add(ipLabel);// 加入面板topPanel_1.add(ipTextField);topPanel_1.add(localNameLabel);topPanel_1.add(localNameField);topPanel_1.add(createServer);topPanel_1.add(searchServer);midPanel_left.setLayout(new BorderLayout());midPanel_right.setLayout(new BorderLayout());midPanel_left.add(text1, BorderLayout.NORTH);midPanel_left.add(text2, BorderLayout.SOUTH);midPanel_right.add(text3, BorderLayout.NORTH);midPanel_right.add(text4, BorderLayout.SOUTH);downPanel_1.add(sendMessage);Container container = getContentPane();// 布局管理器container.setLayout(new BorderLayout());// 布局声明container.add(topPanel_1, BorderLayout.NORTH);container.add(midPanel_left, BorderLayout.CENTER);container.add(midPanel_right, BorderLayout.EAST);container.add(downPanel_1, BorderLayout.SOUTH);this.pack();// 调整此窗口的大小,以适合其子组件的首选大小和布局。setSize(700, 500);// 设置面板宽与高setTitle("点星光聊天");// 设置标题setResizable(false);// 大小不可变setVisible(true);// 设置面板可见this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 关闭时释放资源}public static void main(String[] args) throws IOException {Chat chat = new Chat();chat.launchFrame();chat.message();while(true){chat.messageDisplay();}}@Overridepublic void run() {// TODO 自动生成的方法存根}
}

6. 红蓝按钮交替移动

编写一个应用程序,除了主线程外,还有两个线程:first和second。first负责模拟一个红色的按钮从坐标(10,60)运动到(100,60);second负责模拟一个绿色的按钮从坐标(100,60)运动到(200,60)。另外还有一个start按钮,当点击start按钮后,红色按钮平行移动从左边移动到右边,当红色按钮移动到绿色按钮位置后,红色按钮停止在绿色按钮起始位置,然后绿色按钮接着移动。当绿色按钮移动到指定位置后,所有按钮位置重置,然后循环执行上述过程。

public class MoveButton extends JFrame implements Runnable, ActionListener {private int distance = 10;Thread first, second;Button redButton, greenButton, startButton;public MoveButton() {/** 创建线程*/first = new Thread(this);second = new Thread(this);setLayout(null); // 清除默认布局/** 设置红色按钮的颜色* 设置起始位置与大小* 加入窗体*/redButton = new Button();redButton.setBackground(Color.red);redButton.setBounds(10, 60, 15, 15);add(redButton);/** 设置红色按钮的颜色* 设置起始位置与大小* 加入窗体*/greenButton = new Button();greenButton.setBackground(Color.green);greenButton.setBounds(100, 60, 15, 15);add(greenButton);/** 设置开始按钮的起始位置与大小* 添加监听器* 加入窗体*/startButton = new Button("start");startButton.addActionListener(this);startButton.setBounds(10, 100, 30, 30);add(startButton);setBounds(0, 0, 300, 200);// 设置窗体的起始位置与长宽setVisible(true);// 设置窗体可见/** 关闭窗时释放内存资源*/addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {System.exit(0);}});}/** 实现按钮的移动* synchronized 方法控制对类成员变量的访问*/private synchronized void moveComponent(Button button) {if (Thread.currentThread() == first) {while (distance > 100 && distance <= 200) {try {wait();System.out.println("你好");//线程等待,直到其他线程调用notify或notifyAll方法通知该线程醒来} catch (InterruptedException e) {e.printStackTrace();}}distance += 1;button.setLocation(distance, 60);if (distance >= 100) {if (distance <= 200) {button.setLocation(100, 60);//在蓝色按钮运动期间红色按钮始终位于蓝色按钮最初位置} else {button.setLocation(10, 60);//当距离移动距离大于200时,蓝色按钮归位}notify();//唤醒单个等待的线程(由于约束条件的存在,此程序中势必只有一个等待的线程,故可用此方法替换)//notifyAll();//唤起全部等地的线程}}if (Thread.currentThread() == second) {while (distance >= 10 && distance < 100) {try {wait();//线程等待,直到其他线程调用notify或notifyAll方法通知该线程醒来} catch (InterruptedException e) {e.printStackTrace();}}distance += 1;button.setLocation(distance, 60);if (distance > 200) {button.setLocation(100, 60);//当距离移动距离大于200时,蓝色按钮归位distance = 10;//distance置初值notify();//}}}public void run() {while (true) {/** 判断当前执行的线程是否为first* 如果是,调用moveComponent()方法,移动redButton* 线程睡眠20ms*/if (Thread.currentThread() == first) {moveComponent(redButton);try {Thread.sleep(20);} catch (InterruptedException e) {e.printStackTrace();}}/** 判断当前执行的线程是否为second* 如果是,调用moveComponent()方法,移动greenButton* 线程睡眠10ms*/if (Thread.currentThread() == second) {moveComponent(greenButton);try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}}}}/** 事件监听,启动线程(由于只对startButton按钮绑定监听器,所以默认监听该按钮)*/public void actionPerformed(ActionEvent e) {try {first.start();//启动线程second.start();} catch (Exception e1) {e1.printStackTrace();}}public static void main(String[] args) {new MoveButton();}
}

7. JAVA根据指定URL生成二维码

public class QrCodeUtil {public static void main(String[] args) {String url = "https://www.baidu.com";String path = FileSystemView.getFileSystemView().getHomeDirectory() + File.separator + "testQrcode";String fileName = "temp.jpg";createQrCode(url, path, fileName);}public static String createQrCode(String url, String path, String fileName) {try {Map<EncodeHintType, String> hints = new HashMap<>();hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");BitMatrix bitMatrix = new MultiFormatWriter().encode(url, BarcodeFormat.QR_CODE, 400, 400, hints);File file = new File(path, fileName);if (file.exists() || ((file.getParentFile().exists() || file.getParentFile().mkdirs()) && file.createNewFile())) {writeToFile(bitMatrix, "jpg", file);System.out.println("搞定:" + file);}} catch (Exception e) {e.printStackTrace();}return null;}static void writeToFile(BitMatrix matrix, String format, File file) throws IOException {BufferedImage image = toBufferedImage(matrix);if (!ImageIO.write(image, format, file)) {throw new IOException("Could not write an image of format " + format + " to " + file);}}static void writeToStream(BitMatrix matrix, String format, OutputStream stream) throws IOException {BufferedImage image = toBufferedImage(matrix);if (!ImageIO.write(image, format, stream)) {throw new IOException("Could not write an image of format " + format);}}private static final int BLACK = 0xFF000000;private static final int WHITE = 0xFFFFFFFF;private static BufferedImage toBufferedImage(BitMatrix matrix) {int width = matrix.getWidth();int height = matrix.getHeight();BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);for (int x = 0; x < width; x++) {for (int y = 0; y < height; y++) {image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE);}}return image;}
}

8. ElementPlus中el-select在IOS中无法唤醒软件盘解决方案

项目基于Vue3 + ElementPlus1.3

在main.js代码中

import ElementPlus from 'element-plus'
/* eslint-disable no-new */
window.$vueApp = Vue.createApp(App)
// 给组件每个生命周期,都混入一些公共逻辑, 解决IOS el-select无法唤醒软件盘问题
window.$vueApp.mixin({mounted () {if (typeof this.$el.className === 'string') {if (this.$el.className.split(' ').indexOf('el-select') !== -1) {this.$el.children[0].children[0].children[0].removeAttribute('readOnly')this.$el.children[0].children[0].children[0].onblur = function () {let _this = thissetTimeout(() => {_this.removeAttribute('readOnly')}, 200)}}}}
})
window.$vueApp.use(ElementPlus)

9. JAVA流实现文件批量打包下载

    @ResponseBodypublic void downloadFiles(HttpServletRequest request, HttpServletResponse response, String[] filePaths) {if (filePaths == null || filePaths.length <= 0) {return ;}// 设置响应头response.reset();response.setCharacterEncoding("utf-8");response.setContentType("multipart/form-data");// 设置压缩包名称及不同浏览器中文乱码处理DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");LocalDateTime localDateTime = LocalDateTime.now();String filename = "电子合同" + formatter.format(localDateTime) + ".zip";String agent = request.getHeader("AGENT");try {if (agent.contains("MSIE") || agent.contains("Trident")) {filename = URLEncoder.encode(filename, "UTF-8");} else {filename = new String(filename.getBytes("UTF-8"), "ISO-8859-1");}} catch (UnsupportedEncodingException e) {e.printStackTrace();}response.setHeader("Content-Disposition", "attachment;filename=\"" + filename  + "\""); // key不区分大小写try {// 设置压缩流,直接写入response,实现边压缩边下载ZipOutputStream zipOutputStream = new ZipOutputStream(new BufferedOutputStream(response.getOutputStream()));zipOutputStream.setMethod(ZipOutputStream.DEFLATED);DataOutputStream dataOutputStream = null;for (String filePath : filePaths) {String subFilename = formatter.format(LocalDateTime.now()) + filePath.substring(filePath.lastIndexOf("/") + 1);zipOutputStream.putNextEntry(new ZipEntry(subFilename));dataOutputStream = new DataOutputStream(zipOutputStream);BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(new File(filePath)));byte[] buf = new byte[8192];int length = 0;while ((length = bufferedInputStream.read(buf)) != -1) {dataOutputStream.write(buf, 0 , length);}dataOutputStream.flush();// dataOutputStream.close(); 若在此关闭,对应资源zipOutputStream也将关闭,则压缩包内仅有一个文件bufferedInputStream.close();zipOutputStream.closeEntry();}dataOutputStream.flush();dataOutputStream.close();zipOutputStream.close();} catch (IOException e) {e.printStackTrace();}}

10. Windows10强制停止Vmmem

wsl --shutdown

11. Windows10强制删除占用端口的进程

# 查看占用端口8082的进程
netstat -ano|findstr 8082# 强制删除进程20380及子进程
taskkill /T /F /PID 20380

12. PostgreSQL强制删除数据库

12.1 设置数据库为禁止连接

UPDATE pg_database 
SET datallowconn = 'false' 
WHERE datname = 'db_name';

12.2 中断当前库中所有连接会话

SELECT pg_terminate_backend(pid) 
FROM pg_stat_activity 
WHERE datname = 'db_name';

12.3 删除数据库

drop database db_name;

13. 基于seaborn的正太分布图

import matplotlib.pyplot as plt
import seaborn as sns # rating_df类型为pandas
sns.kdeplot(rating_df['rating_our'],  fill=True,  shade=True, bw=0.8, color='#FA705C')
sns.kdeplot(rating_df['rating_customer'],  fill=True,  shade=True, bw=0.8, color='red')
plt.show()

14. 微信小程序文件下载两种方式

14.1 基本url方式下载(自定义下载文件名称)

  downloadDailyYear: function() {util.get(api.downloadDailyYear).then(function(res) { // 自定义get请求,可忽略if (res.code == 200) {var fileName = res.data.substring(res.data.lastIndexOf("/") + 1, res.data.indexOf("."));wx.downloadFile({url: api.appUrl + res.data,     // 1. 必须带有这个wx.env.USER_DATA_PATH,表示存储在用户本地 !!!// fileName表示自定的文件名称// 实际在PC端调试存储位置为类似 C:\Users\SJshe\AppData\Local\微信开发者工具\User Data\WeappFileSystem\o6zAJs3c0u3SeBVn_9MUgG6UZJ1M\wx2efdf4edd8bccb88filePath: wx.env.USER_DATA_PATH + "/" + fileName,success: function (res) {if (res.statusCode === 200) {wx.openDocument({filePath: res.filePath,fileType: ['xlsx'], // 2. 这个必须写合法类型,不然下载不了(个人认为官方应该特别说明) !!!success: function (res) {console.log('打开文档成功')},fail: function(e) {console.log(e.errMsg);}})}},fail: function(e) { // 强烈建议打印失败原因,便于排查console.log(e.errMsg);}});}});},

14.2 基于后台返回流的方式下载

@GetMapping(value = "/downloadDailyYear")
public BaseResponse<byte[]> downloadDailyYear(HttpSession session, @RequestParam String id, @RequestParam @DateTimeFormat(iso = ISO.DATE) Date startDate, @RequestParam @DateTimeFormat(iso = ISO.DATE) Date endDate) {
}
public class BaseResponse<T> {private String code;private String message;private T data;...
}
downloadDailyYear: function () {var name = '';wx.getStorage({key: 'userInfo',success(res) {name += res.data.name + res.data.employeeNo;}})var year = new Date().getFullYear();util.get(api.downloadDailyYear, {'id': wx.getStorageSync('userId'),'startDate': year + "-" + "01-01", 'endDate': year + "-" + "12-31"}).then(function (res) {if (res.code == 200) {// 1. 必须带有这个wx.env.USER_DATA_PATH,表示存储在用户本地 !!!var filePath = wx.env.USER_DATA_PATH + '/' + year + '工作周报-' + name;FileSystemManager.writeFile({filePath: filePath,data: res.data,encoding: 'base64', // 2. base64解密写入, 后台返回的byte[]数组是经过base64编码的,其他方式写入文件打开格式不对success: function(res) {wx.openDocument({filePath: wx.env.USER_DATA_PATH + '/' + year + '工作周报-' + name,fileType: ['xlsx'], // 3. 这个必须写合法类型,不然下载不了 !!!success: function (res) {console.log('打开文档成功')},fail: function (e) {console.log(e.errMsg);}})},fail: function (e) {console.log(e.errMsg);}});}});},
关键字:全栈工程师工作干货总结(二)

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: