CJ 1 an în urmă
părinte
comite
af3ab3515b
58 a modificat fișierele cu 455 adăugiri și 5 ștergeri
  1. 14 5
      _sidebar.md
  2. BIN
      project/141e6f067105de883e6bf89216c6df0.jpg
  3. BIN
      project/30c34cbc7670997a61e33413e2eb9b5.jpg
  4. BIN
      project/7dd099d4379aaadfc432dfe0326694b.png
  5. BIN
      project/828ed57b6d59414759504aafeb2a660.jpg
  6. 34 0
      project/BI报表.md
  7. 37 0
      project/EDI.md
  8. 3 0
      project/MES前端操作站.md
  9. 22 0
      project/MI系统.md
  10. 193 0
      project/PanaCIM松下扣料机服务.md
  11. 15 0
      project/WMS转码打印.md
  12. BIN
      project/WeChat_20231019204628.mp4
  13. BIN
      project/a4e62c552abd80af7f0a90bddccd74e.jpg
  14. BIN
      project/image-13.png
  15. BIN
      project/image-14.png
  16. BIN
      project/image-15.png
  17. BIN
      project/image-16.png
  18. BIN
      project/image-17.png
  19. BIN
      project/image-18.png
  20. BIN
      project/image-19.png
  21. BIN
      project/image-20.png
  22. BIN
      project/image-21.png
  23. BIN
      project/image-22.png
  24. BIN
      project/image-23.png
  25. BIN
      project/image-24.png
  26. BIN
      project/image-25.png
  27. BIN
      project/image-26.png
  28. BIN
      project/image-27.png
  29. BIN
      project/image-28.png
  30. BIN
      project/image-29.png
  31. BIN
      project/image-30.png
  32. BIN
      project/image-31.png
  33. BIN
      project/image-32.png
  34. BIN
      project/image-33.png
  35. BIN
      project/image-34.png
  36. BIN
      project/image-35.png
  37. BIN
      project/image-36.png
  38. BIN
      project/image-37.png
  39. BIN
      project/image-38.png
  40. BIN
      project/image-39.png
  41. BIN
      project/image-40.png
  42. BIN
      project/image-41.png
  43. BIN
      project/image-42.png
  44. BIN
      project/image-43.png
  45. BIN
      project/image-44.png
  46. BIN
      project/image-45.png
  47. BIN
      project/image-46.png
  48. BIN
      project/image-47.png
  49. BIN
      project/image-48.png
  50. BIN
      project/image-49.png
  51. BIN
      project/image-50.png
  52. BIN
      project/image-51.png
  53. BIN
      project/image-52.png
  54. 15 0
      project/云智高级仓储PDA(Android开发).md
  55. 24 0
      project/代码生成器.md
  56. 31 0
      project/其他项目.md
  57. 43 0
      project/小程序合集.md
  58. 24 0
      project/计划任务.md

+ 14 - 5
_sidebar.md

@@ -1,8 +1,17 @@
 <!-- docs/_sidebar.md -->
 
 * [个人简历](resume.html)
-* [软件发布及追溯系统](/project/软件发布及追溯系统.md)
-* [MES前端操作站](/project/MES前端操作站.md)
-* [Andon系统](/project/Andon系统.md)
-* [DFI友通资讯操作站](/project/DFI友通资讯操作站.md)
-* [BI报表](/project/BI报表.md)
+* [软件发布及追溯系统 2021-08](/project/软件发布及追溯系统.md)
+* [MES前端操作站 2020-2021](/project/MES前端操作站.md)
+* [PanaCIM松下扣料机服务 2020](/project/PanaCIM松下扣料机服务.md)
+* [Andon系统 2020-2021](/project/Andon系统.md)
+* [DFI友通资讯操作站 2022-2023](/project/DFI友通资讯操作站.md)
+* [WMS转码打印 2021](/project/WMS转码打印.md)
+* [BI报表 2022-2023](/project/BI报表.md)
+* [MI系统 2022-2023](/project/MI系统.md)
+* [小程序&微信网页 2022](/project/小程序合集.md)
+* [计划任务 2023](/project/计划任务.md)
+* [云智高级仓储PDA(Android开发) 2018](/project/云智高级仓储PDA(Android开发).md)
+* [代码生成器 2022](/project/代码生成器.md)
+* [EDI系统 2021-2023](/project/EDI.md)
+* [其他项目](/project/其他项目.md)

BIN
project/141e6f067105de883e6bf89216c6df0.jpg


BIN
project/30c34cbc7670997a61e33413e2eb9b5.jpg


BIN
project/7dd099d4379aaadfc432dfe0326694b.png


BIN
project/828ed57b6d59414759504aafeb2a660.jpg


+ 34 - 0
project/BI报表.md

@@ -1,2 +1,36 @@
 ## **BI报表**
 
+#### **项目介绍**
+企业报表功能一直都有这个需求,之前报表开发的较为零散,因此决定开发具有可配置,多租户,易拓展等功能的BI报表系统。
+
+#### **工作内容**
+开发BI后台,拥有基础数据维护,用户角色工厂权限控制,接口转发配置等功能。
+开发BI前台,各类报表的开发工作。
+部署至Linux。
+
+#### **技术栈**
+后台: Java 
+前台: Vue2
+数据库: SqlServer
+
+#### **功能介绍**
+BI报表服务多家企业,通过WMS提供统一的BI接口。由我负责开发BI报表系统的基础功能及报表展示层。
+权限:
+用户,角色,菜单,报表,工厂。
+其中,一个用户可以有多家工厂权限,一个工厂可以有多个报表权限。
+同一个工厂下的员工又可以配置公司拥有的报表权限。
+![Alt text](image-13.png)
+
+接口转发功能
+WMS每提供一个接口给BI调用,如果每次都要写一个API那就太麻烦了,因此做出一个API转发功能,只需在对于工厂下配置该工厂的API接口即可。
+![Alt text](image-14.png)
+![Alt text](image-15.png)
+
+#### **成果**
+目前在华域电子,天宝汽车电子等工厂生产车间电子大屏使用。
+
+#### **功能介绍-报表**
+![Alt text](image-21.png)
+![Alt text](image-16.png)
+![Alt text](image-17.png)
+![Alt text](image-18.png)

+ 37 - 0
project/EDI.md

@@ -0,0 +1,37 @@
+## **EDI 供应商业务合作伙伴**
+
+#### **江苏天宝模板开发**
+使用.NET Core 和 Vue 开发,拥有天采购需求,要货单,明细发货,送货单,收货单,条码打印,采购账单等功能。
+其中条码打印功能较为复杂,拥有很多选择条件,不同的条件打印出来的条码有差异,需要计算数量等校验。
+提交后需要在一个空白的 PDF 模板通过绝对定位将二维码,属性值如:SUP,MFG,EXP,LOT 等。
+![Alt text](image-52.png)
+代码示例:
+
+```C#
+ cb.BeginText();
+                    cb.SetFontAndSize(baseFont, 7);
+                    cb.ShowTextAligned(PdfContentByte.ALIGN_LEFT, "BIN: " + sdHu.ItemBin, 54, 30, 0);
+                    cb.EndText();
+
+                    cb.BeginText();
+                    cb.SetFontAndSize(baseFont, 7);
+                    cb.ShowTextAligned(PdfContentByte.ALIGN_LEFT, sdHu.NeedInspect ? "IQC: Y" : "IQC: N", 78, 15, 0);
+                    cb.EndText();
+
+
+                    cb.BeginText();
+                    cb.SetFontAndSize(baseFont, 7);
+                    cb.ShowTextAligned(PdfContentByte.ALIGN_LEFT, sdHu.HuId, 95, 25, 0);
+                    cb.EndText();
+
+                    QRCodeGenerator qrGenerator = new QRCoder.QRCodeGenerator();
+                    QRCodeData qrCodeData = qrGenerator.CreateQrCode(sdHu.HuId, QRCodeGenerator.ECCLevel.M);
+                    QRCode qrcode = new QRCode(qrCodeData);
+![Alt text](image-49.png)
+```
+
+#### **财务税票模块开发**
+拥有可结算清单,采购账单,采购发票,未开票明细等功能,作为项目亮点,增加了发票识别导入功能,通过在阿里云函数计算编写Python脚本,利用正则等方式将图片或PDF识别出的文本关键字筛选出来。
+我负责开发Vue界面功能和Python脚本。
+![Alt text](image-51.png)
+![Alt text](image-50.png)

+ 3 - 0
project/MES前端操作站.md

@@ -26,6 +26,9 @@
 现已在江苏天宝汽车电子有限公司,华域电子分公司,绍兴怡东汽车零配件等公司生产车间使用。
 
 #### **预览**
+
+![Alt text](image-25.png)
+
 工单执行
 ![Alt text](image.png)
 

+ 22 - 0
project/MI系统.md

@@ -0,0 +1,22 @@
+## **MI系统**
+
+#### **项目介绍**
+生产型企业智能设备管理系统,能够实时监控设备情况,对设备告警停机等情况迅速做出处理,同时分析设备节拍分析出各种报表。
+
+#### **工作内容**
+开发MI前台和后台。\
+开发基于Python的采集程序。
+
+#### **成果**
+目前在上海途胜汽车零部件有限公司使用。
+
+#### **技术栈**
+后台: Java \
+前台: Vue2\
+数据库: SqlServer PostgresSql\
+MQTT: 阿里云MQTT服务\
+采集程序: Python
+
+#### **功能介绍**
+![Alt text](7dd099d4379aaadfc432dfe0326694b.png)
+![Alt text](image-24.png)

+ 193 - 0
project/PanaCIM松下扣料机服务.md

@@ -0,0 +1,193 @@
+## **PanaCIM松下扣料机服务**
+
+#### **项目介绍**
+生产车间拥有松下扣料机设备,需要采集读取多个送下设备生产报文,数据用于MES WMS计算生产排产和报表等功能。
+
+#### **工作内容**
+搭建TCP Server框架,并在现场调通设备通信。
+
+#### **技术栈**
+C# .NET Core TCP通信框架: DotNetty
+
+#### **成果**
+目前在江苏天宝汽车电子有限公司生产服务器局域网运行。
+
+#### **难点**
+该程序将会启用一个TCP服务器,车间内的松下设备会是客户端全部与服务器进行连接,同时不断发送XML报文。需要将XML报文拼成一个完整的报文发送到接下来的Channel进行处理。
+再此期间需要编写解码器应对报文的沾包,断包,多包等问题。
+
+相关:https://cybersicko.net/article/25.html
+
+#### **代码片段(解码器)**
+```C#
+using DotNetty.Buffers;
+using DotNetty.Codecs;
+using DotNetty.Transport.Channels;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Xml;
+
+namespace He3.PanaCIM.SocketServer.Handler
+{
+    /// <summary>
+    /// 解码
+    /// </summary>
+    public class DecoderHandler : ByteToMessageDecoder
+    {
+        private static log4net.ILog log = log4net.LogManager.GetLogger("Log.DecoderHandler");
+        private IByteBuffer byteBuffer = ByteBufferUtil.DefaultAllocator.Buffer();
+
+        protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List<object> output)
+        {
+            int inputLen = input.ReadableBytes;
+            byte[] inputBytes = new byte[inputLen];
+            input.GetBytes(0, inputBytes);
+            log.Debug(context.Channel.RemoteAddress.ToString() + " Received: " + Encoding.Default.GetString(inputBytes));
+
+            #region 处理心跳
+            int pingReqBegin = ByteUtil.Search(inputBytes, ByteUtil.PING_REQ);
+            if (pingReqBegin > -1)
+            {
+                int pingReqEnd = pingReqBegin + ByteUtil.PING_REQ_LEN;
+                if (pingReqEnd == ByteUtil.PING_REQ_LEN
+                    && inputLen == ByteUtil.PING_REQ_LEN)
+                {
+                    inputBytes = new byte[0];
+                }
+                else
+                {
+                    inputBytes = inputBytes.Skip(0).Take(pingReqBegin).Concat(inputBytes.Skip(pingReqEnd)).ToArray();
+                    log.Debug(context.Channel.RemoteAddress.ToString() + " Received after skip ping:" + Encoding.Default.GetString(inputBytes));
+                }
+
+                output.Add(createResponseMessage());
+                //context.WriteAndFlushAsync(ByteBufferUtil.DefaultAllocator.Buffer().WriteBytes(ByteUtil.PING_RSP));
+            }
+            #endregion
+
+            while (inputBytes.Length > 0)
+            {
+                //log.Info("PipleLineId = " + "本次处理 : " + Encoding.Default.GetString(bytes));
+                int stxIndex = Array.IndexOf(inputBytes, ByteUtil.STX);
+                int etxIndex = Array.IndexOf(inputBytes, ByteUtil.ETX);
+
+                //缓存没有
+                if (byteBuffer.ReadableBytes == 0)
+                {
+                    //有头
+                    if (stxIndex != -1)
+                    {
+                        //有尾
+                        if (etxIndex != -1)
+                        {
+                            int shoIndex = Array.IndexOf(inputBytes, ByteUtil.SOH);
+                            byte[] bodyLen = inputBytes.Skip(stxIndex + 1).Take(shoIndex - stxIndex - 1).ToArray();
+                            byte[] message = inputBytes.Skip(shoIndex + 1).Take(etxIndex - shoIndex - 1).ToArray();
+                            output.Add(createDecodeMessage(bodyLen, message));
+
+                            inputBytes = inputBytes.Skip(etxIndex + 1).ToArray();
+                        }
+                        else
+                        {
+                            //如果stxIndex 头部前有报文,丢弃前面的报文
+                            byteBuffer.WriteBytes(inputBytes.Skip(stxIndex).ToArray());
+
+                            int tmpLen = byteBuffer.ReadableBytes;
+                            byte[] tmpBytes = new byte[tmpLen];
+                            byteBuffer.GetBytes(0, tmpBytes);
+                            //log.Info("PipleLineId = " + PipleLineId + "缓存1 : " + Encoding.Default.GetString(tmpBytes));
+
+                            inputBytes = new byte[0];
+                        }
+                    }
+                    else
+                    {
+                        //缓存为空,报文没头,跳过
+                        inputBytes = new byte[0];
+                    }
+                }
+                else
+                {
+                    if (stxIndex != -1)
+                    {
+                        if (stxIndex < etxIndex || etxIndex == -1)
+                        {
+                            int tmpLen = byteBuffer.ReadableBytes;
+                            byte[] tmpBytes = new byte[tmpLen];
+                            byteBuffer.GetBytes(0, tmpBytes);
+                            //log.Info("PipleLineId = " + PipleLineId + "丢弃 : " + Encoding.Default.GetString(tmpBytes));
+
+                            inputBytes = inputBytes.Skip(stxIndex).ToArray();
+                            byteBuffer.Clear();
+                            continue;
+                        }
+                    }
+
+                    if (etxIndex != -1)
+                    {
+                        byteBuffer.WriteBytes(inputBytes.Take(etxIndex + 1).ToArray());
+
+                        int tmpLen = byteBuffer.ReadableBytes;
+                        byte[] tmpBytes = new byte[tmpLen];
+                        byteBuffer.GetBytes(0, tmpBytes);
+                        //log.Info("PipleLineId = " + PipleLineId + "缓存3 : " + Encoding.Default.GetString(tmpBytes));
+
+                        int buffLen = byteBuffer.ReadableBytes;
+                        byte[] currentBytes = new byte[buffLen];
+                        byteBuffer.GetBytes(0, currentBytes);
+                        int shoIndex = Array.IndexOf(currentBytes, ByteUtil.SOH);
+                        byte[] bodyLen = currentBytes.Skip(1).Take(shoIndex - 1).ToArray();
+                        //byte[] message = currentBytes.Skip(shoIndex + 1).SkipLast(1).ToArray();
+                        byte[] message = currentBytes.Skip(shoIndex + 1).Take(currentBytes.Length - shoIndex - 2).ToArray();
+                        output.Add(createDecodeMessage(bodyLen, message));
+
+                        byteBuffer.Clear();
+                        inputBytes = inputBytes.Skip(etxIndex + 1).ToArray();
+                    }
+                    else
+                    {
+                        //断包 进缓冲
+                        byteBuffer.WriteBytes(inputBytes);
+                        inputBytes = new byte[0];
+
+                        int tmpLen = byteBuffer.ReadableBytes;
+                        byte[] tmpBytes = new byte[tmpLen];
+                        byteBuffer.GetBytes(0, tmpBytes);
+                        //log.Info("PipleLineId = " + PipleLineId + "缓存2 : " + Encoding.Default.GetString(tmpBytes));
+                    }
+                }
+            }
+            input.SkipBytes(inputLen);
+        }
+
+        private DecodeMessage createDecodeMessage(byte[] length, byte[] message)
+        {
+            DecodeMessage decodeMessage = new DecodeMessage();
+            decodeMessage.Length = int.Parse(Encoding.Default.GetString(length));
+
+            int messageIdStartIndex = Array.IndexOf(message, ByteUtil.DQTS);
+            int messageIdEndIndex = Array.IndexOf(message, ByteUtil.DQTS, messageIdStartIndex + 1);
+
+            decodeMessage.MessageId = message.Skip(messageIdStartIndex + 1).Take(messageIdEndIndex - messageIdStartIndex - 1).ToArray();
+            decodeMessage.MessageBody = message;
+
+            return decodeMessage;
+        }
+
+        private DecodeMessage createResponseMessage()
+        {
+            DecodeMessage decodeMessage = new DecodeMessage();
+            decodeMessage.Length = 8;
+
+            decodeMessage.MessageId = ByteUtil.MessageId_RSP;
+            decodeMessage.MessageBody = ByteUtil.PING_RSP;
+
+            return decodeMessage;
+        }
+    }
+}
+```

+ 15 - 0
project/WMS转码打印.md

@@ -0,0 +1,15 @@
+## **WMS转码打印程序**
+
+## **功能介绍**
+使用Vue2 BootStrap 和 C#开发。
+功能有登录鉴权,条码打印,转码,等功能。
+其中打印条码使用斑马ZPL指令来打印,Vue无法直接调用打印机,因此开发出一个提供Websocket服务的托盘程序,使用.NET Core Winform开发,Vue将接口传来的ZPL指令通过Socket发送给打印程序,由打印程序调用打印机实现ZPL条码无感打印。
+
+
+## **预览**
+
+![Alt text](image-40.png)
+
+![Alt text](image-41.png)
+
+![Alt text](image-42.png)

BIN
project/WeChat_20231019204628.mp4


BIN
project/a4e62c552abd80af7f0a90bddccd74e.jpg


BIN
project/image-13.png


BIN
project/image-14.png


BIN
project/image-15.png


BIN
project/image-16.png


BIN
project/image-17.png


BIN
project/image-18.png


BIN
project/image-19.png


BIN
project/image-20.png


BIN
project/image-21.png


BIN
project/image-22.png


BIN
project/image-23.png


BIN
project/image-24.png


BIN
project/image-25.png


BIN
project/image-26.png


BIN
project/image-27.png


BIN
project/image-28.png


BIN
project/image-29.png


BIN
project/image-30.png


BIN
project/image-31.png


BIN
project/image-32.png


BIN
project/image-33.png


BIN
project/image-34.png


BIN
project/image-35.png


BIN
project/image-36.png


BIN
project/image-37.png


BIN
project/image-38.png


BIN
project/image-39.png


BIN
project/image-40.png


BIN
project/image-41.png


BIN
project/image-42.png


BIN
project/image-43.png


BIN
project/image-44.png


BIN
project/image-45.png


BIN
project/image-46.png


BIN
project/image-47.png


BIN
project/image-48.png


BIN
project/image-49.png


BIN
project/image-50.png


BIN
project/image-51.png


BIN
project/image-52.png


+ 15 - 0
project/云智高级仓储PDA(Android开发).md

@@ -0,0 +1,15 @@
+## **云智高级仓储PDA(Android开发)**
+
+#### **项目介绍**
+基于Android原生Material组件开发的Android扫码枪程序,集成厂商的扫码回调服务完成各种仓储业务。
+
+
+#### **工作内容**
+开发Android程序并打包。
+
+
+#### **成果**
+目前在公司所有客户提供PDA服务。
+
+
+![Alt text](image-30.png)

+ 24 - 0
project/代码生成器.md

@@ -0,0 +1,24 @@
+## **代码生成器**
+
+
+#### **项目介绍**
+使用Java开发,分为GUI和Web版本,通过freemarker框架编写好ftl模板,选择数据库表生成代码。
+支持MySql数据库和SqlServer。
+
+GUI窗体版本使用JavaFX开发。
+#### **成果**
+已在企业内部使用
+
+#### **预览**
+模板
+![Alt text](image-35.png)
+
+生成规则
+![Alt text](image-36.png)
+
+代码生成
+![Alt text](image-37.png)
+
+窗体版本\
+![Alt text](image-39.png)
+![Alt text](image-38.png)

+ 31 - 0
project/其他项目.md

@@ -0,0 +1,31 @@
+## **单据打印**
+介绍:通过订阅RabbitMQ接受推送过来的下载链接,将下载链接的Excel转换成PDF格式调用打印机进行打印,订阅可配置订阅取消。使用Pyqt开发。
+![Alt text](image-43.png)
+
+
+## **任务调度**
+介绍:可动态增删任务,触发后执行CMD通过路径调用bat脚本或程序,可设置随机区间。
+使用Pyqt开发。
+![Alt text](image-44.png)
+
+## **烘烤箱管理**
+介绍:生成烘烤箱层数,设定时间,放入后倒计时,可提前取出。
+![Alt text](image-48.png)
+
+## **博客网站**
+介绍:个人博客网站,使用Django自己开发的,拥有基本博客功能。\
+参考: https://cybersicko.net/article/119.html
+![Alt text](image-47.png)
+
+
+
+## **OpenVpn搭建**
+介绍:在一台阿里云服务器部署OpenVpn服务器,通过该VPN访问公司阿里产品内网,使用广泛。\
+使用Python Django开发,增删Vpn用户。
+![Alt text](image-45.png)
+![Alt text](image-46.png)
+
+## **义乌电网Android 2020**
+
+[WeChat_20231017211753.mp4](WeChat_20231019204628.mp4 ':include :type=video controls width=100%')
+

+ 43 - 0
project/小程序合集.md

@@ -0,0 +1,43 @@
+## **小程序合集**
+
+#### **巡检小程序**
+##### 项目介绍
+后台使用Java开发,前台微信小程序。\
+由我负责开发Java后台和小程序\
+功能介绍:\
+登录:\
+    1. 手机号登录,用过OpenId获取手机号,保存至SqlServer\
+    2. 账号密码登录,调用WMS登录接口。\
+Redis缓存Token\
+公司切换:\
+    后台配置有不同公司的WMS线上地址,切换后将进入另一个公司的数据。\
+巡检功能:\
+    巡检项目动态可配置,在WMS中维护基础数据和巡检点位等。\
+    用户点击巡检项目,扫描巡检点位二维码开始巡检。\
+    巡检人员以文字,数值,照片等形式上传巡检数据。
+
+![Alt text](141e6f067105de883e6bf89216c6df0.jpg)
+![Alt text](30c34cbc7670997a61e33413e2eb9b5.jpg)
+
+#### **ISI工作流小程序**
+##### 项目介绍
+开发小程序JS,对接WMS接口实现功能。
+功能:
+查询筛选,进展提交,评论,审批等功能。
+![Alt text](a4e62c552abd80af7f0a90bddccd74e.jpg)
+![Alt text](828ed57b6d59414759504aafeb2a660.jpg)
+
+#### **企业微信网页**
+##### 项目介绍
+使用Vue开发,配置在企业微信功能菜单中,使用微信也可以访问。
+拥有产品追溯,合理化建议,实验室记录,设备保养等功能。
+功能主要为表单提交,数据查询,图片上传等。
+后台开发了企业微信相关配置。
+![Alt text](image-33.png)
+![Alt text](image-27.png)
+![Alt text](image-28.png)
+
+#### **培训小程序**
+##### 项目介绍
+拥有选课培训考试功能,考试分为简答题,多选题,单选题,选择并回答等题型。
+![Alt text](image-26.png)

+ 24 - 0
project/计划任务.md

@@ -0,0 +1,24 @@
+#### **介绍**
+之前的公司技术栈C#居多,再后来公司需要一套定时任务系统来处理各系统的调度来弥补WMS和各系统之间调度的缺陷,因此选用了一个开源的C#开发的定时任务系统。
+
+而我被分配到一个数据清洗程序的开发,需求是从大量数据的MongoDB将数据清洗至另一个SqlServer,要具备一定的实时性,因为MongoDB里面的产品测试数据是一直在增长的。
+
+而我想到了定时任务和Python,然后就想到,用Java开发一个Web定是任务管理平台,而执行的是Python脚本。
+
+这能解决什么问题呢?
+
+1.脚本可以动态添加,动态修改,无需修改任何Java代码,因为Python是脚本语言,不存在编译过程,改了就生效,就能运行。
+
+2.可以在Python环境的服务器通过PIP安装很多第三方库,能做非常多的事情,比如定时爬虫,定时API调用,定时数据清洗等等。
+
+
+详情:https://cybersicko.net/article/153.html
+
+#### **设计**
+使用相关技术:Java Quartz,MySql数据库,Python脚本。
+
+![Alt text](image-31.png)
+
+![Alt text](image-32.png)
+
+![Alt text](image-34.png)