文件目录如下,其中static存放背景图之类的图片,templates存放前端.html等文件。 前端:index.html
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1"> <script src="../static/jquery.min.js"></script> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" > <meta name="renderer" content="webkit"> <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script> <title>测量结果</title> <style type = "text/css"> body{margin:0; background-size:100% 100%; background-attachment: fixed; text-align:center; } #myPlayer{max-width: 600px;width: 600px;} .background{ margin:0 auto; } .videodiv{ position: absolute float; } .button{ width: 140px; line-height: 38px; text-align: center; font-weight: bold; color: #fff; text-shadow: 1px 1px 1px #333; border-radius: 5px; margin: 0 20px 20px 0; position: relative; overflow: hidden; } .button.red{ border: 1px solid #b42323; box-shadow: 0 1px 2px #e99494 inset,0 -1px 0 #954b4b inset,0 -2px 3px #e99494 inset; background: -webkit-linear-gradient(top,#d53939,#b92929); background: -moz-linear-gradient(top,#d53939,#b92929); background: linear-gradient(top,#d53939,#b92929); } .button.black { border: 1px solid #333; box-shadow: 0 1px 2px #8b8b8b inset,0 -1px 0 #3d3d3d inset,0 -2px 3px #8b8b8b inset; background: -webkit-linear-gradient(top,#656565,#4c4c4c); background: -moz-linear-gradient(top,#656565,#4a4a4a); background: linear-gradient(top,#656565,#4a4a4a); } </style> </head> <h2>所有数据</h2> <body background="../static/sky.jpg"> <!--内容部分--> <table class="table table-responsive table-bordered" align='center' border="1" > <thead> <tr> <th> <input type="button" value="全选" onclick="checkAll()"/> <input type="button" value="反选" onclick="uncheckAll()"/> </th> <!--th>时间</th--> <th>时间</th> <th>长度</th> <th>宽度</th> <th>高度</th> <th>成熟度</th> <th>操作</th> </tr> </thead> <tbody id="dataBody" style="margin:0 auto; width:90%; height: 98%;"> </tbody> </table> <br> <button type="button" class="button black"><a href="/result" class="button">返回</a></button> <div id="dataid" d="{{data}}" style="display:none"></div> <script> //jobajaxdata.js代码实现 function getJobData(currentPage, pageSize, opr, fname) { //num=document.searchForm.num.value //length=document.searchForm.length.value //width = document.searchForm.width.value //height=document.searchForm.height.value //maturity=document.searchForm.maturity.value if(opr == 'del'){ if(!confirm('确定要删除吗?')){ return false } } else if(opr == 'dels'){ delArray=checkStatus() if(!confirm('确定要全部删除吗?')){ return false } $.ajax({ type: 'post', // 传数据的方式 url: '/ajaxdels.do', dataType: 'json', // xml、json、script、html data:JSON.stringify({ 'fnames': delArray, // $('#userName') == document.getElementById('userName') 'opr': opr }), error: function(xhr, err){ alert('请求失败,请检查,' + err + '!') }, success: function(data, textStatus){ // success对应的回调函数的第一个参数,是服务器返回的数据 } }); } else if(opr=='searchAll'){ num=null length=null width=null height=null maturity=null } $.ajax({ type: 'post', // 传数据的方式 url: '/ajaxjob.do', dataType: 'json', // xml、json、script、html data:JSON.stringify({ 'fname': fname, // $('#userName') == document.getElementById('userName') 'num':num, 'length':length, 'width':width, 'height':height, 'maturity':maturity, 'pageSize': pageSize, 'currentPage': currentPage, 'opr': opr }), error: function(xhr, err){ alert('请求失败,请检查,' + err + '!') }, success: function(data, textStatus){ // success对应的回调函数的第一个参数,是服务器返回的数据 if(data.code == 1){ var htmlText = "" //console.log(data.jobData) for(var i =0;i <data.jobData.length;i=i+2){ htmlText += '<tr>' + ' <td align="center"><input type="checkbox" name="fname" value="'+ data.jobData[i][1] +'" /></td>\n' + //' <td>' + data.jobData[i][1] + '</td>\n'+ ' <td>' + data.jobData[i][1].slice(0,8) + '<br>'+data.jobData[i+1][1].slice(8,16) + '</td>\n' + ' <td>' + data.jobData[i][3] + '<br>'+data.jobData[i+1][3] + '</td>\n' + ' <td>' + data.jobData[i][4] + '<br>'+data.jobData[i+1][4] + '</td>\n' + ' <td>' + data.jobData[i][5] +'<br>'+data.jobData[i+1][5] + '</td>\n' + ' <td>' + data.jobData[i][6] +'<br>'+data.jobData[i+1][6] + '</td>\n' + ' <td>\n' + ' <a href="/detail/'+ data.jobData[i][1]+data.currentPage +'">详情</a>'+ ' <a href="javascript:getJobData('+ data.currentPage +',' + data.pageSize + ','+ '\'del\''+',' + data.jobData[i][1] +')">删除</a>' + ' </td>\n' + ' </tr>\n' } pageText='<tr><td colspan="1">'+ '<a href="javascript:getJobData('+ data.currentPage +',' + data.pageSize + ','+ '\'dels\''+',' + '0' +')">删除</a> </td>' pageText += '<td colspan="7">'+'当前第' + data.currentPage + '页 总共有' + data.totalPage + '页 '; if(data.currentPage <= 1) { pageText += '首页 上一页 '; }else{ pageText += '<a href="javascript:getJobData(1,8,\'search\', 0);">首页</a> ' + '<a href="javascript:getJobData(' + (data.currentPage - 1) + ', 8, \'search\', 0);">上一页</a> '; } if(data.currentPage >= data.totalPage){ pageText += '下一页 尾页 '; }else { pageText += '<a href="javascript:getJobData(' + (data.currentPage + 1) + ', 8, \'search\', 0);">下一页</a> ' + '<a href="javascript:getJobData(' + data.totalPage + ', 8, \'search\', 0);">尾页</a> '; } pageText +='总共有'+data.counts/2+'例数据'+'</td></tr>' $('#dataBody').empty() $('#dataBody').append(htmlText) $('#dataBody').append(pageText) //document.searchForm.currentPage.value = data.currentPage //document.searchForm.pageSize.value=data.pageSize } } }); } function checkStatus(){ var checkOnes=document.getElementsByName('fname'); var myArray=new Array() for(var i=0;i<checkOnes.length;i++){ //5.拿到每一个复选框,并将其状态置为选中 if(checkOnes[i].checked==true){ myArray.push(checkOnes[i].value) } } return myArray } function checkAll(){ var checkOnes=document.getElementsByName('fname'); for(var i=0;i<checkOnes.length;i++){ //5.拿到每一个复选框,并将其状态置为选中 checkOnes[i].checked=true; } } function uncheckAll(){ var checkOnes=document.getElementsByName('fname'); for(var i=0;i<checkOnes.length;i++){ //5.拿到每一个复选框,并将其状态置为选中 checkOnes[i].checked=false; } } $(document).ready( function(){ var data = document.getElementById('dataid').getAttribute('d'); getJobData(data, 8, 'searchAll', 0) } ) </script> </body> </html>后端:基于flask框架的web后端,用python自带的sqlite3数据库。 app.py
#!/usr/bin/env python # -*- coding: utf-8 -*- # # appCam.py # based on tutorial ==> https://blog.miguelgrinberg.com/post/video-streaming-with-flask # PiCam Local Web Server with Flask # MJRoBot.org 19Jan18 from flask import Flask, render_template, Response,json,jsonif import time import sqlite3 from jobcontroller import jobcontroller app = Flask(__name__) app.config['UPLOAD_FOLDER'] = 'static/uploads/' app.config['ALLOWED_EXTENSIONS'] = set(['png', 'jpg', 'jpeg', 'gif']) app.config['JSON_AS_ASCII']=False app.config['JSONIFY_MIMETYPE'] ="application/json;charset=utf-8" #绑定路由 app.register_blueprint(jobcontroller) @app.route("/") @app.route("/data/<currentPage>") def data(currentPage): return render_template('index.html',data=currentPage) if __name__ == '__main__': app.run(host='0.0.0.0', port =5000, debug=True, threaded=True)controller.py
#controller文件夹下-jobcontroller.py实现代码 from flask import Blueprint,Flask,render_template,request,Response,session,url_for,jsonify from JobService import JobService import json jobService=JobService() #引入服务层 jobcontroller=Blueprint('jobcontroller',__name__) @jobcontroller.route('/ajaxdels.do',methods=['POST','GET']) def ajadels(): jobData = request.get_data() jobDict = json.loads(jobData) fnames=(jobDict.get('fnames')) opr = jobDict.get('opr') if opr == 'dels': for x in fnames: delResult = jobService.removeJob(x) returnData = {'code': 1} return json.dumps(returnData) @jobcontroller.route('/ajaxjob.do',methods=['POST','GET']) def getJobInfo(): jobData = request.get_data() jobDict = json.loads(jobData) fname=(jobDict.get('fname')) currentPage = int(jobDict.get('currentPage')) pageSize = int(jobDict.get('pageSize')) opr = jobDict.get('opr') delResult = 0 if opr == 'del': delResult = jobService.removeJob(fname) pass result = jobService.findPageJobList(pageSize, currentPage) counts = jobService.countJobs() totalPage = 0 if (counts % pageSize == 0): totalPage = counts // pageSize else: totalPage = counts // pageSize + 1 pass returnData = {'code': 1, 'jobData': result, 'pageSize': pageSize, 'currentPage': currentPage, 'totalPage': totalPage, 'delcode': delResult, 'opr': 'search', 'counts': counts} return json.dumps(returnData)dao.py
#dao层文件夹-jobdao.py代码实现 import sqlite3 import os def takeSecond(elem): return elem[1] class JobDao(): def findPageJobList(self,pageSize,currentPage): try: con = sqlite3.connect('./static/sqlitedb/datas.db') cur = con.cursor() sql = "select count(*) from fish " con = sqlite3.connect('./static/sqlitedb/datas.db') cur = con.cursor() cur.execute(sql) count = cur.fetchone() count=count[0] params=[] #sql语句和parms就需要是动态 sql ="select * from fish " #startRow=(currentPage-1)*pageSize sql+="limit ?,? " if((count-pageSize*currentPage) >= 0): startRow=count-pageSize*currentPage else: startRow=0 pageSize=count-pageSize*(currentPage-1) params.append(str(startRow)) params.append(str(pageSize)) cur.execute(sql,params) result = cur.fetchall() result.sort(reverse=True,key=takeSecond) except Exception as e: print(e) print('查询失败') finally: # 关闭游标 cur.close() # 关闭连接 con.close() #print(result) return result def countJobs(self): try: sql = "select count(*) from fish " con = sqlite3.connect('./static/sqlitedb/datas.db') cur = con.cursor() cur.execute(sql) result = cur.fetchone() except Exception as e: print(e) print('查询失败') finally: # 关闭游标 cur.close() # 关闭连接 con.close() return result def removeJob(self, fname): result=0 try: con = sqlite3.connect('./static/sqlitedb/datas.db') cur = con.cursor() sql = "delete from fish where fname=?" fname=str(fname) #print(fname) cur.execute(sql,(fname,)) result=1 con.commit() path1 = './static/uploads/'+fname+'_A.jpg' # 文件路径 path2 = './static/uploads/'+fname+'_B.jpg' # 文件路径 if os.path.exists(path1) and os.path.exists(path2): # 如果文件存在 # 删除文件,可使用以下两种方法。 os.remove(path1) os.remove(path2) #os.unlink(path) else: print('no such file:%s'%fname) # 则返回文件不存在 except Exception as e: print(e) print('查询失败') finally: # 关闭游标 cur.close() # 关闭连接 con.close() return resultservice.py
#service文件夹下-jobservice.py实现代码 from JobDao import JobDao class JobService(): def findPageJobList(self,pageSize,currentPage): jobDao=JobDao() return jobDao.findPageJobList(pageSize,currentPage) pass def removeJob(self,fname): jobDao=JobDao() return jobDao.removeJob(fname) pass def countJobs(self): jobDao = JobDao() return jobDao.countJobs()[0] pass pass