题目:现场快递柜状态采集与控制系统
目标:设计实现一个对现场快递柜状态数据采集、显示、参数设置、抽屉打开、保鲜控 制等功能软件系统。

编译环境:Vscode

程序语言:python


UI界面截图:

运行状态截图:

温度曲线截图:

Server.py(主程序代码):

from PySide2.QtCore import QFile    # 导入文件类
from PySide2.QtWidgets import QApplication  # 导入QtWidgets模块
from PySide2.QtUiTools import QUiLoader  # 加载UI文件
import threading  # 线程模块
import serial  # 导入串口模块
from ControlTable import *  # 导入控制表类(用户)
from send import *  # 导入发送模块(用户)
from receive import *  # 导入接收模块(用户)# 配置串口
portx = "COM2"
bps = 38400
# 超时设置,None:永远等待操作,0为立即返回请求结果,其他值为等待超时时间(单位为秒)
timex = None
ser = serial.Serial(portx, bps, timeout=timex)  # 开启串口通信class Software:def __init__(self):# 从文件中加载UI定义qfile_Server = QFile("UI/software.ui")qfile_Server.open(QFile.ReadOnly)qfile_Server.close()# 从 UI 定义中动态 创建一个相应的窗口对象self.ui = QUiLoader().load(qfile_Server)self.ui.Shezhiwendu.setPlaceholderText('请输入温度')self.ui.openButton.clicked.connect(self.open)self.ui.closeButton.clicked.connect(self.close)self.ui.yaStateSet.clicked.connect(self.CompressorSet)self.ui.drawer1.clicked.connect(lambda: self.drawer(1))self.ui.drawer2.clicked.connect(lambda: self.drawer(2))self.ui.drawer3.clicked.connect(lambda: self.drawer(3))self.ui.drawer4.clicked.connect(lambda: self.drawer(4))self.ui.drawer5.clicked.connect(lambda: self.drawer(5))self.ui.drawer6.clicked.connect(lambda: self.drawer(6))self.ui.drawer7.clicked.connect(lambda: self.drawer(7))self.ui.drawer8.clicked.connect(lambda: self.drawer(8))self.ui.drawer9.clicked.connect(lambda: self.drawer(9))self.ui.drawer10.clicked.connect(lambda: self.drawer(10))self.ui.Shezhiwendu.returnPressed.connect(self.TemptureSet)self.ui.setAttritutes.clicked.connect(self.SendAttributes)#  定义初始状态参数self.yastate = Falseself.drawerStates = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]def open(self):  # 开机self.ui.systemstate.setText('     ' + "运行")self.ui.openButton.setEnabled(False)self.ui.closeButton.setEnabled(True)self.ui.Shezhiwendu.setEnabled(True)self.ui.yastate.setEnabled(True)self.ui.drawer1.setEnabled(True)self.ui.drawer2.setEnabled(True)self.ui.drawer3.setEnabled(True)self.ui.drawer4.setEnabled(True)self.ui.drawer5.setEnabled(True)self.ui.drawer6.setEnabled(True)self.ui.drawer7.setEnabled(True)self.ui.drawer8.setEnabled(True)self.ui.drawer9.setEnabled(True)self.ui.drawer10.setEnabled(True)self.ui.DeviceID.setEnabled(True)self.ui.DeviceAddress.setEnabled(True)self.ui.readInterpret.setEnabled(True)self.ui.ComDelay.setEnabled(True)self.ui.temptureSet.setEnabled(True)self.ui.temptureError.setEnabled(True)self.ui.setAttritutes.setEnabled(True)self.ui.yaStateSet.setEnabled(True)def close(self):  # 关机self.ui.Shezhiwendu.clear()self.ui.Shezhiwendu.setEnabled(False)self.ui.yastate.setEnabled(False)self.ui.Currentwendu.setText("")  # 将文本框置空self.ui.yastate.setText("")  # 将文本框置空self.ui.systemstate.setText("")  # 将文本框置空self.ui.DeviceID.setText("")  # 将文本框置空self.ui.temptureSet.setText("")  # 将文本框置空self.ui.openButton.setEnabled(True)self.ui.closeButton.setEnabled(False)# 将文本框置空self.ui.drawer1.setText("")self.ui.drawer2.setText("")self.ui.drawer3.setText("")self.ui.drawer4.setText("")self.ui.drawer5.setText("")self.ui.drawer6.setText("")self.ui.drawer7.setText("")self.ui.drawer8.setText("")self.ui.drawer9.setText("")self.ui.drawer10.setText("")self.ui.drawer1.setEnabled(False)self.ui.drawer2.setEnabled(False)self.ui.drawer3.setEnabled(False)self.ui.drawer4.setEnabled(False)self.ui.drawer5.setEnabled(False)self.ui.drawer6.setEnabled(False)self.ui.drawer7.setEnabled(False)self.ui.drawer8.setEnabled(False)self.ui.drawer9.setEnabled(False)self.ui.drawer10.setEnabled(False)self.ui.DeviceID.setEnabled(False)self.ui.DeviceAddress.setEnabled(False)self.ui.readInterpret.setEnabled(False)self.ui.ComDelay.setEnabled(False)self.ui.temptureSet.setEnabled(False)self.ui.temptureError.setEnabled(False)self.ui.setAttritutes.setEnabled(False)self.ui.yaStateSet.setEnabled(False)def drawer(self, i):   # 开关抽屉控制drawerStates_Send = self.drawerStatesif i == 1:if self.drawerStates[0] == 0:drawerStates_Send[0] = 1else:drawerStates_Send[0] = 0elif i == 2:if self.drawerStates[1] == 0:drawerStates_Send[1] = 1else:drawerStates_Send[1] = 0elif i == 3:if self.drawerStates[2] == 0:drawerStates_Send[2] = 1else:drawerStates_Send[2] = 0elif i == 4:if self.drawerStates[3] == 0:drawerStates_Send[3] = 1else:drawerStates_Send[3] = 0elif i == 5:if self.drawerStates[4] == 0:drawerStates_Send[4] = 1else:drawerStates_Send[4] = 0elif i == 6:if self.drawerStates[5] == 0:drawerStates_Send[5] = 1else:drawerStates_Send[5] = 0elif i == 7:if self.drawerStates[6] == 0:drawerStates_Send[6] = 1else:drawerStates_Send[6] = 0elif i == 8:if self.drawerStates[7] == 0:drawerStates_Send[7] = 1else:drawerStates_Send[7] = 0elif i == 9:if self.drawerStates[8] == 0:drawerStates_Send[8] = 1else:drawerStates_Send[8] = 0elif i == 10:if self.drawerStates[9] == 0:drawerStates_Send[9] = 1else:drawerStates_Send[9] = 0drawControlFrame_Send(ser, 0x3f, drawerStates_Send)def TemptureSet(self):  # 设置温度tempture = self.ui.Shezhiwendu.text()if tempture != "":address = ControlTableAttributes['Address']setTempFrame_Send(ser, address, int(tempture))def CompressorSet(self):  # 压缩机控制按钮if self.yastate == False:self.yastate = Trueself.ui.signal.setText("The start compressor command has been send")else:self.yastate = Falseself.ui.signal.setText("The stop compressor command has been send")def SendAttributes(self):  # 发送设置的属性if self.ui.DeviceID.text() != "" and self.ui.temptureSet.text() != "":Attributes = {'DeviceID': int(self.ui.DeviceID.text(), 16).to_bytes(5, 'big'),'Address': int(self.ui.DeviceAddress.currentText()),'StateUpload': int(self.ui.readInterpret.currentText()),'CompressorStartDelay': int(self.ui.ComDelay.currentText()),'tempture_set': tempture_send(int(self.ui.temptureSet.text())),'temptureError': int(self.ui.temptureError.currentText()),}print(Attributes)setParaFrame_Send(ser, Attributes)self.ui.signal.setText("")else:   # 如果未填写好self.ui.signal.setText("Please enter DeviceID and tempture of set")# 实例化窗口程序
app = QApplication([])
software = Software()
software.ui.show()
# 设置接受数据守护线程
receivethread = threading.Thread(target=lambda: Receive(software, ser))
receivethread.setDaemon(True)
receivethread.start()
# 循环执行
app.exec_()

Receive.py(接收模块) :

from ControlTable import *  # 导入控制表数据结构(用户)
import datetime  # 计算时间
import chart    # 导入图像模块(用户)
from send import compressorControlFrame_Send  # 字节流处理(用户)TemptureList = []  # 存储温度列表
DateTimeList = []  # 时间轴更新def Receive(software, ser):  # 接收线程while(True):if software.ui.closeButton.isEnabled():Frame = ser.read(80)    # 接收80B数据resultFrame = ReceiveFrame(Frame)  # 将接收到的数据转换为常量字节流for result in resultFrame:if result[2] == 0x2C:   # 接收到的帧为控制表状态帧# 保存接收到的数据ControlTableAttributes_set(result[6:11], result[11], result[13], result[14], result[17], result[18])ControlTableStatus_set(result[24:29], result[29], result[31], result[32], result[33], result[36:38])tempture = temptureReceive()  # 计算接收到的温度并绘制图像if software.yastate == True:    # 如果启动了压缩机# 设置温度计算temptureSet = '{:0>8}'.format(str(bin(ControlTableStatus['tempture_set']))[2:])if(temptureSet[0] == '0'):temptureSet = str(int(temptureSet[1:7], 2)+1/2*int(temptureSet[7], 2))else:temptureSet = '-' + str(int(temptureSet[1:7], 2)+1/2*int(temptureSet[7], 2))# 判断当前温度,调控压缩机开关if float(tempture) <= float(temptureSet) - ControlTableAttributes['tempture_controlerror'] + 1:compressorControlFrame_Send(ser, 0x3f, False)if float(tempture) >= float(temptureSet) + ControlTableAttributes['tempture_controlerror'] - 1:compressorControlFrame_Send(ser, 0x3f, True)else:   # 如果没有启动压缩机compressorControlFrame_Send(ser, 0x3f, False)Lock = LockReceive()  # 计算Lock状态UISoftwareUpdate(software, Lock, tempture)  # UI更新def temptureReceive():  # 计算接收到的温度并绘制图像tempture = '{:0>8}'.format(str(bin(ControlTableStatus['tempture_current']))[2:])if(tempture[0] == '0'):tempture = str(int(tempture[1:7], 2)+1/2*int(tempture[7], 2))else:tempture = '-' + str(int(tempture[1:7], 2)+1/2*int(tempture[7], 2))DateTimeList.append(datetime.datetime.now().strftime("%H:%M:%S"))TemptureList.append(float(tempture))chart.Scatter(DateTimeList, TemptureList, '#abddff')return tempturedef LockReceive():  # 计算Lock状态return '{:0>8}'.format(str(bin(ControlTableStatus['LockState'][0]))[2:])[::-1] + '{:0>8}'.format(str(bin(ControlTableStatus['LockState'][1]))[2:4])[::-1] + '{:0>8}'.format(str(bin(ControlTableStatus['LockState'][1]))[4:])def UISoftwareUpdate(software, Lock, tempture):  # 更新UI界面if software.ui.closeButton.isEnabled():drawerStateReceived(software, Lock)software.ui.yastate.setText('     ' + CompressorState_show(ControlTableStatus['CompressorState']))software.ui.Currentwendu.setText(tempture + "℃")def drawerStateReceived(software, Lock):  # 根据Lock字段显示各个抽屉的状态if Lock[0] == '1':software.drawerStates[0] = 1software.ui.drawer1.setText("开")else:software.drawerStates[0] = 0software.ui.drawer1.setText("关")if Lock[1] == '1':software.drawerStates[1] = 1software.ui.drawer2.setText("开")else:software.drawerStates[1] = 0software.ui.drawer2.setText("关")if Lock[2] == '1':software.drawerStates[2] = 1software.ui.drawer3.setText("开")else:software.drawerStates[2] = 0software.ui.drawer3.setText("关")if Lock[3] == '1':software.drawerStates[3] = 1software.ui.drawer4.setText("开")else:software.drawerStates[3] = 0software.ui.drawer4.setText("关")if Lock[4] == '1':software.drawerStates[4] = 1software.ui.drawer5.setText("开")else:software.drawerStates[4] = 0software.ui.drawer5.setText("关")if Lock[5] == '1':software.drawerStates[5] = 1software.ui.drawer6.setText("开")else:software.drawerStates[5] = 0software.ui.drawer6.setText("关")if Lock[6] == '1':software.drawerStates[6] = 1software.ui.drawer7.setText("开")else:software.drawerStates[6] = 0software.ui.drawer7.setText("关")if Lock[7] == '1':software.drawerStates[7] = 1software.ui.drawer8.setText("开")else:software.drawerStates[7] = 0software.ui.drawer8.setText("关")if Lock[8] == '1':software.drawerStates[8] = 1software.ui.drawer9.setText("开")else:software.drawerStates[8] = 0software.ui.drawer9.setText("关")if Lock[9] == '1':software.drawerStates[9] = 1software.ui.drawer10.setText("开")else:software.drawerStates[9] = 0software.ui.drawer10.setText("关")def ReceiveFrame(hex_datas):  # 匹配帧头和帧尾,获取匹配成功的帧resultFrame = []for i in range(0, len(hex_datas)-1):if hex_datas[i] == 0xFF and hex_datas[i+1] == 0xFF:for j in range(i, len(hex_datas)-1):if hex_datas[j] == 0xFF and hex_datas[j+1] == 0xF7:result = hex_datas[i:j+2]if len(result) == 14 or len(result) == 44:resultFrame.append(result)return resultFrame  # 返回匹配成功的帧(列表)

chart.py(绘图模块):

import pyecharts.options as opts  # 绘图
from pyecharts.charts import Line   # 导入Line模块def Scatter(time, tempture, colour):  # 绘制折线图html文件time = time[-10:]   # 取time末尾10位tempture = tempture[-10:]  # 取温度末尾10位c = (Line(init_opts=opts.InitOpts(width="900px",height="600px",)).add_xaxis(time).add_yaxis('温度/°C', tempture).set_colors(colour).set_global_opts(title_opts=opts.TitleOpts(title="温度变化"),yaxis_opts=opts.AxisOpts(name="温度°C"),xaxis_opts=opts.AxisOpts(name="time"))).render("html\chart.html")  # 生成折线图html文件

send.py(发送模块):

import packet  # 封装成帧格式# 启停压缩机控制帧发送def compressorControlFrame_Send(ser, address, comOn):result = ser.write(packet.compressorControlFrame(address, comOn))# 开锁帧发送def drawControlFrame_Send(ser, address, draw):result = ser.write(packet.drawControlFrame(address, draw))# 查询帧发送def searchFrame_Send(ser, address):result = ser.write(packet.searchFrame(address))# 设置温度帧发送def setTempFrame_Send(ser, address, temp):temp = tempture_send(temp)result = ser.write(packet.setTempFrame(address, temp))# 设置参数帧发送def setParaFrame_Send(ser, Attributes):result = ser.write(packet.setParaFrame(Attributes))# 设置温度转换成发送格式def tempture_send(tempture):tempture = float(tempture)  # 将温度转化为浮点型s = str(tempture).split('.')  # 再转化为字符串型,以.分割列表tempture = str(int(int(s[0]) < 0)) + \'{:0>6}'.format(str(bin(int(s[0]))[2:])) + str(int(int(s[1]) != 0))  # 填充左边数字补零,宽度为6 将温度转换为十六进制数tempture = int(tempture, 2)return tempture

packet.py (封装成帧 ):

import struct  # 导入封装成帧模块
frameNum = 0  # 帧号# 封装成帧def DataFrame(address, funNum, data):length = len(data) + 10crc_frame = calc_crc(struct.pack('4B', length, frameNum, address, funNum) + data)return struct.pack('6B', eval('0xFF'), eval('0xFF'), length, frameNum,address, funNum) + data + struct.pack('H', crc_frame) + struct.pack('2B', eval('0xFF'), eval('0xF7'))# 解封装def DataFrame_unpack(frame):return struct.unpack('6B', frame[0:6]) + struct.unpack(str(len(frame[6:-2])) + 'B', frame[6:-2]) + struct.unpack('2B', frame[-2:])# (1)查询帧(10Byte)def searchFrame(address):  # 设备地址(16进制)global frameNumframeNum = (frameNum + 1) % 255Data = DataFrame(address, 1, b'')return Data# (2)启停压缩机控制帧(11Byte)def compressorControlFrame(address, comOn):  # 设备地址(16进制),是否启动压缩机(bool)global frameNumframeNum = (frameNum + 1) % 255if comOn:Data = DataFrame(address, 2, b'\x01')  # 数据1,启动else:Data = DataFrame(address, 2, b'\x00')  # 数据0,停止return Data# (3)开锁帧(12Byte)def drawControlFrame(address, draw):  # 设备地址(16进制),抽屉状态(元组)global frameNumb1 = 0b2 = 0frameNum = (frameNum + 1) % 255# 处理第一个字节for i in range(8):b1 += draw[i]*2**i# 处理第二个字节for i in [8, 9]:b2 += draw[i]*2**(i-8)Data = DataFrame(address, 3, b1.to_bytes(1, 'big')+b2.to_bytes(1, 'big'))  # 7return Data# (4)设置温度帧(11Byte)def setTempFrame(address, temp):  # 设备地址(16进制),设置温度(10进制)global frameNumframeNum = (frameNum + 1) % 255Data = DataFrame(address, 4, temp.to_bytes(1, 'big'))return Data# (5)设置参数帧(28Byte)def setParaFrame(para):global frameNumframeNum = (frameNum + 1) % 255data = para['DeviceID']+para['Address'].to_bytes(1, 'big')+b'\x00'+para['StateUpload'].to_bytes(1, 'big')+para['CompressorStartDelay'].to_bytes(1, 'big')+b'\x00\x00'+para['tempture_set'].to_bytes(1, 'big')+para['temptureError'].to_bytes(1, 'big')+b'\xff\xff\xff\xff\x00'Data = DataFrame(0x7f, 5, data)return Data# (6)设置温度控制偏差帧(11Byte)def setCtrlDeviationFrame(address, deviation):  # address是16进制,deviation是10进制global frameNumframeNum = (frameNum + 1) % 255Data = DataFrame(address, 6, deviation.to_bytes(1, 'big'))return Data# (7)设置设备地址帧(16Byte)def setDeviceAdressFrame(eqCodeing, newAddress):  # 形参均为16进制整型global frameNumframeNum = (frameNum + 1) % 255Data = DataFrame(0x7f, 9, eqCodeing.to_bytes(5, 'big')+newAddress.to_bytes(1, 'big'))return Data# 循环冗余校验def calc_crc(string):crc = 0xFFFFfor pos in string:crc ^= posfor i in range(len(string)):if ((crc & 1) != 0):crc >>= 1crc ^= 0xA001else:crc >>= 1return eval(hex(((crc & 0xff) << 8) + (crc >> 8)))  # 返回CRC校验码(16进制字节流)

ControlTable.py(存放接收到的数据结构):

# 控制表状态,用字典储存各个信息,每读取一次更新一次
ControlTableStatus = {'DeviceID': b'\xFF\xFF\xFF\xFF\xFF',  # 设备ID比特流'SystemState': 0x00,  # 二位十六进制数表示一个比特'CompressorState': 0x00,'tempture_set': 0x00,'tempture_current': 0x00,'LockState': b'\x00\x00',
}# 控制表状态设置def ControlTableStatus_set(DeviceID, SystemState, CompressorState, tempture_set, tempture_current, LockState):ControlTableStatus['DeviceID'] = DeviceIDControlTableStatus['SystemState'] = SystemStateControlTableStatus['CompressorState'] = CompressorStateControlTableStatus['tempture_set'] = tempture_setControlTableStatus['tempture_current'] = tempture_currentControlTableStatus['LockState'] = LockStatereturn ControlTableStatus# 展示系统状态,用数字0,1,2分别表示三种状态def SystemState_show(SystemState):if SystemState == 0:return "停止"elif SystemState == 1:return "预启动"elif SystemState == 2:return "运行"# 展示压缩机状态,表示四种状态def CompressorState_show(CompressorState):if CompressorState == 0:return "停止"elif CompressorState == 1:return "预启动"elif CompressorState == 2:return "运行"elif CompressorState == 3:return "故障"# 控制表属性,同样用字典储存
ControlTableAttributes = {'DeviceID': b'\xFF\xFF\xFF\xFF\xFF','Address': 0x01,'StateUpload': 0x01,'CompressorStartDelay': 0x1E,'tempture_set': 0x00,'tempture_controlerror': 0x02,
}# 控制表属性设置def ControlTableAttributes_set(DeviceID, Address, StateUpload, CompressorStartDelay, tempture_set, tempture_controlerror):ControlTableAttributes['DeviceID'] = DeviceIDControlTableAttributes['Address'] = AddressControlTableAttributes['StateUpload'] = StateUploadControlTableAttributes['CompressorStartDelay'] = CompressorStartDelayControlTableAttributes['tempture_set'] = tempture_setControlTableAttributes['tempture_controlerror'] = tempture_controlerrorreturn ControlTableAttributes

现场快递柜状态采集与控制系统相关推荐

  1. 共享快递柜业务场景实战(服务构建)

    简介: 使用物联网平台,快速构建一个高性能的共享快递柜业务 1.背景 当我们的设备和物联网平台建立mqtt连接通道后,会根据业务需求传输不同的数据.本次以共享快递柜业务场景讲解topic和payloa ...

  2. [附源码]JAVA+ssm基于Internet快递柜管理系统(程序+Lw)

    项目运行 环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclis ...

  3. [附源码]Python计算机毕业设计SSM基于Internet快递柜管理系统(程序+LW)

    环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,St ...

  4. 计算机毕设(附源码)JAVA-SSM基于Internet快递柜管理系统

    项目运行 环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclis ...

  5. Verilog实现快递柜

    FPGA这东西就是个玄学.这个实验做了这么久,不想让它被遗忘,在此做一下记录,让它变得有价值起来. Verilog实现快递柜 -- 实验六记录 实验描述 实验分析 打开vivado 新建工程 新建三个 ...

  6. 计算机毕业设计ssm+vue基本微信小程序的快递柜管理系统 uniapp 小程序

    项目介绍 随着计算机信息技术的发展,越来越多的用户使用手机,各种信息化应用出现在智能手机中,特别是微信APP拥有大量的用户群,使用微信小程序可以为人们的生活提供便利.另一方面,我国网购数量日益增加,各 ...

  7. 计算机毕业设计ssm+vue基本微信小程序的快递柜管理系统

    项目介绍 随着计算机信息技术的发展,越来越多的用户使用手机,各种信息化应用出现在智能手机中,特别是微信APP拥有大量的用户群,使用微信小程序可以为人们的生活提供便利.另一方面,我国网购数量日益增加,各 ...

  8. 丰巢后撤,便宜了菜鸟驿站、京东快递柜?

    配图来自Canva 最近许多人取快递的时候发现,黄绿色的丰巢快递柜已经变成了红色的京东快递柜.这也让很多刚刚经历了丰巢收费风波的用户不禁产生疑问,京东不会要收更多的"管理费"吧. ...

  9. [附源码]计算机毕业设计校园快递柜存取件系统Springboot程序

    项目运行 环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclis ...

最新文章

  1. 后台接口向数据库录入汉字时乱码以及自动过滤文字经验总结
  2. 你最需要了解的H3C交换机端口安全模式
  3. Ajax Control Toolkit 34个服务器端控件 详解
  4. 数学建模——主成分分析算法详解Python代码
  5. mysql 找不到hdfs文件_hadoop判断文件是否存在
  6. dump文件导入表修复工具——Imports Fixer
  7. 小学计算机使用和运行记录表,20XX年小学微机室的各种管理制度和常用表格.doc...
  8. Transaction 那点事儿
  9. Loadrunner:管理员权限启动报错“win10为了对电脑进行保护,已经阻止此应用”
  10. 《巴菲特致股东的信》十年期固定行使价格期权对公司的侵蚀-计算过程演示
  11. oracle db recover参数,【参数】恢复db_recovery_file_dest_size参数为默认值“0”方法
  12. Cherry键盘外接Mac command按键失灵
  13. Altium Designer四层板设计教程
  14. 74HC245引脚定义 使用方法
  15. 社交电商如何持续进化?来看看最新的拼团玩法——七人拼团
  16. 手机开机卡在android画面,手机一直停在开机画面怎么解决【图文】
  17. SLAM-Visual Navigation学习之SIFT算法与代码详解
  18. Doris进阶——初识Doris_FE、BE、BROKER的扩缩容
  19. match2(双周赛)
  20. 浏览器前缀/ css3 渐变 /

热门文章

  1. Flex移动skin–第3部分:多平台开发
  2. 计算机磁盘图标变成软件的了,电脑的本地磁盘图标变成一个U盘形状图标了怎么回事?如何解决?...
  3. uni-app小程序利用动画做出左右滑动切换的效果
  4. 路由器交换机升级操作系统(导IOS)
  5. Web3的企业如何用Token激励员工?
  6. 区块链学习笔记:区块链到底能干什么
  7. excel计算式自动计算_钢筋计算太麻烦?全套钢筋翻样Excel自动计算表,限时分享...
  8. 路由器固件编译及个性化
  9. 有赞实时计算 Flink 1.13 升级实践
  10. 玫瑰线 matlab,如何用MATLAB画玫瑰线