├── .gitattributes ├── CoughCheckerAPI ├── .gitignore ├── Readme ├── algorithm.py ├── base.py ├── clinical │ ├── labels.csv │ ├── original │ │ ├── neg │ │ │ ├── neg-0421-083-cough-m-53.mp3 │ │ │ ├── neg-0421-085-cough-m-43.mp3 │ │ │ ├── neg-0421-088-cough-f-66.mp3 │ │ │ ├── neg-0421-089-cough-f-20.mp3 │ │ │ ├── neg-0421-090-cough-f-17.mp3 │ │ │ ├── neg-0421-091-cough-m-47.mp3 │ │ │ ├── neg-0422-095-cough-m-53.mp3 │ │ │ ├── neg-0422-097-cough-m-37.mp3 │ │ │ └── neg-0422-098-cough-f-24.mp3 │ │ └── pos │ │ │ ├── pos-0421-084-cough-m-50.mp3 │ │ │ ├── pos-0421-086-cough-m-65.mp3 │ │ │ ├── pos-0421-087-cough-f-40.mp3 │ │ │ ├── pos-0421-092-cough-m-53.mp3 │ │ │ ├── pos-0421-093-cough-f-24.mp3 │ │ │ ├── pos-0421-094-cough-m-51.mp3 │ │ │ └── pos-0422-096-cough-m-31.mp3 │ └── segmented │ │ ├── neg │ │ ├── neg-0421-083-cough-m-53-0.mp3 │ │ ├── neg-0421-083-cough-m-53-1.mp3 │ │ ├── neg-0421-083-cough-m-53-10.mp3 │ │ ├── neg-0421-083-cough-m-53-11.mp3 │ │ ├── neg-0421-083-cough-m-53-12.mp3 │ │ ├── neg-0421-083-cough-m-53-13.mp3 │ │ ├── neg-0421-083-cough-m-53-14.mp3 │ │ ├── neg-0421-083-cough-m-53-15.mp3 │ │ ├── neg-0421-083-cough-m-53-16.mp3 │ │ ├── neg-0421-083-cough-m-53-17.mp3 │ │ ├── neg-0421-083-cough-m-53-2.mp3 │ │ ├── neg-0421-083-cough-m-53-3.mp3 │ │ ├── neg-0421-083-cough-m-53-4.mp3 │ │ ├── neg-0421-083-cough-m-53-5.mp3 │ │ ├── neg-0421-083-cough-m-53-6.mp3 │ │ ├── neg-0421-083-cough-m-53-7.mp3 │ │ ├── neg-0421-083-cough-m-53-8.mp3 │ │ ├── neg-0421-083-cough-m-53-9.mp3 │ │ ├── neg-0421-085-cough-m-43-1.mp3 │ │ ├── neg-0421-085-cough-m-43-2.mp3 │ │ ├── neg-0421-088-cough-f-66-0.mp3 │ │ ├── neg-0421-088-cough-f-66-1.mp3 │ │ ├── neg-0421-088-cough-f-66-2.mp3 │ │ ├── neg-0421-088-cough-f-66-3.mp3 │ │ ├── neg-0421-088-cough-f-66-4.mp3 │ │ ├── neg-0421-088-cough-f-66-5.mp3 │ │ ├── neg-0421-088-cough-f-66-6.mp3 │ │ ├── neg-0421-088-cough-f-66-8.mp3 │ │ ├── neg-0421-089-cough-f-20-0.mp3 │ │ ├── neg-0421-089-cough-f-20-2.mp3 │ │ ├── neg-0421-089-cough-f-20-3.mp3 │ │ ├── neg-0421-089-cough-f-20-4.mp3 │ │ ├── neg-0421-089-cough-f-20-5.mp3 │ │ ├── neg-0421-089-cough-f-20-6.mp3 │ │ ├── neg-0421-090-cough-f-17-1.mp3 │ │ ├── neg-0421-090-cough-f-17-11.mp3 │ │ ├── neg-0421-090-cough-f-17-2.mp3 │ │ ├── neg-0421-090-cough-f-17-3.mp3 │ │ ├── neg-0421-090-cough-f-17-4.mp3 │ │ ├── neg-0421-090-cough-f-17-5.mp3 │ │ ├── neg-0421-090-cough-f-17-6.mp3 │ │ ├── neg-0421-090-cough-f-17-7.mp3 │ │ ├── neg-0421-091-cough-m-47-1.mp3 │ │ ├── neg-0421-091-cough-m-47-2.mp3 │ │ ├── neg-0421-091-cough-m-47-3.mp3 │ │ ├── neg-0421-091-cough-m-47-4.mp3 │ │ ├── neg-0421-091-cough-m-47-5.mp3 │ │ ├── neg-0421-091-cough-m-47-6.mp3 │ │ ├── neg-0421-091-cough-m-47-7.mp3 │ │ ├── neg-0421-091-cough-m-47-8.mp3 │ │ ├── neg-0422-095-cough-m-53-0.mp3 │ │ ├── neg-0422-095-cough-m-53-1.mp3 │ │ ├── neg-0422-095-cough-m-53-10.mp3 │ │ ├── neg-0422-095-cough-m-53-12.mp3 │ │ ├── neg-0422-095-cough-m-53-13.mp3 │ │ ├── neg-0422-095-cough-m-53-14.mp3 │ │ ├── neg-0422-095-cough-m-53-15.mp3 │ │ ├── neg-0422-095-cough-m-53-2.mp3 │ │ ├── neg-0422-095-cough-m-53-3.mp3 │ │ ├── neg-0422-095-cough-m-53-4.mp3 │ │ ├── neg-0422-095-cough-m-53-5.mp3 │ │ ├── neg-0422-095-cough-m-53-6.mp3 │ │ ├── neg-0422-095-cough-m-53-7.mp3 │ │ ├── neg-0422-095-cough-m-53-8.mp3 │ │ ├── neg-0422-095-cough-m-53-9.mp3 │ │ ├── neg-0422-097-cough-m-37-1.mp3 │ │ ├── neg-0422-097-cough-m-37-3.mp3 │ │ ├── neg-0422-097-cough-m-37-4.mp3 │ │ ├── neg-0422-097-cough-m-37-8.mp3 │ │ ├── neg-0422-097-cough-m-37-9.mp3 │ │ ├── neg-0422-098-cough-f-24-0.mp3 │ │ ├── neg-0422-098-cough-f-24-1.mp3 │ │ └── neg-0422-098-cough-f-24-5.mp3 │ │ └── pos │ │ ├── pos-0421-084-cough-m-50-0.mp3 │ │ ├── pos-0421-084-cough-m-50-1.mp3 │ │ ├── pos-0421-084-cough-m-50-2.mp3 │ │ ├── pos-0421-084-cough-m-50-3.mp3 │ │ ├── pos-0421-084-cough-m-50-4.mp3 │ │ ├── pos-0421-084-cough-m-50-5.mp3 │ │ ├── pos-0421-084-cough-m-50-6.mp3 │ │ ├── pos-0421-084-cough-m-50-7.mp3 │ │ ├── pos-0421-086-cough-m-65-0.mp3 │ │ ├── pos-0421-086-cough-m-65-1.mp3 │ │ ├── pos-0421-086-cough-m-65-2.mp3 │ │ ├── pos-0421-086-cough-m-65-3.mp3 │ │ ├── pos-0421-086-cough-m-65-4.mp3 │ │ ├── pos-0421-086-cough-m-65-5.mp3 │ │ ├── pos-0421-086-cough-m-65-6.mp3 │ │ ├── pos-0421-086-cough-m-65-7.mp3 │ │ ├── pos-0421-086-cough-m-65-8.mp3 │ │ ├── pos-0421-087-cough-f-40-0.mp3 │ │ ├── pos-0421-087-cough-f-40-1.mp3 │ │ ├── pos-0421-087-cough-f-40-2.mp3 │ │ ├── pos-0421-087-cough-f-40-3.mp3 │ │ ├── pos-0421-087-cough-f-40-5.mp3 │ │ ├── pos-0421-087-cough-f-40-6.mp3 │ │ ├── pos-0421-092-cough-m-53-0.mp3 │ │ ├── pos-0421-092-cough-m-53-1.mp3 │ │ ├── pos-0421-092-cough-m-53-12.mp3 │ │ ├── pos-0421-092-cough-m-53-13.mp3 │ │ ├── pos-0421-092-cough-m-53-3.mp3 │ │ ├── pos-0421-092-cough-m-53-5.mp3 │ │ ├── pos-0421-092-cough-m-53-6.mp3 │ │ ├── pos-0421-092-cough-m-53-7.mp3 │ │ ├── pos-0421-092-cough-m-53-9.mp3 │ │ ├── pos-0421-093-cough-f-24-0.mp3 │ │ ├── pos-0421-093-cough-f-24-1.mp3 │ │ ├── pos-0421-093-cough-f-24-2.mp3 │ │ ├── pos-0421-093-cough-f-24-5.mp3 │ │ ├── pos-0421-093-cough-f-24-6.mp3 │ │ ├── pos-0421-094-cough-m-51-0.mp3 │ │ ├── pos-0421-094-cough-m-51-2.mp3 │ │ ├── pos-0421-094-cough-m-51-3.mp3 │ │ ├── pos-0421-094-cough-m-51-4.mp3 │ │ ├── pos-0421-094-cough-m-51-5.mp3 │ │ ├── pos-0421-094-cough-m-51-6.mp3 │ │ ├── pos-0421-094-cough-m-51-7.mp3 │ │ ├── pos-0422-096-cough-m-31-1.mp3 │ │ ├── pos-0422-096-cough-m-31-2.mp3 │ │ ├── pos-0422-096-cough-m-31-6.mp3 │ │ └── pos-0422-096-cough-m-31-8.mp3 ├── config.py ├── cough_svm.pkl ├── document │ └── create_table ├── figures │ ├── 克林顿.jpg │ ├── 卡特.jpg │ ├── 奥巴马.jpg │ ├── 小布什.jpg │ ├── 尼克松.jpg │ ├── 福特.jpg │ ├── 约翰逊.jpg │ ├── 老布什.jpg │ ├── 肯尼迪.jpg │ └── 里根.jpg ├── haface.py ├── main.py ├── sql.py ├── static │ ├── 2ed2d4f892b1de6883855c2b64eb2b0500693df7018d5f0c117293858751c21b.jpg │ ├── 318124b98158d5ff33f814512474a4753dfa5f1c161c09254111545accac3dd0.mp3 │ ├── 485ee98a7696e5196c3598c350a7418998a011ba9e736ad13d0624dc521d189e.mp3 │ ├── 595c7ddfa6aa736ff78901716f4af9f14c39274a00dc1c3977ee5bc13f095d25.mp3 │ ├── 95336304da07506b49902f53a42d092b136c4303d3d93d629b7923aeb52c0c2b.mp3 │ ├── cf471e072872786c5f74652dbbb23d06b6177b235e0e453f99e298f8b8191478.mp3 │ └── placeholder ├── util.py └── views.py ├── README.md ├── docs ├── 1.png ├── 2.png ├── 3.png └── icon.jpg ├── miniprogram ├── app.js ├── app.json ├── app.wxss ├── img │ ├── icon.jpg │ ├── record.png │ └── recording.png ├── lib │ └── weui.wxss ├── pages │ ├── getface │ │ ├── getface.js │ │ ├── getface.json │ │ ├── getface.wxml │ │ └── getface.wxss │ ├── identity │ │ ├── identity.js │ │ ├── identity.json │ │ ├── identity.wxml │ │ └── identity.wxss │ ├── index │ │ ├── index.js │ │ ├── index.json │ │ ├── index.wxml │ │ └── index.wxss │ ├── logs │ │ ├── logs.js │ │ ├── logs.json │ │ ├── logs.wxml │ │ └── logs.wxss │ ├── record │ │ ├── record.js │ │ ├── record.json │ │ ├── record.wxml │ │ └── record.wxss │ ├── rerecord │ │ ├── rerecord.js │ │ ├── rerecord.json │ │ ├── rerecord.wxml │ │ └── rerecord.wxss │ ├── return │ │ ├── return.js │ │ ├── return.wxml │ │ └── return.wxss │ ├── returnresult │ │ ├── resultimage │ │ │ ├── art1.jpeg │ │ │ ├── art2.jpg │ │ │ ├── art3.jpeg │ │ │ ├── art4.jpeg │ │ │ └── timg.jpeg │ │ ├── returnresult.js │ │ ├── returnresult.json │ │ ├── returnresult.wxml │ │ └── returnresult.wxss │ └── welcome │ │ ├── welcome.js │ │ ├── welcome.json │ │ ├── welcome.wxml │ │ └── welcome.wxss ├── project.config.json ├── recordings │ ├── long_cough.mp3 │ └── timg.jpg ├── sitemap.json └── utils │ └── util.js ├── nginx.conf └── nginxssl.conf /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /CoughCheckerAPI/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | __pycache__/ -------------------------------------------------------------------------------- /CoughCheckerAPI/Readme: -------------------------------------------------------------------------------- 1 | gunicorn -w 4 -b 172.17.23.158:8888 main:app 2 | 3 | nginx -c /etc/nginx/nginx.conf 4 | 5 | nginx.conf: 6 | http{ 7 | server { 8 | listen 80; 9 | server_name 127.0.0.1; 10 | 11 | location / { 12 | proxy_pass http://127.0.0.1:8888/; 13 | } 14 | } 15 | } 16 | events { 17 | worker_connections 1024; ## Default: 1024 18 | } 19 | 20 | 21 | TestPath:http://47.102.200.200:80/v1/test 22 | Method:Get 23 | Output:"helloworld" 24 | 25 | CoughPath:http://47.102.200.200:80/v1/check/cough 26 | Method:Post 27 | Input Body(form-data):{cough:cough_file} 28 | Output:{rate:rate} 29 | Sample Output:{'rate': '0.0'} 30 | headers: 31 | Cache-Control:no-cache 32 | Content-Type:multipart/form-data; boundary= 33 | Content-Length: 34 | Host: 35 | User-Agent:PostmanRuntime/7.26.8 36 | Accept:*/* 37 | Accept-Encoding:gzip, deflate, br 38 | Connection:keep-alive 39 | 40 | FigurePath:http://47.102.200.200:80/v1/check/figure 41 | Method:Post 42 | Input Body(form-data):{figure:figure_file} 43 | Output:{id:id,name:name,rate:rate} 44 | Sample Output:{'id': 4, 'name': '小布什', 'rate': '0.0'} 45 | headers: 46 | coughtoken:coughtoken From Coughchecker API 47 | Cache-Control:no-cache 48 | Content-Type:multipart/form-data; boundary= 49 | Content-Length: 50 | Host: 51 | User-Agent:PostmanRuntime/7.26.8 52 | Accept:*/* 53 | Accept-Encoding:gzip, deflate, br 54 | Connection:keep-alive 55 | -------------------------------------------------------------------------------- /CoughCheckerAPI/algorithm.py: -------------------------------------------------------------------------------- 1 | from builtins import * 2 | 3 | import librosa 4 | import matplotlib.pyplot as plt 5 | import numpy as np 6 | from sklearn.cluster import AffinityPropagation 7 | from sklearn import svm 8 | import glob 9 | import joblib 10 | 11 | def get_mfcc_feature(stream): 12 | return librosa.feature.mfcc(y=stream, n_mfcc=24).transpose().flatten().tolist() 13 | 14 | def cut_cough_segment(origin_stream,threshold=0.70,layback=0.15): #振幅门限取咳嗽段音频+AP聚类划分 15 | 16 | amplitude_start_process=0 17 | amplitude_end_process=0 18 | amplitude_start_list=[] 19 | 20 | for index in range(len(origin_stream)): 21 | if amplitude_start_process <= amplitude_end_process and origin_stream[index]>threshold: 22 | amplitude_start_process=index/len(origin_stream) 23 | amplitude_start_list.append(amplitude_start_process) 24 | if amplitude_end_process (str, str): 38 | """ 39 | find out who is in the img 40 | img should have been preprocessed, and must be 200*200 41 | :rtype: (t_id: str, name: str) if something wrong, id will be "" and name will be the reason 42 | :param img: cv2's img (i don't know whats that) 43 | """ 44 | img=img_pretreat(img) 45 | try: 46 | if (len(img) != 200 or len(img[0]) != 200): 47 | # wrong size 48 | raise IOError("Size Error") 49 | print(faceInfoDict) 50 | for faceInfo in faceInfoDict.values(): 51 | # i haven't make me understand it, maybe the algorithm is based on gray pics instead of colorful ones 52 | results = face_recognition.compare_faces( 53 | faceInfo.img, 54 | img 55 | )[0][0] 56 | if results: 57 | return faceInfo.t_id, faceInfo.name 58 | except: 59 | raise ValueError("Identity Not Found") 60 | 61 | 62 | def register(img, t_id: str, name: str = '') -> int: 63 | """ 64 | register the person in the img 65 | registered img should have been preprocessed 66 | :rtype: 0 success 67 | -1 unknown fault 68 | 1 exist 69 | :param img: cv2's img (i don't know whats that) 70 | :param t_id: str 71 | :param name: str 72 | """ 73 | img=img_pretreat(img) 74 | try: 75 | if t_id in faceInfoDict: 76 | return 1 77 | faceInfoDict[t_id] = FaceInfo(t_id, name, img) 78 | return 0 79 | except: 80 | return -1 81 | 82 | 83 | def init(): 84 | pwd = os.getcwd() + "/figures/" 85 | files = os.listdir(pwd) 86 | serial_id = 0 87 | for filename in files: 88 | serial_id += 1 89 | img = cv_imread(pwd + filename) 90 | face_locations = face_recognition.face_locations(img) 91 | # To find out the hugest face in the list. Use (r-l)*(b-t) and t, r, b, l = face_location 92 | face = sorted(face_locations, key=lambda face: (face[2] - face[0]) * (face[1] - face[3]))[-1] 93 | # get the real face and resize to 200 * 200 94 | img_q = cv2.resize(img[face[0]:face[2], face[3]:face[1]], (200, 200), interpolation=cv2.INTER_CUBIC) 95 | faceInfoDict[serial_id] = FaceInfo(img_q, serial_id, os.path.splitext(filename)[0]) 96 | 97 | 98 | init() 99 | -------------------------------------------------------------------------------- /CoughCheckerAPI/main.py: -------------------------------------------------------------------------------- 1 | from config import IP_HOST,IP_PORT 2 | from base import app 3 | from views import * 4 | 5 | 6 | if __name__=='__main__': 7 | app.run(host=IP_HOST,port=IP_PORT,debug=True) -------------------------------------------------------------------------------- /CoughCheckerAPI/sql.py: -------------------------------------------------------------------------------- 1 | from base import sql_cursor,sql_conn 2 | from builtins import * 3 | 4 | 5 | def add_check_record(id,name,rate): 6 | sentence="insert into check_record (user_id,name,covid_rate) values ('{0}','{1}',{2});".format(id,name,str(rate)) 7 | print(sentence) 8 | sql_cursor.execute(sentence) 9 | sql_conn.commit() -------------------------------------------------------------------------------- /CoughCheckerAPI/static/2ed2d4f892b1de6883855c2b64eb2b0500693df7018d5f0c117293858751c21b.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SegmentationFaultTeam/CovidCoughDetector/170e174d9e26d08ff07f749a3193cebd458b670c/CoughCheckerAPI/static/2ed2d4f892b1de6883855c2b64eb2b0500693df7018d5f0c117293858751c21b.jpg -------------------------------------------------------------------------------- /CoughCheckerAPI/static/318124b98158d5ff33f814512474a4753dfa5f1c161c09254111545accac3dd0.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SegmentationFaultTeam/CovidCoughDetector/170e174d9e26d08ff07f749a3193cebd458b670c/CoughCheckerAPI/static/318124b98158d5ff33f814512474a4753dfa5f1c161c09254111545accac3dd0.mp3 -------------------------------------------------------------------------------- /CoughCheckerAPI/static/485ee98a7696e5196c3598c350a7418998a011ba9e736ad13d0624dc521d189e.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SegmentationFaultTeam/CovidCoughDetector/170e174d9e26d08ff07f749a3193cebd458b670c/CoughCheckerAPI/static/485ee98a7696e5196c3598c350a7418998a011ba9e736ad13d0624dc521d189e.mp3 -------------------------------------------------------------------------------- /CoughCheckerAPI/static/595c7ddfa6aa736ff78901716f4af9f14c39274a00dc1c3977ee5bc13f095d25.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SegmentationFaultTeam/CovidCoughDetector/170e174d9e26d08ff07f749a3193cebd458b670c/CoughCheckerAPI/static/595c7ddfa6aa736ff78901716f4af9f14c39274a00dc1c3977ee5bc13f095d25.mp3 -------------------------------------------------------------------------------- /CoughCheckerAPI/static/95336304da07506b49902f53a42d092b136c4303d3d93d629b7923aeb52c0c2b.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SegmentationFaultTeam/CovidCoughDetector/170e174d9e26d08ff07f749a3193cebd458b670c/CoughCheckerAPI/static/95336304da07506b49902f53a42d092b136c4303d3d93d629b7923aeb52c0c2b.mp3 -------------------------------------------------------------------------------- /CoughCheckerAPI/static/cf471e072872786c5f74652dbbb23d06b6177b235e0e453f99e298f8b8191478.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SegmentationFaultTeam/CovidCoughDetector/170e174d9e26d08ff07f749a3193cebd458b670c/CoughCheckerAPI/static/cf471e072872786c5f74652dbbb23d06b6177b235e0e453f99e298f8b8191478.mp3 -------------------------------------------------------------------------------- /CoughCheckerAPI/static/placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SegmentationFaultTeam/CovidCoughDetector/170e174d9e26d08ff07f749a3193cebd458b670c/CoughCheckerAPI/static/placeholder -------------------------------------------------------------------------------- /CoughCheckerAPI/util.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | import random 3 | import datetime 4 | from builtins import * 5 | 6 | 7 | 8 | def commonResponse(statusCode=200, responseStr='Request Success', responseHeaders={}): 9 | return responseStr, statusCode, responseHeaders 10 | 11 | 12 | def generate_random_hash(): 13 | text=''.join(random.sample 14 | (['z','y','x','w','v','u','t','s','r','q','p','o','n','m','l','k','j','i','h','g','f','e','d','c','b','a'] 15 | , 15))+str(datetime.datetime.now()) 16 | return hashlib.sha256(text.encode("utf-8")).hexdigest() 17 | -------------------------------------------------------------------------------- /CoughCheckerAPI/views.py: -------------------------------------------------------------------------------- 1 | from flask import request 2 | import hashlib 3 | import redis 4 | import librosa 5 | 6 | from sql import * 7 | from base import app,clf,redis_cursor 8 | from util import * 9 | from algorithm import predict 10 | import haface 11 | 12 | 13 | @app.route('/v1/test',methods=['GET']) 14 | def test_api(): 15 | return commonResponse(200,"helloworld") 16 | 17 | 18 | @app.route('/v1/check/cough',methods=['POST']) 19 | def check_cough_api(): 20 | output={'rate':-100} 21 | 22 | cough_file=request.files.get('cough') 23 | if not cough_file: 24 | return commonResponse(400,"Cough File Not Found") 25 | 26 | cough_file_name=generate_random_hash()+'.mp3' 27 | cough_file_path='./static/'+cough_file_name 28 | with open(cough_file_path,'wb') as f: 29 | f.write(cough_file.read()) 30 | f.close() 31 | 32 | stream,sr=librosa.load(cough_file_path,sr=None) 33 | try: 34 | output['rate'] = predict(stream,clf)*100 35 | except IOError: #整段音频振幅全部低于门限值,无法检测到咳嗽声 36 | return commonResponse(400,"Please Cough More Heavy") 37 | if output['rate']<0: 38 | return commonResponse(400,"Please Cough More Times") 39 | 40 | cough_token = generate_random_hash() 41 | redis_cursor.set(cough_token,output['rate']) 42 | return commonResponse(200,str(output),{'coughtoken':cough_token}) 43 | 44 | 45 | @app.route('/v1/check/figure',methods=['POST']) 46 | def check_figure_api(): 47 | output = {'id': 'Null', 'name': 'Null','rate':'Null'} 48 | 49 | cough_token=request.headers.get('coughtoken') 50 | if not cough_token: 51 | return commonResponse(400,"Cough Token Header Not Found") 52 | covid_rate=redis_cursor.get(cough_token) 53 | if not covid_rate: 54 | return commonResponse(400,"Covid Rate Not Found") 55 | output['rate']=covid_rate.decode() 56 | 57 | figure_file = request.files.get('figure') 58 | if not figure_file: 59 | return commonResponse(400,"Figure File Not Found") 60 | 61 | figure_file_name = generate_random_hash() + '.jpg' 62 | figure_file_path = './static/' + figure_file_name 63 | with open(figure_file_path, 'wb') as f: 64 | f.write(figure_file.read()) 65 | f.close() 66 | 67 | figure_img = haface.cv_imread(figure_file_path) 68 | try: 69 | output['id'], output['name'] = haface.query(figure_img) 70 | except ValueError: 71 | return commonResponse(400, "Identity Not Found") 72 | except IOError: 73 | return commonResponse(400, "Figure File Size Error") 74 | 75 | add_check_record(output['id'],output['name'],output['rate']) 76 | return commonResponse(200,str(output)) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # COVID咳嗽声检测 2 | 3 | ### 简介 4 | 5 | 本项目旨在通过机器学习,用咳嗽的录音判断使用者是否感染了新冠病毒,可以作为有效的新冠病毒初步检测的机制,提高新冠病毒检测的效率。在检测的准确度方面,有MIT和剑桥的论文作为理论支撑,理论上最高准确率可达98%,完全满足作为初步检测的条件。 6 | 7 | ### 架构 8 | 9 | 机器学习的后端,训练完成后加载到云服务器上,开放一个传入接口,传入一张照片和一段音频,开放一个传出接口,返回一段文字,包含用户的名字和是否感染 10 | 11 | 前端从摄像头获取用户咳嗽时的照片,同时录取咳嗽的音频,传送给后端;接受从后端返回的用户名和是否感染,显示在屏幕上 12 | 13 | ### 后端 14 | 15 | 后端部署: 16 | 在cough-checker-api根目录下使用gunicorn启动项目 17 | gunicorn -w 4 -b 内网IP:端口号 main:app & 18 | 19 | 将nginx.conf和nginxssl.conf放入/etc/nginx文件夹下(只是建议,可以放在其他位置)后: 20 | nginx -c /etc/nginx/nginx.conf 或 nginx -c /etc/nginx/nginxssl.conf 21 | 启动nginx后即可通过域名或外网IP访问接口 22 | 23 | 运行环境:Ubuntu 16.04 Server 24 | 25 | 项目依赖: 26 | ubuntu:Python3、ffmpeg、nginx 27 | Python 3:gunicorn、flask、numpy、cv2、dlib、face_recognition、sklearn、matplotlib、pymysql、redis、librosa、flask_cors 28 | 29 | ### 前端 30 | 31 | 使用微信小程序开发html、js、css结合 32 | 33 | 34 | 35 | [小程序实例](https://github.com/SegmentationFaultTeam/CovidCoughDetector/tree/master/docs/1.png) 36 | 37 | 38 | 39 | https://github.com/SegmentationFaultTeam/CovidCoughDetector/tree/master/docs/2.png 40 | 41 | https://github.com/SegmentationFaultTeam/CovidCoughDetector/tree/master/docs/3.png -------------------------------------------------------------------------------- /docs/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SegmentationFaultTeam/CovidCoughDetector/170e174d9e26d08ff07f749a3193cebd458b670c/docs/1.png -------------------------------------------------------------------------------- /docs/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SegmentationFaultTeam/CovidCoughDetector/170e174d9e26d08ff07f749a3193cebd458b670c/docs/2.png -------------------------------------------------------------------------------- /docs/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SegmentationFaultTeam/CovidCoughDetector/170e174d9e26d08ff07f749a3193cebd458b670c/docs/3.png -------------------------------------------------------------------------------- /docs/icon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SegmentationFaultTeam/CovidCoughDetector/170e174d9e26d08ff07f749a3193cebd458b670c/docs/icon.jpg -------------------------------------------------------------------------------- /miniprogram/app.js: -------------------------------------------------------------------------------- 1 | //app.js 2 | App({ 3 | onLaunch: function () { 4 | // 展示本地存储能力 5 | var logs = wx.getStorageSync('logs') || [] 6 | logs.unshift(Date.now()) 7 | wx.setStorageSync('logs', logs) 8 | 9 | // 登录 10 | wx.login({ 11 | success: res => { 12 | // 发送 res.code 到后台换取 openId, sessionKey, unionId 13 | } 14 | }) 15 | // 获取用户信息 16 | wx.getSetting({ 17 | success: res => { 18 | if (res.authSetting['scope.userInfo']) { 19 | // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框 20 | wx.getUserInfo({ 21 | success: res => { 22 | // 可以将 res 发送给后台解码出 unionId 23 | this.globalData.userInfo = res.userInfo 24 | 25 | // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 26 | // 所以此处加入 callback 以防止这种情况 27 | if (this.userInfoReadyCallback) { 28 | this.userInfoReadyCallback(res) 29 | } 30 | } 31 | }) 32 | } 33 | } 34 | }) 35 | }, 36 | globalData: { 37 | userInfo: null, 38 | username:'', 39 | geo:'', 40 | recrt:[], 41 | imgrt:[], 42 | rtpage:[], 43 | coughtoken:'', 44 | covidrate:'', 45 | username:'', 46 | recurl:'http://47.102.200.200:80/v1/check/cough', 47 | imgurl:'http://47.102.200.200:80/v1/check/figure', 48 | } 49 | }) -------------------------------------------------------------------------------- /miniprogram/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "pages": [ 3 | "pages/welcome/welcome", 4 | "pages/identity/identity", 5 | "pages/record/record", 6 | "pages/rerecord/rerecord", 7 | "pages/getface/getface", 8 | "pages/index/index", 9 | "pages/logs/logs", 10 | "pages/return/return", 11 | "pages/returnresult/returnresult" 12 | ], 13 | "window": { 14 | "navigationBarTitleText": "COVID-19咳嗽声检测", 15 | "backgroundTextStyle": "light", 16 | "navigationBarBackgroundColor": "#fff", 17 | "navigationBarTextStyle": "black" 18 | }, 19 | "networkTimeout": { 20 | "request": 10000, 21 | "connectSocket": 10000, 22 | "uploadFile": 10000, 23 | "downloadFile": 10000 24 | }, 25 | "style": "v2", 26 | "sitemapLocation": "sitemap.json" 27 | } -------------------------------------------------------------------------------- /miniprogram/app.wxss: -------------------------------------------------------------------------------- 1 | /**app.wxss**/ 2 | .container { 3 | height: 100%; 4 | display: flex; 5 | flex-direction: column; 6 | align-items: center; 7 | justify-content: space-between; 8 | padding: 200rpx 0; 9 | box-sizing: border-box; 10 | } 11 | /* pages/welcome/welcome.wxss */ 12 | button{ 13 | margin-top: 30rpx; 14 | margin-bottom: 30rpx; 15 | } 16 | .picture{ 17 | display: flex; 18 | width: 100px; 19 | height: 100px; 20 | align-items: center; 21 | justify-content: center; 22 | text-align: center; 23 | } 24 | .debugging{ 25 | display: none; 26 | width: 100%; 27 | height: 100%; 28 | align-items: center; 29 | justify-content: center; 30 | text-align: center; 31 | font-weight: 300; 32 | font-size-adjust: 1; 33 | } 34 | .title{ 35 | display: flex; 36 | width: 100%; 37 | height: 100%; 38 | align-items: center; 39 | justify-content: center; 40 | text-align: center; 41 | font-weight: 300; 42 | font-size-adjust: 1; 43 | } 44 | .mytext{ 45 | display: flex; 46 | width: 100%; 47 | height: 100%; 48 | align-items: center; 49 | justify-content: center; 50 | text-align: center; 51 | font-weight: 300; 52 | } 53 | .button-sp-area{ 54 | margin: 0 auto; 55 | width: 60%; 56 | } -------------------------------------------------------------------------------- /miniprogram/img/icon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SegmentationFaultTeam/CovidCoughDetector/170e174d9e26d08ff07f749a3193cebd458b670c/miniprogram/img/icon.jpg -------------------------------------------------------------------------------- /miniprogram/img/record.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SegmentationFaultTeam/CovidCoughDetector/170e174d9e26d08ff07f749a3193cebd458b670c/miniprogram/img/record.png -------------------------------------------------------------------------------- /miniprogram/img/recording.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SegmentationFaultTeam/CovidCoughDetector/170e174d9e26d08ff07f749a3193cebd458b670c/miniprogram/img/recording.png -------------------------------------------------------------------------------- /miniprogram/lib/weui.wxss: -------------------------------------------------------------------------------- 1 | /*! 2 | * weui.js v1.1.0 (https://github.com/weui/weui-wxss) 3 | * Copyright 2016, wechat ui team 4 | * MIT license 5 | */ 6 | page { 7 | line-height: 1.6; 8 | font-family: -apple-system-font, "Helvetica Neue", sans-serif; 9 | } 10 | icon { 11 | vertical-align: middle; 12 | } 13 | .weui-cells { 14 | position: relative; 15 | margin-top: 1.17647059em; 16 | background-color: #FFFFFF; 17 | line-height: 1.41176471; 18 | font-size: 17px; 19 | } 20 | .weui-cells:before { 21 | content: " "; 22 | position: absolute; 23 | left: 0; 24 | top: 0; 25 | right: 0; 26 | height: 1px; 27 | border-top: 1rpx solid #D9D9D9; 28 | color: #D9D9D9; 29 | } 30 | .weui-cells:after { 31 | content: " "; 32 | position: absolute; 33 | left: 0; 34 | bottom: 0; 35 | right: 0; 36 | height: 1px; 37 | border-bottom: 1rpx solid #D9D9D9; 38 | color: #D9D9D9; 39 | } 40 | .weui-cells__title { 41 | margin-top: .77em; 42 | margin-bottom: .3em; 43 | padding-left: 15px; 44 | padding-right: 15px; 45 | color: #999999; 46 | font-size: 14px; 47 | } 48 | .weui-cells_after-title { 49 | margin-top: 0; 50 | } 51 | .weui-cells__tips { 52 | margin-top: .3em; 53 | color: #999999; 54 | padding-left: 15px; 55 | padding-right: 15px; 56 | font-size: 14px; 57 | } 58 | .weui-cell { 59 | padding: 10px 15px; 60 | position: relative; 61 | display: -webkit-box; 62 | display: -webkit-flex; 63 | display: flex; 64 | -webkit-box-align: center; 65 | -webkit-align-items: center; 66 | align-items: center; 67 | } 68 | .weui-cell:before { 69 | content: " "; 70 | position: absolute; 71 | left: 0; 72 | top: 0; 73 | right: 0; 74 | height: 1px; 75 | border-top: 1rpx solid #D9D9D9; 76 | color: #D9D9D9; 77 | left: 15px; 78 | } 79 | .weui-cell:first-child:before { 80 | display: none; 81 | } 82 | .weui-cell_active { 83 | background-color: #ECECEC; 84 | } 85 | .weui-cell_primary { 86 | -webkit-box-align: start; 87 | -webkit-align-items: flex-start; 88 | align-items: flex-start; 89 | } 90 | .weui-cell__bd { 91 | -webkit-box-flex: 1; 92 | -webkit-flex: 1; 93 | flex: 1; 94 | } 95 | .weui-cell__ft { 96 | text-align: right; 97 | color: #999999; 98 | } 99 | .weui-cell_access { 100 | color: inherit; 101 | } 102 | .weui-cell__ft_in-access { 103 | padding-right: 13px; 104 | position: relative; 105 | } 106 | .weui-cell__ft_in-access:after { 107 | content: " "; 108 | display: inline-block; 109 | height: 6px; 110 | width: 6px; 111 | border-width: 2px 2px 0 0; 112 | border-color: #C8C8CD; 113 | border-style: solid; 114 | -webkit-transform: matrix(0.71, 0.71, -0.71, 0.71, 0, 0); 115 | transform: matrix(0.71, 0.71, -0.71, 0.71, 0, 0); 116 | position: relative; 117 | top: -2px; 118 | position: absolute; 119 | top: 50%; 120 | margin-top: -4px; 121 | right: 2px; 122 | } 123 | .weui-cell_link { 124 | color: #586C94; 125 | font-size: 14px; 126 | } 127 | .weui-cell_link:active { 128 | background-color: #ECECEC; 129 | } 130 | .weui-cell_link:first-child:before { 131 | display: block; 132 | } 133 | .weui-icon-radio { 134 | margin-left: 3.2px; 135 | margin-right: 3.2px; 136 | } 137 | .weui-icon-checkbox_circle, 138 | .weui-icon-checkbox_success { 139 | margin-left: 4.6px; 140 | margin-right: 4.6px; 141 | } 142 | .weui-check__label:active { 143 | background-color: #ECECEC; 144 | } 145 | .weui-check { 146 | position: absolute; 147 | left: -9999px; 148 | } 149 | .weui-check__hd_in-checkbox { 150 | padding-right: 0.35em; 151 | } 152 | .weui-cell__ft_in-radio { 153 | padding-left: 0.35em; 154 | } 155 | .weui-cell_input { 156 | padding-top: 0; 157 | padding-bottom: 0; 158 | } 159 | .weui-label { 160 | width: 105px; 161 | word-wrap: break-word; 162 | word-break: break-all; 163 | } 164 | .weui-input { 165 | height: 2.58823529em; 166 | min-height: 2.58823529em; 167 | line-height: 2.58823529em; 168 | } 169 | .weui-toptips { 170 | position: fixed; 171 | -webkit-transform: translateZ(0); 172 | transform: translateZ(0); 173 | top: 0; 174 | left: 0; 175 | right: 0; 176 | padding: 5px; 177 | font-size: 14px; 178 | text-align: center; 179 | color: #FFFFFF; 180 | z-index: 5000; 181 | word-wrap: break-word; 182 | word-break: break-all; 183 | } 184 | .weui-toptips_warn { 185 | background-color: #E64340; 186 | } 187 | .weui-textarea { 188 | display: block; 189 | width: 100%; 190 | } 191 | .weui-textarea-counter { 192 | color: #B2B2B2; 193 | text-align: right; 194 | } 195 | .weui-textarea-counter_warn { 196 | color: #E64340; 197 | } 198 | .weui-cell_warn { 199 | color: #E64340; 200 | } 201 | .weui-form-preview { 202 | position: relative; 203 | background-color: #FFFFFF; 204 | } 205 | .weui-form-preview:before { 206 | content: " "; 207 | position: absolute; 208 | left: 0; 209 | top: 0; 210 | right: 0; 211 | height: 1px; 212 | border-top: 1rpx solid #D9D9D9; 213 | color: #D9D9D9; 214 | } 215 | .weui-form-preview:after { 216 | content: " "; 217 | position: absolute; 218 | left: 0; 219 | bottom: 0; 220 | right: 0; 221 | height: 1px; 222 | border-bottom: 1rpx solid #D9D9D9; 223 | color: #D9D9D9; 224 | } 225 | .weui-form-preview__value { 226 | font-size: 14px; 227 | } 228 | .weui-form-preview__value_in-hd { 229 | font-size: 26px; 230 | } 231 | .weui-form-preview__hd { 232 | position: relative; 233 | padding: 10px 15px; 234 | text-align: right; 235 | line-height: 2.5em; 236 | } 237 | .weui-form-preview__hd:after { 238 | content: " "; 239 | position: absolute; 240 | left: 0; 241 | bottom: 0; 242 | right: 0; 243 | height: 1px; 244 | border-bottom: 1rpx solid #D9D9D9; 245 | color: #D9D9D9; 246 | left: 15px; 247 | } 248 | .weui-form-preview__bd { 249 | padding: 10px 15px; 250 | font-size: .9em; 251 | text-align: right; 252 | color: #999999; 253 | line-height: 2; 254 | } 255 | .weui-form-preview__ft { 256 | position: relative; 257 | line-height: 50px; 258 | display: -webkit-box; 259 | display: -webkit-flex; 260 | display: flex; 261 | } 262 | .weui-form-preview__ft:after { 263 | content: " "; 264 | position: absolute; 265 | left: 0; 266 | top: 0; 267 | right: 0; 268 | height: 1px; 269 | border-top: 1rpx solid #D5D5D6; 270 | color: #D5D5D6; 271 | } 272 | .weui-form-preview__item { 273 | overflow: hidden; 274 | } 275 | .weui-form-preview__label { 276 | float: left; 277 | margin-right: 1em; 278 | min-width: 4em; 279 | color: #999999; 280 | text-align: justify; 281 | text-align-last: justify; 282 | } 283 | .weui-form-preview__value { 284 | display: block; 285 | overflow: hidden; 286 | word-break: normal; 287 | word-wrap: break-word; 288 | } 289 | .weui-form-preview__btn { 290 | position: relative; 291 | display: block; 292 | -webkit-box-flex: 1; 293 | -webkit-flex: 1; 294 | flex: 1; 295 | color: #3CC51F; 296 | text-align: center; 297 | } 298 | .weui-form-preview__btn:after { 299 | content: " "; 300 | position: absolute; 301 | left: 0; 302 | top: 0; 303 | width: 1px; 304 | bottom: 0; 305 | border-left: 1rpx solid #D5D5D6; 306 | color: #D5D5D6; 307 | } 308 | .weui-form-preview__btn:first-child:after { 309 | display: none; 310 | } 311 | .weui-form-preview__btn_active { 312 | background-color: #EEEEEE; 313 | } 314 | .weui-form-preview__btn_default { 315 | color: #999999; 316 | } 317 | .weui-form-preview__btn_primary { 318 | color: #0BB20C; 319 | } 320 | .weui-cell_select { 321 | padding: 0; 322 | } 323 | .weui-select { 324 | position: relative; 325 | padding-left: 15px; 326 | padding-right: 30px; 327 | height: 2.58823529em; 328 | min-height: 2.58823529em; 329 | line-height: 2.58823529em; 330 | border-right: 1rpx solid #D9D9D9; 331 | } 332 | .weui-select:before { 333 | content: " "; 334 | display: inline-block; 335 | height: 6px; 336 | width: 6px; 337 | border-width: 2px 2px 0 0; 338 | border-color: #C8C8CD; 339 | border-style: solid; 340 | -webkit-transform: matrix(0.71, 0.71, -0.71, 0.71, 0, 0); 341 | transform: matrix(0.71, 0.71, -0.71, 0.71, 0, 0); 342 | position: relative; 343 | top: -2px; 344 | position: absolute; 345 | top: 50%; 346 | right: 15px; 347 | margin-top: -4px; 348 | } 349 | .weui-select_in-select-after { 350 | padding-left: 0; 351 | } 352 | .weui-cell__hd_in-select-after, 353 | .weui-cell__bd_in-select-before { 354 | padding-left: 15px; 355 | } 356 | .weui-cell_vcode { 357 | padding-right: 0; 358 | } 359 | .weui-vcode-img { 360 | margin-left: 5px; 361 | height: 2.58823529em; 362 | vertical-align: middle; 363 | } 364 | .weui-vcode-btn { 365 | display: inline-block; 366 | height: 2.58823529em; 367 | margin-left: 5px; 368 | padding: 0 0.6em 0 0.7em; 369 | border-left: 1px solid #E5E5E5; 370 | line-height: 2.58823529em; 371 | vertical-align: middle; 372 | font-size: 17px; 373 | color: #3CC51F; 374 | white-space: nowrap; 375 | } 376 | .weui-vcode-btn:active { 377 | color: #52a341; 378 | } 379 | .weui-cell_switch { 380 | padding-top: 6px; 381 | padding-bottom: 6px; 382 | } 383 | .weui-uploader__hd { 384 | display: -webkit-box; 385 | display: -webkit-flex; 386 | display: flex; 387 | padding-bottom: 10px; 388 | -webkit-box-align: center; 389 | -webkit-align-items: center; 390 | align-items: center; 391 | } 392 | .weui-uploader__title { 393 | -webkit-box-flex: 1; 394 | -webkit-flex: 1; 395 | flex: 1; 396 | } 397 | .weui-uploader__info { 398 | color: #B2B2B2; 399 | } 400 | .weui-uploader__bd { 401 | margin-bottom: -4px; 402 | margin-right: -9px; 403 | overflow: hidden; 404 | } 405 | .weui-uploader__file { 406 | float: left; 407 | margin-right: 9px; 408 | margin-bottom: 9px; 409 | } 410 | .weui-uploader__img { 411 | display: block; 412 | width: 79px; 413 | height: 79px; 414 | } 415 | .weui-uploader__file_status { 416 | position: relative; 417 | } 418 | .weui-uploader__file_status:before { 419 | content: " "; 420 | position: absolute; 421 | top: 0; 422 | right: 0; 423 | bottom: 0; 424 | left: 0; 425 | background-color: rgba(0, 0, 0, 0.5); 426 | } 427 | .weui-uploader__file-content { 428 | position: absolute; 429 | top: 50%; 430 | left: 50%; 431 | -webkit-transform: translate(-50%, -50%); 432 | transform: translate(-50%, -50%); 433 | color: #FFFFFF; 434 | } 435 | .weui-uploader__input-box { 436 | float: left; 437 | position: relative; 438 | margin-right: 9px; 439 | margin-bottom: 9px; 440 | width: 77px; 441 | height: 77px; 442 | border: 1px solid #D9D9D9; 443 | } 444 | .weui-uploader__input-box:before, 445 | .weui-uploader__input-box:after { 446 | content: " "; 447 | position: absolute; 448 | top: 50%; 449 | left: 50%; 450 | -webkit-transform: translate(-50%, -50%); 451 | transform: translate(-50%, -50%); 452 | background-color: #D9D9D9; 453 | } 454 | .weui-uploader__input-box:before { 455 | width: 2px; 456 | height: 39.5px; 457 | } 458 | .weui-uploader__input-box:after { 459 | width: 39.5px; 460 | height: 2px; 461 | } 462 | .weui-uploader__input-box:active { 463 | border-color: #999999; 464 | } 465 | .weui-uploader__input-box:active:before, 466 | .weui-uploader__input-box:active:after { 467 | background-color: #999999; 468 | } 469 | .weui-uploader__input { 470 | position: absolute; 471 | z-index: 1; 472 | top: 0; 473 | left: 0; 474 | width: 100%; 475 | height: 100%; 476 | opacity: 0; 477 | } 478 | .weui-article { 479 | padding: 20px 15px; 480 | font-size: 15px; 481 | } 482 | .weui-article__section { 483 | margin-bottom: 1.5em; 484 | } 485 | .weui-article__h1 { 486 | font-size: 18px; 487 | font-weight: 400; 488 | margin-bottom: .9em; 489 | } 490 | .weui-article__h2 { 491 | font-size: 16px; 492 | font-weight: 400; 493 | margin-bottom: .34em; 494 | } 495 | .weui-article__h3 { 496 | font-weight: 400; 497 | font-size: 15px; 498 | margin-bottom: .34em; 499 | } 500 | .weui-article__p { 501 | margin: 0 0 .8em; 502 | } 503 | .weui-msg { 504 | padding-top: 36px; 505 | text-align: center; 506 | } 507 | .weui-msg__link { 508 | display: inline; 509 | color: #586C94; 510 | } 511 | .weui-msg__icon-area { 512 | margin-bottom: 30px; 513 | } 514 | .weui-msg__text-area { 515 | margin-bottom: 25px; 516 | padding: 0 20px; 517 | } 518 | .weui-msg__title { 519 | margin-bottom: 5px; 520 | font-weight: 400; 521 | font-size: 20px; 522 | } 523 | .weui-msg__desc { 524 | font-size: 14px; 525 | color: #999999; 526 | } 527 | .weui-msg__opr-area { 528 | margin-bottom: 25px; 529 | } 530 | .weui-msg__extra-area { 531 | margin-bottom: 15px; 532 | font-size: 14px; 533 | color: #999999; 534 | } 535 | @media screen and (min-height: 438px) { 536 | .weui-msg__extra-area { 537 | position: fixed; 538 | left: 0; 539 | bottom: 0; 540 | width: 100%; 541 | text-align: center; 542 | } 543 | } 544 | .weui-flex { 545 | display: -webkit-box; 546 | display: -webkit-flex; 547 | display: flex; 548 | } 549 | .weui-flex__item { 550 | -webkit-box-flex: 1; 551 | -webkit-flex: 1; 552 | flex: 1; 553 | } 554 | .weui-btn { 555 | margin-top: 15px; 556 | } 557 | .weui-btn:first-child { 558 | margin-top: 0; 559 | } 560 | .weui-btn-area { 561 | margin: 1.17647059em 15px 0.3em; 562 | } 563 | .weui-agree { 564 | display: block; 565 | padding: .5em 15px; 566 | font-size: 13px; 567 | } 568 | .weui-agree__text { 569 | color: #999999; 570 | } 571 | .weui-agree__link { 572 | display: inline; 573 | color: #586C94; 574 | } 575 | .weui-agree__checkbox { 576 | position: absolute; 577 | left: -9999px; 578 | } 579 | .weui-agree__checkbox-icon { 580 | position: relative; 581 | top: 2px; 582 | display: inline-block; 583 | border: 1px solid #D1D1D1; 584 | background-color: #FFFFFF; 585 | border-radius: 3px; 586 | width: 11px; 587 | height: 11px; 588 | } 589 | .weui-agree__checkbox-icon-check { 590 | position: absolute; 591 | top: 1px; 592 | left: 1px; 593 | } 594 | .weui-footer { 595 | color: #999999; 596 | font-size: 14px; 597 | text-align: center; 598 | } 599 | .weui-footer_fixed-bottom { 600 | position: fixed; 601 | bottom: .52em; 602 | left: 0; 603 | right: 0; 604 | } 605 | .weui-footer__links { 606 | font-size: 0; 607 | } 608 | .weui-footer__link { 609 | display: inline-block; 610 | vertical-align: top; 611 | margin: 0 .62em; 612 | position: relative; 613 | font-size: 14px; 614 | color: #586C94; 615 | } 616 | .weui-footer__link:before { 617 | content: " "; 618 | position: absolute; 619 | left: 0; 620 | top: 0; 621 | width: 1px; 622 | bottom: 0; 623 | border-left: 1rpx solid #C7C7C7; 624 | color: #C7C7C7; 625 | left: -0.65em; 626 | top: .36em; 627 | bottom: .36em; 628 | } 629 | .weui-footer__link:first-child:before { 630 | display: none; 631 | } 632 | .weui-footer__text { 633 | padding: 0 .34em; 634 | font-size: 12px; 635 | } 636 | .weui-grids { 637 | border-top: 1rpx solid #D9D9D9; 638 | border-left: 1rpx solid #D9D9D9; 639 | overflow: hidden; 640 | } 641 | .weui-grid { 642 | position: relative; 643 | float: left; 644 | padding: 20px 10px; 645 | width: 33.33333333%; 646 | box-sizing: border-box; 647 | border-right: 1rpx solid #D9D9D9; 648 | border-bottom: 1rpx solid #D9D9D9; 649 | } 650 | .weui-grid_active { 651 | background-color: #ECECEC; 652 | } 653 | .weui-grid__icon { 654 | display: block; 655 | width: 28px; 656 | height: 28px; 657 | margin: 0 auto; 658 | } 659 | .weui-grid__label { 660 | margin-top: 5px; 661 | display: block; 662 | text-align: center; 663 | color: #000000; 664 | font-size: 14px; 665 | white-space: nowrap; 666 | text-overflow: ellipsis; 667 | overflow: hidden; 668 | } 669 | .weui-loading { 670 | margin: 0 5px; 671 | width: 20px; 672 | height: 20px; 673 | display: inline-block; 674 | vertical-align: middle; 675 | -webkit-animation: weuiLoading 1s steps(12, end) infinite; 676 | animation: weuiLoading 1s steps(12, end) infinite; 677 | background: transparent url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAiIGhlaWdodD0iMTIwIiB2aWV3Qm94PSIwIDAgMTAwIDEwMCI+PHBhdGggZmlsbD0ibm9uZSIgZD0iTTAgMGgxMDB2MTAwSDB6Ii8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjRTlFOUU5IiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAgLTMwKSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iIzk4OTY5NyIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgzMCAxMDUuOTggNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjOUI5OTlBIiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKDYwIDc1Ljk4IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0EzQTFBMiIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSg5MCA2NSA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNBQkE5QUEiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoMTIwIDU4LjY2IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0IyQjJCMiIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgxNTAgNTQuMDIgNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjQkFCOEI5IiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKDE4MCA1MCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNDMkMwQzEiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTE1MCA0NS45OCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNDQkNCQ0IiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTEyMCA0MS4zNCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNEMkQyRDIiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTkwIDM1IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0RBREFEQSIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgtNjAgMjQuMDIgNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjRTJFMkUyIiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKC0zMCAtNS45OCA2NSkiLz48L3N2Zz4=) no-repeat; 678 | background-size: 100%; 679 | } 680 | @-webkit-keyframes weuiLoading { 681 | 0% { 682 | -webkit-transform: rotate3d(0, 0, 1, 0deg); 683 | transform: rotate3d(0, 0, 1, 0deg); 684 | } 685 | 100% { 686 | -webkit-transform: rotate3d(0, 0, 1, 360deg); 687 | transform: rotate3d(0, 0, 1, 360deg); 688 | } 689 | } 690 | @keyframes weuiLoading { 691 | 0% { 692 | -webkit-transform: rotate3d(0, 0, 1, 0deg); 693 | transform: rotate3d(0, 0, 1, 0deg); 694 | } 695 | 100% { 696 | -webkit-transform: rotate3d(0, 0, 1, 360deg); 697 | transform: rotate3d(0, 0, 1, 360deg); 698 | } 699 | } 700 | .weui-badge { 701 | display: inline-block; 702 | padding: .15em .4em; 703 | min-width: 8px; 704 | border-radius: 18px; 705 | background-color: #F43530; 706 | color: #FFFFFF; 707 | line-height: 1.2; 708 | text-align: center; 709 | font-size: 12px; 710 | vertical-align: middle; 711 | } 712 | .weui-badge_dot { 713 | padding: .4em; 714 | min-width: 0; 715 | } 716 | .weui-loadmore { 717 | width: 65%; 718 | margin: 1.5em auto; 719 | line-height: 1.6em; 720 | font-size: 14px; 721 | text-align: center; 722 | } 723 | .weui-loadmore__tips { 724 | display: inline-block; 725 | vertical-align: middle; 726 | } 727 | .weui-loadmore_line { 728 | border-top: 1px solid #E5E5E5; 729 | margin-top: 2.4em; 730 | } 731 | .weui-loadmore__tips_in-line { 732 | position: relative; 733 | top: -0.9em; 734 | padding: 0 .55em; 735 | background-color: #FFFFFF; 736 | color: #999999; 737 | } 738 | .weui-loadmore__tips_in-dot { 739 | position: relative; 740 | padding: 0 .16em; 741 | width: 4px; 742 | height: 1.6em; 743 | } 744 | .weui-loadmore__tips_in-dot:before { 745 | content: " "; 746 | position: absolute; 747 | top: 50%; 748 | left: 50%; 749 | margin-top: -1px; 750 | margin-left: -2px; 751 | width: 4px; 752 | height: 4px; 753 | border-radius: 50%; 754 | background-color: #E5E5E5; 755 | } 756 | .weui-panel { 757 | background-color: #FFFFFF; 758 | margin-top: 10px; 759 | position: relative; 760 | overflow: hidden; 761 | } 762 | .weui-panel:first-child { 763 | margin-top: 0; 764 | } 765 | .weui-panel:before { 766 | content: " "; 767 | position: absolute; 768 | left: 0; 769 | top: 0; 770 | right: 0; 771 | height: 1px; 772 | border-top: 1rpx solid #E5E5E5; 773 | color: #E5E5E5; 774 | } 775 | .weui-panel:after { 776 | content: " "; 777 | position: absolute; 778 | left: 0; 779 | bottom: 0; 780 | right: 0; 781 | height: 1px; 782 | border-bottom: 1rpx solid #E5E5E5; 783 | color: #E5E5E5; 784 | } 785 | .weui-panel__hd { 786 | padding: 14px 15px 10px; 787 | color: #999999; 788 | font-size: 13px; 789 | position: relative; 790 | } 791 | .weui-panel__hd:after { 792 | content: " "; 793 | position: absolute; 794 | left: 0; 795 | bottom: 0; 796 | right: 0; 797 | height: 1px; 798 | border-bottom: 1rpx solid #E5E5E5; 799 | color: #E5E5E5; 800 | left: 15px; 801 | } 802 | .weui-media-box { 803 | padding: 15px; 804 | position: relative; 805 | } 806 | .weui-media-box:before { 807 | content: " "; 808 | position: absolute; 809 | left: 0; 810 | top: 0; 811 | right: 0; 812 | height: 1px; 813 | border-top: 1rpx solid #E5E5E5; 814 | color: #E5E5E5; 815 | left: 15px; 816 | } 817 | .weui-media-box:first-child:before { 818 | display: none; 819 | } 820 | .weui-media-box__title { 821 | font-weight: 400; 822 | font-size: 17px; 823 | width: auto; 824 | overflow: hidden; 825 | text-overflow: ellipsis; 826 | white-space: nowrap; 827 | word-wrap: normal; 828 | word-wrap: break-word; 829 | word-break: break-all; 830 | } 831 | .weui-media-box__desc { 832 | color: #999999; 833 | font-size: 13px; 834 | line-height: 1.2; 835 | overflow: hidden; 836 | text-overflow: ellipsis; 837 | display: -webkit-box; 838 | -webkit-box-orient: vertical; 839 | -webkit-line-clamp: 2; 840 | } 841 | .weui-media-box__info { 842 | margin-top: 15px; 843 | padding-bottom: 5px; 844 | font-size: 13px; 845 | color: #CECECE; 846 | line-height: 1em; 847 | list-style: none; 848 | overflow: hidden; 849 | } 850 | .weui-media-box__info__meta { 851 | float: left; 852 | padding-right: 1em; 853 | } 854 | .weui-media-box__info__meta_extra { 855 | padding-left: 1em; 856 | border-left: 1px solid #CECECE; 857 | } 858 | .weui-media-box__title_in-text { 859 | margin-bottom: 8px; 860 | } 861 | .weui-media-box_appmsg { 862 | display: -webkit-box; 863 | display: -webkit-flex; 864 | display: flex; 865 | -webkit-box-align: center; 866 | -webkit-align-items: center; 867 | align-items: center; 868 | } 869 | .weui-media-box__thumb { 870 | width: 100%; 871 | height: 100%; 872 | vertical-align: top; 873 | } 874 | .weui-media-box__hd_in-appmsg { 875 | margin-right: .8em; 876 | width: 60px; 877 | height: 60px; 878 | line-height: 60px; 879 | text-align: center; 880 | } 881 | .weui-media-box__bd_in-appmsg { 882 | -webkit-box-flex: 1; 883 | -webkit-flex: 1; 884 | flex: 1; 885 | min-width: 0; 886 | } 887 | .weui-media-box_small-appmsg { 888 | padding: 0; 889 | } 890 | .weui-cells_in-small-appmsg { 891 | margin-top: 0; 892 | } 893 | .weui-cells_in-small-appmsg:before { 894 | display: none; 895 | } 896 | .weui-progress { 897 | display: -webkit-box; 898 | display: -webkit-flex; 899 | display: flex; 900 | -webkit-box-align: center; 901 | -webkit-align-items: center; 902 | align-items: center; 903 | } 904 | .weui-progress__bar { 905 | -webkit-box-flex: 1; 906 | -webkit-flex: 1; 907 | flex: 1; 908 | } 909 | .weui-progress__opr { 910 | margin-left: 15px; 911 | font-size: 0; 912 | } 913 | .weui-navbar { 914 | display: -webkit-box; 915 | display: -webkit-flex; 916 | display: flex; 917 | position: absolute; 918 | z-index: 500; 919 | top: 0; 920 | width: 100%; 921 | border-bottom: 1rpx solid #CCCCCC; 922 | } 923 | .weui-navbar__item { 924 | position: relative; 925 | display: block; 926 | -webkit-box-flex: 1; 927 | -webkit-flex: 1; 928 | flex: 1; 929 | padding: 13px 0; 930 | text-align: center; 931 | font-size: 0; 932 | } 933 | .weui-navbar__item.weui-bar__item_on { 934 | color: #1AAD19; 935 | } 936 | .weui-navbar__slider { 937 | position: absolute; 938 | content: " "; 939 | left: 0; 940 | bottom: 0; 941 | width: 6em; 942 | height: 3px; 943 | background-color: #1AAD19; 944 | -webkit-transition: -webkit-transform .3s; 945 | transition: -webkit-transform .3s; 946 | transition: transform .3s; 947 | transition: transform .3s, -webkit-transform .3s; 948 | } 949 | .weui-navbar__title { 950 | display: inline-block; 951 | font-size: 15px; 952 | max-width: 8em; 953 | width: auto; 954 | overflow: hidden; 955 | text-overflow: ellipsis; 956 | white-space: nowrap; 957 | word-wrap: normal; 958 | } 959 | .weui-tab { 960 | position: relative; 961 | height: 100%; 962 | } 963 | .weui-tab__panel { 964 | box-sizing: border-box; 965 | height: 100%; 966 | padding-top: 50px; 967 | overflow: auto; 968 | -webkit-overflow-scrolling: touch; 969 | } 970 | .weui-search-bar { 971 | position: relative; 972 | padding: 8px 10px; 973 | display: -webkit-box; 974 | display: -webkit-flex; 975 | display: flex; 976 | box-sizing: border-box; 977 | background-color: #EFEFF4; 978 | border-top: 1rpx solid #D7D6DC; 979 | border-bottom: 1rpx solid #D7D6DC; 980 | } 981 | .weui-icon-search { 982 | margin-right: 8px; 983 | font-size: inherit; 984 | } 985 | .weui-icon-search_in-box { 986 | position: absolute; 987 | left: 10px; 988 | top: 7px; 989 | } 990 | .weui-search-bar__text { 991 | display: inline-block; 992 | font-size: 14px; 993 | vertical-align: middle; 994 | } 995 | .weui-search-bar__form { 996 | position: relative; 997 | -webkit-box-flex: 1; 998 | -webkit-flex: auto; 999 | flex: auto; 1000 | border-radius: 5px; 1001 | background: #FFFFFF; 1002 | border: 1rpx solid #E6E6EA; 1003 | } 1004 | .weui-search-bar__box { 1005 | position: relative; 1006 | padding-left: 30px; 1007 | padding-right: 30px; 1008 | width: 100%; 1009 | box-sizing: border-box; 1010 | z-index: 1; 1011 | } 1012 | .weui-search-bar__input { 1013 | height: 28px; 1014 | line-height: 28px; 1015 | font-size: 14px; 1016 | } 1017 | .weui-icon-clear { 1018 | position: absolute; 1019 | top: 0; 1020 | right: 0; 1021 | padding: 7px 8px; 1022 | font-size: 0; 1023 | } 1024 | .weui-search-bar__label { 1025 | position: absolute; 1026 | top: 0; 1027 | right: 0; 1028 | bottom: 0; 1029 | left: 0; 1030 | z-index: 2; 1031 | border-radius: 3px; 1032 | text-align: center; 1033 | color: #9B9B9B; 1034 | background: #FFFFFF; 1035 | line-height: 28px; 1036 | } 1037 | .weui-search-bar__cancel-btn { 1038 | margin-left: 10px; 1039 | line-height: 28px; 1040 | color: #09BB07; 1041 | white-space: nowrap; 1042 | } 1043 | -------------------------------------------------------------------------------- /miniprogram/pages/getface/getface.js: -------------------------------------------------------------------------------- 1 | //index.js 2 | //获取应用实例 3 | const app = getApp() 4 | 5 | Page({ 6 | data:{ 7 | taken:0, 8 | debuginfo:'debugmode', 9 | }, 10 | onLoad:function(){ 11 | this.setData({debuginfo:getApp().globalData.coughtoken}); 12 | }, 13 | takePhoto:function() { 14 | var app = getApp(); 15 | var imgrt=app.globalData.imgrt; 16 | this.setData({taken:1}); 17 | var that=this; 18 | const ctx = wx.createCameraContext(); 19 | ctx.takePhoto({ 20 | quality: 'high', 21 | success: (res) => { 22 | console.log('temp photo path:',res.tempImagePath); 23 | getApp().globalData.imgrt=res.tempImagePath; 24 | wx.saveFile({ 25 | tempFilePath: res.tempImagePath, 26 | success (res) { 27 | console.log('------img save success:',res); 28 | console.log('----imgpath:',res.savedFilePath); 29 | getApp().globalData.imgrt = res.savedFilePath; 30 | }, 31 | fail (res){ 32 | console.log('-----img save file failed:',res); 33 | } 34 | }) 35 | /* 36 | //插入上传代码段 37 | wx.saveFile({ 38 | tempFilePath:res.tempImagePath, 39 | success (res) { 40 | getApp().globalData.imgrt = res.savedFilePath 41 | } 42 | })*/ 43 | } 44 | }) 45 | }, 46 | skipit:function(){ 47 | var app = getApp(); 48 | var imgrt=app.globalData.imgrt; 49 | wx.navigateTo({url: '/pages/returnresult/returnresult'}); 50 | }, 51 | jumptorecord: function(){ 52 | var app = getApp(); 53 | var that=this; 54 | var imgrt=getApp().globalData.imgrt; 55 | var coughtoken=getApp().globalData.coughtoken; 56 | wx.showLoading({title: '上传中...',}); 57 | wx.uploadFile({ 58 | url: getApp().globalData.imgurl, 59 | filePath: 'recordings/timg.jpg', 60 | //filePath: getApp().globalData.imgrt, 61 | name: "figure", //name should be the file key in formData, 62 | header: { 63 | coughtoken:coughtoken 64 | }, 65 | method: 'POST', 66 | timeout:"1000", 67 | formData: { 68 | }, 69 | success: res => { 70 | console.log('img upload success:',res); 71 | wx.hideLoading(); 72 | var data = res.data 73 | getApp().globalData.username=res.data; 74 | console.log(data) 75 | //do something 76 | that.setData({debuginfo:JSON.stringify(res.data)}); 77 | wx.navigateTo({url: '/pages/returnresult/returnresult'}); 78 | }, 79 | fail: err => { 80 | console.log('img upload error:',err); 81 | console.log('imgrt',getApp().globalData.imgrt); 82 | that.setData({debuginfo:err}); 83 | wx.hideLoading(); 84 | wx.showToast({ 85 | title: '请求超时', 86 | icon: 'loading', 87 | durantion:"5000" 88 | }) 89 | } 90 | }); 91 | }, 92 | }) 93 | -------------------------------------------------------------------------------- /miniprogram/pages/getface/getface.json: -------------------------------------------------------------------------------- 1 | { 2 | "usingComponents": {} 3 | } -------------------------------------------------------------------------------- /miniprogram/pages/getface/getface.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{debuginfo}} 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | \n\n拍照预览 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /miniprogram/pages/getface/getface.wxss: -------------------------------------------------------------------------------- 1 | /* pages/getface/getface.wxss */ -------------------------------------------------------------------------------- /miniprogram/pages/identity/identity.js: -------------------------------------------------------------------------------- 1 | Page({ 2 | data: { 3 | focus: false, 4 | name: '', 5 | id: '', 6 | debuginfo:'debugmode' 7 | }, 8 | bindKeyInput1: function (e) { 9 | this.setData({ 10 | name: e.detail.value 11 | }) 12 | }, 13 | bindKeyInput2: function (e) { 14 | this.setData({ 15 | id: e.detail.value 16 | }) 17 | }, 18 | bindHideKeyboard: function (e) { 19 | if (e.detail.value === '123') { 20 | // 收起键盘 21 | wx.hideKeyboard() 22 | } 23 | }, 24 | jumptogetface: function(){ 25 | wx.navigateTo({url: '/pages/record/record'}); 26 | }, 27 | 28 | data: { 29 | focus: false, 30 | userInfo: {}, 31 | hasUserInfo: false, 32 | canIUse: wx.canIUse('button.open-type.getUserInfo'), 33 | inputValue:'' 34 | }, 35 | //事件处理函数 36 | bindKeyInput: function (e) { 37 | this.setData({ 38 | inputValue: e.detail.value 39 | }) 40 | }, 41 | bindViewTap: function() { 42 | wx.navigateTo({ 43 | url: '../logs/logs' 44 | }) 45 | }, 46 | onLoad: function () { 47 | if (app.globalData.userInfo) { 48 | this.setData({ 49 | userInfo: app.globalData.userInfo, 50 | hasUserInfo: true 51 | }) 52 | } else if (this.data.canIUse){ 53 | // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 54 | // 所以此处加入 callback 以防止这种情况 55 | app.userInfoReadyCallback = res => { 56 | this.setData({ 57 | userInfo: res.userInfo, 58 | hasUserInfo: true 59 | }) 60 | } 61 | } else { 62 | // 在没有 open-type=getUserInfo 版本的兼容处理 63 | wx.getUserInfo({ 64 | success: res => { 65 | app.globalData.userInfo = res.userInfo 66 | this.setData({ 67 | userInfo: res.userInfo, 68 | hasUserInfo: true 69 | }) 70 | } 71 | }) 72 | } 73 | }, 74 | getUserInfo: function(e) { 75 | console.log(e) 76 | app.globalData.userInfo = e.detail.userInfo 77 | this.setData({ 78 | userInfo: e.detail.userInfo, 79 | hasUserInfo: true 80 | }) 81 | }, 82 | 83 | 84 | }) -------------------------------------------------------------------------------- /miniprogram/pages/identity/identity.json: -------------------------------------------------------------------------------- 1 | { 2 | "usingComponents": {} 3 | } -------------------------------------------------------------------------------- /miniprogram/pages/identity/identity.wxml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 姓名{{inputValue}} 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 身份证号 23 | 24 | 25 | 26 | 27 | 28 | 29 | {{name}} 30 | {{id}} 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /miniprogram/pages/identity/identity.wxss: -------------------------------------------------------------------------------- 1 | @import "/lib/weui.wxss"; 2 | 3 | .page-section{ 4 | margin-bottom: 20rpx; 5 | } 6 | -------------------------------------------------------------------------------- /miniprogram/pages/index/index.js: -------------------------------------------------------------------------------- 1 | //index.js 2 | //获取应用实例 3 | const app = getApp() 4 | 5 | Page({ 6 | data: { 7 | motto: 'funk', 8 | focus: false, 9 | userInfo: {}, 10 | hasUserInfo: false, 11 | canIUse: wx.canIUse('button.open-type.getUserInfo'), 12 | inputValue:'' 13 | }, 14 | //事件处理函数 15 | bindKeyInput: function (e) { 16 | this.setData({ 17 | inputValue: e.detail.value 18 | }) 19 | }, 20 | bindViewTap: function() { 21 | wx.navigateTo({ 22 | url: '../logs/logs' 23 | }) 24 | }, 25 | onLoad: function () { 26 | if (app.globalData.userInfo) { 27 | this.setData({ 28 | userInfo: app.globalData.userInfo, 29 | hasUserInfo: true 30 | }) 31 | } else if (this.data.canIUse){ 32 | // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 33 | // 所以此处加入 callback 以防止这种情况 34 | app.userInfoReadyCallback = res => { 35 | this.setData({ 36 | userInfo: res.userInfo, 37 | hasUserInfo: true 38 | }) 39 | } 40 | } else { 41 | // 在没有 open-type=getUserInfo 版本的兼容处理 42 | wx.getUserInfo({ 43 | success: res => { 44 | app.globalData.userInfo = res.userInfo 45 | this.setData({ 46 | userInfo: res.userInfo, 47 | hasUserInfo: true 48 | }) 49 | } 50 | }) 51 | } 52 | }, 53 | getUserInfo: function(e) { 54 | console.log(e) 55 | app.globalData.userInfo = e.detail.userInfo 56 | this.setData({ 57 | userInfo: e.detail.userInfo, 58 | hasUserInfo: true 59 | }) 60 | } 61 | }) 62 | -------------------------------------------------------------------------------- /miniprogram/pages/index/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "usingComponents": {} 3 | } -------------------------------------------------------------------------------- /miniprogram/pages/index/index.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 23 | 24 | 25 | 可以自动聚焦的input 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /miniprogram/pages/index/index.wxss: -------------------------------------------------------------------------------- 1 | /**index.wxss**/ 2 | .userinfo { 3 | display: flex; 4 | flex-direction: column; 5 | align-items: center; 6 | } 7 | 8 | .userinfo-avatar { 9 | width: 128rpx; 10 | height: 128rpx; 11 | margin: 20rpx; 12 | border-radius: 50%; 13 | } 14 | 15 | .userinfo-nickname { 16 | color: #aaa; 17 | } 18 | 19 | .usermotto { 20 | margin-top: 200px; 21 | } -------------------------------------------------------------------------------- /miniprogram/pages/logs/logs.js: -------------------------------------------------------------------------------- 1 | //logs.js 2 | const util = require('../../utils/util.js') 3 | 4 | Page({ 5 | data: { 6 | logs: [] 7 | }, 8 | onLoad: function () { 9 | this.setData({ 10 | logs: (wx.getStorageSync('logs') || []).map(log => { 11 | return util.formatTime(new Date(log)) 12 | }) 13 | }) 14 | } 15 | }) 16 | -------------------------------------------------------------------------------- /miniprogram/pages/logs/logs.json: -------------------------------------------------------------------------------- 1 | { 2 | "navigationBarTitleText": "查看启动日志", 3 | "usingComponents": {} 4 | } -------------------------------------------------------------------------------- /miniprogram/pages/logs/logs.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{index + 1}}. {{log}} 5 | 6 | 7 | -------------------------------------------------------------------------------- /miniprogram/pages/logs/logs.wxss: -------------------------------------------------------------------------------- 1 | .log-list { 2 | display: flex; 3 | flex-direction: column; 4 | padding: 40rpx; 5 | } 6 | .log-item { 7 | margin: 10rpx; 8 | } 9 | -------------------------------------------------------------------------------- /miniprogram/pages/record/record.js: -------------------------------------------------------------------------------- 1 | Page({ 2 | /** 3 | * 页面的初始数据 4 | */ 5 | data: { 6 | wrec:0, 7 | auth:0, 8 | itfirst:1, 9 | debuginfo:'debugmode' 10 | }, 11 | startit: function (){ 12 | var app = getApp(); 13 | var recrt=app.globalData.recrt; 14 | wx.createAudioContext('mplayer'); 15 | this.setData({itfirst:0}); 16 | this.setData({wrec:1}); 17 | var that=this; 18 | const options = { 19 | duration: 100000,//指定录音的时长,单位 ms 20 | sampleRate: 16000,//采样率 21 | numberOfChannels: 1,//录音通道数 22 | encodeBitRate: 96000,//编码码率 23 | format: 'mp3',//音频格式,有效值 aac/mp3 24 | frameSize: 50,//指定帧大小,单位 KB 25 | } 26 | wx.authorize({ 27 | scope: 'scope.record', 28 | success(){ 29 | that.setData({auth:1}); 30 | } 31 | }); 32 | 33 | setTimeout(function () { 34 | wx.getRecorderManager().start(options); 35 | wx.getRecorderManager().onStart(() => { 36 | console.log('recorder start') 37 | }); 38 | wx.getRecorderManager().onError((res) => { 39 | console.log('start-record error'); 40 | console.log(res); 41 | }, 1000); 42 | }) 43 | }, 44 | pauseit: function (){ 45 | var app = getApp(); 46 | var recrt=app.globalData.recrt; 47 | 48 | this.setData({wrec:0}); 49 | wx.getRecorderManager().stop(); 50 | wx.getRecorderManager().onStop( 51 | (res) => { 52 | this.tempFilePath = res.tempFilePath; 53 | console.log('停止录音', res.tempFilePath); 54 | console.log('msg:',res); 55 | console.log('temprecordpath',res.tempFilePath); 56 | getApp().globalData.recrt=res.tempFilePath; 57 | setTimeout(function () { 58 | wx.saveFile({ 59 | tempFilePath: res.tempFilePath, 60 | success (res) { 61 | getApp().globalData.recrt = res.savedFilePath 62 | } 63 | }) 64 | }, 1000); 65 | console.log('savedrecordpath',getApp().globalData.recrt); 66 | } 67 | ); 68 | wx.getRecorderManager().onError((res) => { 69 | console.log('stop-record error'); 70 | console.log(res); 71 | }) 72 | 73 | }, 74 | playit : function(){ 75 | var app = getApp(); 76 | var recrt=app.globalData.recrt; 77 | 78 | this.audioCtx = wx.createAudioContext('myAudio',recrt); 79 | this.audioCtx.play(); 80 | }, 81 | submitit:function(){ 82 | var that=this; 83 | var app = getApp(); 84 | var recrt=app.globalData.recrt; 85 | wx.showLoading({title: '上传中...',}); 86 | wx.uploadFile({ 87 | url: getApp().globalData.recurl, 88 | //filePath: getApp().globalData.recrt, 89 | filePath: '/recordings/long_cough.mp3', 90 | name: "cough", //name should be the file key in formData, 91 | method: 'POST', 92 | timeout:"1000", 93 | formData: { 94 | }, 95 | success: ret => { 96 | wx.hideLoading(); 97 | var data = ret.data; 98 | console.log('recording upload success') 99 | console.log('return header',ret.header); 100 | console.log('return data',ret.data); 101 | var coughheader = ret.header; 102 | getApp().globalData.coughtoken=ret.header.coughtoken; 103 | if(getApp().globalData.coughtoken==null){ 104 | that.setData({debuginfo:"not coughing correctly"}); 105 | wx.navigateTo({url: '/pages/rerecord/rerecord'}); 106 | return; 107 | } 108 | getApp().globalData.covidrate=ret.data; 109 | console.log('$$$$$$$$your rate is :',getApp().globalData.covidrate); 110 | that.setData({debuginfo:JSON.stringify(getApp().globalData.coughtoken)}); 111 | //do something 112 | wx.navigateTo({url: '/pages/getface/getface'}); 113 | }, 114 | fail: err => { 115 | console.log('erroring recording, err=',err,'recrt=',getApp().globalData.recrt); 116 | this.setData({debuginfo:JSON.stringify(getApp().globalData.recrt)}); 117 | wx.hideLoading(); 118 | wx.showLoading({ 119 | title: '请求超时', 120 | duration: 5000 121 | }) 122 | } 123 | }); 124 | //wx.navigateTo({url: '/pages/getface/getface'}); 125 | }, 126 | 127 | 128 | /** 129 | * 生命周期函数--监听页面加载 130 | */ 131 | onLoad: function (options) { 132 | }, 133 | 134 | /** 135 | * 生命周期函数--监听页面初次渲染完成 136 | */ 137 | onReady: function () { 138 | 139 | }, 140 | /** 141 | * 生命周期函数--监听页面显示 142 | */ 143 | onShow: function () { 144 | 145 | }, 146 | 147 | /** 148 | * 生命周期函数--监听页面隐藏 149 | */ 150 | onHide: function () { 151 | 152 | }, 153 | 154 | /** 155 | * 生命周期函数--监听页面卸载 156 | */ 157 | onUnload: function () { 158 | 159 | }, 160 | 161 | /** 162 | * 页面相关事件处理函数--监听用户下拉动作 163 | */ 164 | onPullDownRefresh: function () { 165 | 166 | }, 167 | 168 | /** 169 | * 页面上拉触底事件的处理函数 170 | */ 171 | onReachBottom: function () { 172 | 173 | }, 174 | 175 | /** 176 | * 用户点击右上角分享 177 | */ 178 | onShareAppMessage: function () { 179 | 180 | } 181 | }) -------------------------------------------------------------------------------- /miniprogram/pages/record/record.json: -------------------------------------------------------------------------------- 1 | { 2 | "usingComponents": {} 3 | } -------------------------------------------------------------------------------- /miniprogram/pages/record/record.wxml: -------------------------------------------------------------------------------- 1 | 2 | \n 3 | 4 | 5 | 录制一段10s左右的咳嗽声音 6 | 7 | 8 | 9 | {{debuginfo}} 10 | 11 | 12 | 13 | 14 | \n\n请开始录音\n\n\n\n 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | \n\n正在录音\n\n\n\n 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /miniprogram/pages/record/record.wxss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SegmentationFaultTeam/CovidCoughDetector/170e174d9e26d08ff07f749a3193cebd458b670c/miniprogram/pages/record/record.wxss -------------------------------------------------------------------------------- /miniprogram/pages/rerecord/rerecord.js: -------------------------------------------------------------------------------- 1 | Page({ 2 | /** 3 | * 页面的初始数据 4 | */ 5 | data: { 6 | wrec:0, 7 | auth:0, 8 | itfirst:1, 9 | debuginfo:'debugmode' 10 | }, 11 | startit: function (){ 12 | var app = getApp(); 13 | var recrt=app.globalData.recrt; 14 | wx.createAudioContext('mplayer'); 15 | this.setData({itfirst:0}); 16 | this.setData({wrec:1}); 17 | var that=this; 18 | const options = { 19 | duration: 100000,//指定录音的时长,单位 ms 20 | sampleRate: 16000,//采样率 21 | numberOfChannels: 1,//录音通道数 22 | encodeBitRate: 96000,//编码码率 23 | format: 'mp3',//音频格式,有效值 aac/mp3 24 | frameSize: 50,//指定帧大小,单位 KB 25 | } 26 | wx.authorize({ 27 | scope: 'scope.record', 28 | success(){ 29 | that.setData({auth:1}); 30 | } 31 | }); 32 | wx.getRecorderManager().start(options); 33 | wx.getRecorderManager().onStart(() => { 34 | console.log('recorder start') 35 | }); 36 | /* 37 | wx.getRecorderManager().onError((res) => { 38 | console.log(res); 39 | }) 40 | */ 41 | }, 42 | pauseit: function (){ 43 | var app = getApp(); 44 | var recrt=app.globalData.recrt; 45 | 46 | this.setData({wrec:0}); 47 | wx.getRecorderManager().stop(); 48 | wx.getRecorderManager().onStop((res) => { 49 | this.tempFilePath = res.tempFilePath; 50 | console.log('停止录音', res.tempFilePath); 51 | console.log('temprecordpath',res.tempFilePath); 52 | getApp().globalData.recrt=res.tempFilePath; 53 | wx.saveFile({ 54 | tempFilePath: res.tempFilePath, 55 | success (res) { 56 | getApp().globalData.recrt = res.savedFilePath 57 | } 58 | }) 59 | console.log('savedrecordpath',getApp().globalData.recrt); 60 | }) 61 | }, 62 | playit : function(){ 63 | var app = getApp(); 64 | var recrt=app.globalData.recrt; 65 | 66 | this.audioCtx = wx.createAudioContext('myAudio',recrt); 67 | this.audioCtx.play(); 68 | }, 69 | submitit:function(){ 70 | var that=this; 71 | var app = getApp(); 72 | var recrt=app.globalData.recrt; 73 | wx.showLoading({title: '上传中...',}); 74 | wx.uploadFile({ 75 | url: getApp().globalData.recurl, 76 | filePath: getApp().globalData.recrt, 77 | //filePath: '/recordings/long_cough.mp3', 78 | name: "cough", //name should be the file key in formData, 79 | method: 'POST', 80 | timeout:"1000", 81 | formData: { 82 | }, 83 | success: ret => { 84 | wx.hideLoading(); 85 | var data = ret.data; 86 | console.log('recording upload success') 87 | console.log('return header',ret.header); 88 | console.log('return data',ret.data); 89 | var coughheader = ret.header; 90 | getApp().globalData.coughtoken=ret.header.coughtoken; 91 | if(getApp().globalData.coughtoken==null){ 92 | that.setData({debuginfo:"not coughing correctly"}); 93 | console.log('no coughtoken'); 94 | wx.navigateTo({url: '/pages/rerecord/rerecord'}); 95 | return; 96 | } 97 | getApp().globalData.covidrate=ret.data; 98 | console.log('$$$$$$$$your rate is :',getApp().globalData.covidrate); 99 | that.setData({debuginfo:JSON.stringify(getApp().globalData.coughtoken)}); 100 | //do something 101 | wx.navigateTo({url: '/pages/getface/getface'}); 102 | }, 103 | fail: err => { 104 | console.log('erroring recording, err=',err,'recrt=',getApp().globalData.recrt); 105 | this.setData({debuginfo:JSON.stringify(getApp().globalData.recrt)}); 106 | wx.hideLoading(); 107 | wx.showLoading({ 108 | title: '请求超时', 109 | duration: 5000 110 | }) 111 | } 112 | }); 113 | //wx.navigateTo({url: '/pages/getface/getface'}); 114 | }, 115 | 116 | 117 | /** 118 | * 生命周期函数--监听页面加载 119 | */ 120 | onLoad: function (options) { 121 | }, 122 | 123 | /** 124 | * 生命周期函数--监听页面初次渲染完成 125 | */ 126 | onReady: function () { 127 | 128 | }, 129 | /** 130 | * 生命周期函数--监听页面显示 131 | */ 132 | onShow: function () { 133 | 134 | }, 135 | 136 | /** 137 | * 生命周期函数--监听页面隐藏 138 | */ 139 | onHide: function () { 140 | 141 | }, 142 | 143 | /** 144 | * 生命周期函数--监听页面卸载 145 | */ 146 | onUnload: function () { 147 | 148 | }, 149 | 150 | /** 151 | * 页面相关事件处理函数--监听用户下拉动作 152 | */ 153 | onPullDownRefresh: function () { 154 | 155 | }, 156 | 157 | /** 158 | * 页面上拉触底事件的处理函数 159 | */ 160 | onReachBottom: function () { 161 | 162 | }, 163 | 164 | /** 165 | * 用户点击右上角分享 166 | */ 167 | onShareAppMessage: function () { 168 | 169 | } 170 | }) -------------------------------------------------------------------------------- /miniprogram/pages/rerecord/rerecord.json: -------------------------------------------------------------------------------- 1 | { 2 | "usingComponents": {} 3 | } -------------------------------------------------------------------------------- /miniprogram/pages/rerecord/rerecord.wxml: -------------------------------------------------------------------------------- 1 | 2 | \n 3 | 4 | 5 | 录制一段10s左右的咳嗽声音 6 | 7 | 8 | 9 | {{debuginfo}} 10 | 11 | 12 | \n 13 | 14 | 15 | \n 16 | 请咳嗽地更强烈、咳嗽时间长一些 17 | 18 | 19 | 这有助于程序得出更精确的数据 20 | 21 | 22 | 23 | 24 | \n\n请开始录音\n\n\n\n 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | \n\n正在录音\n\n\n\n 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /miniprogram/pages/rerecord/rerecord.wxss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SegmentationFaultTeam/CovidCoughDetector/170e174d9e26d08ff07f749a3193cebd458b670c/miniprogram/pages/rerecord/rerecord.wxss -------------------------------------------------------------------------------- /miniprogram/pages/return/return.js: -------------------------------------------------------------------------------- 1 | // pages/return/return.js 2 | Page({ 3 | 4 | /** 5 | * 页面的初始数据 6 | */ 7 | data: { 8 | rem:'defaulty', 9 | s1:'', 10 | s2:'' 11 | }, 12 | 13 | /** 14 | * 生命周期函数--监听页面加载 15 | */ 16 | onLoad: function (options) { 17 | this.setData({s1:getApp().globalData.covidrate}); 18 | this.setData({s2:getApp().globalData.username}); 19 | 20 | var that=this; 21 | wx.request({ 22 | url: 'http://47.102.200.200:80/v1/test', 23 | method:'GET', 24 | data: { 25 | }, 26 | header: { 27 | 'content-type':'x-www-form-urlencoded' 28 | }, 29 | success: function (res) { 30 | console.log(res.data); 31 | //this.rem=console.log(res.data); 32 | that.setData({ rem: res.data }); 33 | }, 34 | fail: function (res){ 35 | console.log(res.data); 36 | //this.rem = "数据获取失败"; 37 | that.setData({ rem: "fault" }); 38 | } 39 | }) 40 | }, 41 | 42 | /** 43 | * 生命周期函数--监听页面初次渲染完成 44 | */ 45 | onReady: function () { 46 | 47 | }, 48 | 49 | /** 50 | * 生命周期函数--监听页面显示 51 | */ 52 | onShow: function () { 53 | 54 | }, 55 | 56 | /** 57 | * 生命周期函数--监听页面隐藏 58 | */ 59 | onHide: function () { 60 | 61 | }, 62 | 63 | /** 64 | * 生命周期函数--监听页面卸载 65 | */ 66 | onUnload: function () { 67 | 68 | }, 69 | 70 | /** 71 | * 页面相关事件处理函数--监听用户下拉动作 72 | */ 73 | onPullDownRefresh: function () { 74 | 75 | }, 76 | 77 | /** 78 | * 页面上拉触底事件的处理函数 79 | */ 80 | onReachBottom: function () { 81 | 82 | }, 83 | getreturn: function (){ 84 | this.setData({ 85 | returnmessage:wx.request({url: '47.102.200.200:80/v1/test'}) 86 | }) 87 | 88 | } 89 | }) -------------------------------------------------------------------------------- /miniprogram/pages/return/return.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Your Result 4 | 5 | 6 | {{s1}} 7 | 8 | 9 | 10 | {{s2}} 11 | 12 | 13 | -------------------------------------------------------------------------------- /miniprogram/pages/return/return.wxss: -------------------------------------------------------------------------------- 1 | /* pages/return/return.wxss */ -------------------------------------------------------------------------------- /miniprogram/pages/returnresult/resultimage/art1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SegmentationFaultTeam/CovidCoughDetector/170e174d9e26d08ff07f749a3193cebd458b670c/miniprogram/pages/returnresult/resultimage/art1.jpeg -------------------------------------------------------------------------------- /miniprogram/pages/returnresult/resultimage/art2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SegmentationFaultTeam/CovidCoughDetector/170e174d9e26d08ff07f749a3193cebd458b670c/miniprogram/pages/returnresult/resultimage/art2.jpg -------------------------------------------------------------------------------- /miniprogram/pages/returnresult/resultimage/art3.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SegmentationFaultTeam/CovidCoughDetector/170e174d9e26d08ff07f749a3193cebd458b670c/miniprogram/pages/returnresult/resultimage/art3.jpeg -------------------------------------------------------------------------------- /miniprogram/pages/returnresult/resultimage/art4.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SegmentationFaultTeam/CovidCoughDetector/170e174d9e26d08ff07f749a3193cebd458b670c/miniprogram/pages/returnresult/resultimage/art4.jpeg -------------------------------------------------------------------------------- /miniprogram/pages/returnresult/resultimage/timg.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SegmentationFaultTeam/CovidCoughDetector/170e174d9e26d08ff07f749a3193cebd458b670c/miniprogram/pages/returnresult/resultimage/timg.jpeg -------------------------------------------------------------------------------- /miniprogram/pages/returnresult/returnresult.js: -------------------------------------------------------------------------------- 1 | // pages/returnresult/returnresult.js 2 | const app = getApp() 3 | Page({ 4 | data: { 5 | motto: '您的新冠阳性概率为', 6 | userInfo: {}, 7 | hasUserInfo: false, 8 | canIUse: wx.canIUse('button.open-type.getUserInfo'), 9 | answer:'testing', 10 | winWidth: 0, 11 | winHeight: 0, 12 | // tab切换 13 | currentTab: 0, 14 | s1:'新冠概率获取失败', 15 | s2:'您照片身份信息获取失败' 16 | }, 17 | //事件处理函数 18 | onReady:function(){ 19 | console.log('onloadcovidrate',getApp().globalData.covidrate); 20 | this.setData({s1:JSON.parse( getApp().globalData.covidrate.replace(/'/g,'\"') ).rate}); 21 | this.setData({s2:JSON.parse( getApp().globalData.username.replace(/'/g,'\"') ).name}); 22 | }, 23 | bindViewTap: function() { 24 | wx.navigateTo({ 25 | url: '../logs/logs' 26 | }) 27 | }, 28 | onLoad: function () { 29 | if (app.globalData.userInfo) { 30 | this.setData({ 31 | userInfo: app.globalData.userInfo, 32 | hasUserInfo: true 33 | }) 34 | } else if (this.data.canIUse){ 35 | // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 36 | // 所以此处加入 callback 以防止这种情况 37 | app.userInfoReadyCallback = res => { 38 | this.setData({ 39 | userInfo: res.userInfo, 40 | hasUserInfo: true 41 | }) 42 | } 43 | } else { 44 | // 在没有 open-type=getUserInfo 版本的兼容处理 45 | wx.getUserInfo({ 46 | success: res => { 47 | app.globalData.userInfo = res.userInfo 48 | this.setData({ 49 | userInfo: res.userInfo, 50 | hasUserInfo: true 51 | }) 52 | } 53 | }) 54 | } 55 | }, 56 | getUserInfo: function(e) { 57 | console.log(e) 58 | app.globalData.userInfo = e.detail.userInfo 59 | this.setData({ 60 | userInfo: e.detail.userInfo, 61 | hasUserInfo: true 62 | }) 63 | }, 64 | 65 | 66 | 67 | onLoad: function() { 68 | var that = this; 69 | /** 70 | * 获取系统信息 71 | */ 72 | wx.getSystemInfo( { 73 | 74 | success: function( res ) { 75 | that.setData( { 76 | winWidth: res.windowWidth, 77 | winHeight: res.windowHeight 78 | }); 79 | } 80 | 81 | }); 82 | }, 83 | /** 84 | * 滑动切换tab 85 | */ 86 | bindChange: function( e ) { 87 | var that = this; 88 | that.setData( { currentTab: e.detail.current }); 89 | }, 90 | /** 91 | * 点击tab切换 92 | */ 93 | swichNav:function( e ) { 94 | var that = this; 95 | if( this.data.currentTab === e.target.dataset.current ) { 96 | return false; 97 | } else { 98 | that.setData( { 99 | currentTab: e.target.dataset.current 100 | }) 101 | } 102 | } 103 | 104 | }) 105 | -------------------------------------------------------------------------------- /miniprogram/pages/returnresult/returnresult.json: -------------------------------------------------------------------------------- 1 | { 2 | "usingComponents": {} 3 | 4 | } 5 | -------------------------------------------------------------------------------- /miniprogram/pages/returnresult/returnresult.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 检测结果 5 | 防疫贴士 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | {{userInfo.nickName}} 16 | 17 | 18 | 19 | 您好,{{s2}} 20 | 21 | 22 | {{motto}}:{{s1}} 23 | 24 | 25 | 26 | 27 | 28 | 29 | 出门前 30 | 31 | 开窗通风30分钟,量体温评估身体状况,不带病上班 32 | 33 | 34 | 35 | 乘电梯 36 | 37 | 务必佩戴口罩,接触按钮时可用纸巾隔开 38 | 尽量不在电梯内交流,不扎堆乘坐电梯 39 | 40 | 41 | 42 | 上下班 43 | 44 | 尽量选择步行、骑行或开私家车,乘坐公共交通时,应与他人保持距离,尽量避免用手触摸车上设施 45 | 46 | 47 | 48 | 办公时 49 | 50 | 接触公用物品或传阅纸质文件前后需洗手 51 | 保持环境卫生清洁,重视手机、鼠标、键盘、文具等物品的消毒 52 | 53 | 54 | 55 | 就餐时 56 | 57 | 选择单人单餐、单桌或隔离就坐,外卖尽量无接触拿取 58 | 59 | 60 | 61 | 采购时 62 | 63 | 快速挑选,尽量一次性购买齐全,减少出门购物频次 64 | 自备购物袋,尽量减少与公共设施的接触 65 | 不采买来源不明的禽类,更不要吃野味 66 | 结账时不要拥挤,排队过程中和他人保持一定距离 67 | 68 | 69 | 70 | 回家后 71 | 72 | 手不要碰口罩外侧,将其外折扎紧,装袋密封丢弃 73 | 使用流动清水认真洗手,并注意水龙头清洁 74 | 75 | 76 | 77 | 做饭时 78 | 79 | 尽量吃新鲜食材,不要放置太久 80 | 肉类蛋类彻底煮熟后食用 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /miniprogram/pages/returnresult/returnresult.wxss: -------------------------------------------------------------------------------- 1 | /* pages/returnresult/returnresult.wxss */ 2 | .userinfo { 3 | display: flex; 4 | margin-top: 40px; 5 | flex-direction: column; 6 | align-items: center; 7 | } 8 | 9 | .userinfo-avatar { 10 | width: 128rpx; 11 | height: 128rpx; 12 | margin: 20rpx; 13 | border-radius: 50%; 14 | } 15 | 16 | .userinfo-nickname { 17 | color: #aaa; 18 | } 19 | 20 | .usermotto { 21 | display:flex; 22 | justify-content:center; 23 | margin-top: 65px; 24 | color:black; 25 | font-size:20px; 26 | font-weight:bold; 27 | font-family:微软雅黑; 28 | } 29 | 30 | .data0{ 31 | display:flex; 32 | justify-content:center; 33 | margin-top: 40px; 34 | color:black; 35 | font-size:15px; 36 | font-weight:bold; 37 | font-family:微软雅黑; 38 | } 39 | 40 | .swiper-tab{ 41 | width: 100%; 42 | border-bottom: 2rpx solid #777777; 43 | text-align: center; 44 | line-height: 80rpx;} 45 | .swiper-tab-list{ font-size: 30rpx; 46 | display: inline-block; 47 | width: 33.33%; 48 | color: #777777; 49 | } 50 | .on{ color: #da7c0c; 51 | border-bottom: 5rpx solid #da7c0c;} 52 | 53 | .swiper-box{ display: block; height: 100%; width: 100%; overflow: hidden; } 54 | .swiper-box view{ 55 | text-align: center; 56 | } 57 | 58 | .artImg { 59 | width: 30%; 60 | } 61 | 62 | .art { 63 | width: 70%; 64 | } 65 | 66 | .artImg image { 67 | width: 100%; 68 | height: 150rpx; 69 | } 70 | 71 | .content { 72 | width: 100%; 73 | display: flex; 74 | flex-wrap: wrap; 75 | } 76 | 77 | .hint{ 78 | margin: 0 auto; 79 | width: 100%; 80 | color:black; 81 | font-size:16px; 82 | font-weight:bold; 83 | font-family:微软雅黑; 84 | border-bottom: 5rpx solid #da7c0c; 85 | } 86 | 87 | .subhint{ 88 | margin: 0 auto; 89 | width: 100%; 90 | color:black; 91 | font-size:13px; 92 | font-weight:bold; 93 | font-family:微软雅黑; 94 | } 95 | 96 | 97 | -------------------------------------------------------------------------------- /miniprogram/pages/welcome/welcome.js: -------------------------------------------------------------------------------- 1 | // pages/welcome/welcome.js 2 | Page({ 3 | jumptotest:function(){ 4 | wx.request({ 5 | url:'https://test.depetrol.com', 6 | method:'GET', 7 | success (res){ 8 | console.log('----wx request sucess'); 9 | console.log('return message',res); 10 | }, 11 | fail (err){ 12 | console.log('-----wx request failed'); 13 | console.log('err message',err); 14 | } 15 | }); 16 | 17 | }, 18 | /** 19 | * 页面的初始数据 20 | */ 21 | data: { 22 | 23 | }, 24 | 25 | /** 26 | * 生命周期函数--监听页面加载 27 | */ 28 | onLoad: function (options) { 29 | 30 | }, 31 | 32 | /** 33 | * 生命周期函数--监听页面初次渲染完成 34 | */ 35 | onReady: function () { 36 | 37 | }, 38 | jumptoidentity: function(){ 39 | wx.navigateTo({url: '/pages/record/record'}); 40 | }, 41 | /** 42 | * 生命周期函数--监听页面显示 43 | */ 44 | onShow: function () { 45 | 46 | }, 47 | 48 | /** 49 | * 生命周期函数--监听页面隐藏 50 | */ 51 | onHide: function () { 52 | 53 | }, 54 | 55 | /** 56 | * 生命周期函数--监听页面卸载 57 | */ 58 | onUnload: function () { 59 | 60 | }, 61 | 62 | /** 63 | * 页面相关事件处理函数--监听用户下拉动作 64 | */ 65 | onPullDownRefresh: function () { 66 | 67 | }, 68 | 69 | /** 70 | * 页面上拉触底事件的处理函数 71 | */ 72 | onReachBottom: function () { 73 | 74 | }, 75 | 76 | /** 77 | * 用户点击右上角分享 78 | */ 79 | onShareAppMessage: function () { 80 | 81 | } 82 | }) -------------------------------------------------------------------------------- /miniprogram/pages/welcome/welcome.json: -------------------------------------------------------------------------------- 1 | { 2 | "usingComponents": {} 3 | } -------------------------------------------------------------------------------- /miniprogram/pages/welcome/welcome.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | \n 4 | 5 | 6 |

COVID咳嗽声检测demo

7 |
8 | 9 | 10 | 11 | 12 | 通过机器学习分析一段咳嗽的录音 13 | 14 | 15 | 来判断是否感染新型冠状肺炎 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /miniprogram/pages/welcome/welcome.wxss: -------------------------------------------------------------------------------- 1 | /* pages/welcome/welcome.wxss */ 2 | button{ 3 | margin-top: 30rpx; 4 | margin-bottom: 30rpx; 5 | } 6 | 7 | .title{ 8 | display: flex; 9 | width: 100%; 10 | height: 100%; 11 | align-items: center; 12 | justify-content: center; 13 | text-align: center; 14 | font-weight: 300; 15 | font-size-adjust: 1; 16 | } 17 | .picture{ 18 | display: flex; 19 | width: 100%; 20 | height: 100%; 21 | align-items: center; 22 | justify-content: center; 23 | text-align: center; 24 | font-weight: 300; 25 | font-size-adjust: 1; 26 | } 27 | .mytext{ 28 | display: flex; 29 | width: 100%; 30 | height: 100%; 31 | align-items: center; 32 | justify-content: center; 33 | text-align: center; 34 | font-weight: 300; 35 | } 36 | .button-sp-area{ 37 | margin: 0 auto; 38 | width: 60%; 39 | } -------------------------------------------------------------------------------- /miniprogram/project.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "项目配置文件", 3 | "packOptions": { 4 | "ignore": [] 5 | }, 6 | "setting": { 7 | "urlCheck": false, 8 | "es6": true, 9 | "enhance": false, 10 | "postcss": true, 11 | "preloadBackgroundData": false, 12 | "minified": true, 13 | "newFeature": false, 14 | "coverView": true, 15 | "nodeModules": false, 16 | "autoAudits": false, 17 | "showShadowRootInWxmlPanel": true, 18 | "scopeDataCheck": false, 19 | "uglifyFileName": false, 20 | "checkInvalidKey": true, 21 | "checkSiteMap": true, 22 | "uploadWithSourceMap": true, 23 | "compileHotReLoad": false, 24 | "useMultiFrameRuntime": false, 25 | "useApiHook": true, 26 | "babelSetting": { 27 | "ignore": [], 28 | "disablePlugins": [], 29 | "outputPath": "" 30 | }, 31 | "enableEngineNative": false, 32 | "useIsolateContext": true, 33 | "useCompilerModule": true, 34 | "userConfirmedUseCompilerModuleSwitch": false, 35 | "packNpmManually": false, 36 | "packNpmRelationList": [], 37 | "minifyWXSS": true 38 | }, 39 | "compileType": "miniprogram", 40 | "libVersion": "2.14.0", 41 | "appid": "wx6dcc991a461fe946", 42 | "projectname": "CovidCough", 43 | "debugOptions": { 44 | "hidedInDevtools": [] 45 | }, 46 | "scripts": {}, 47 | "isGameTourist": false, 48 | "simulatorType": "wechat", 49 | "simulatorPluginLibVersion": {}, 50 | "condition": { 51 | "search": { 52 | "list": [] 53 | }, 54 | "conversation": { 55 | "list": [] 56 | }, 57 | "game": { 58 | "list": [] 59 | }, 60 | "plugin": { 61 | "list": [] 62 | }, 63 | "gamePlugin": { 64 | "list": [] 65 | }, 66 | "miniprogram": { 67 | "list": [] 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /miniprogram/recordings/long_cough.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SegmentationFaultTeam/CovidCoughDetector/170e174d9e26d08ff07f749a3193cebd458b670c/miniprogram/recordings/long_cough.mp3 -------------------------------------------------------------------------------- /miniprogram/recordings/timg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SegmentationFaultTeam/CovidCoughDetector/170e174d9e26d08ff07f749a3193cebd458b670c/miniprogram/recordings/timg.jpg -------------------------------------------------------------------------------- /miniprogram/sitemap.json: -------------------------------------------------------------------------------- 1 | { 2 | "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html", 3 | "rules": [{ 4 | "action": "allow", 5 | "page": "*" 6 | }] 7 | } -------------------------------------------------------------------------------- /miniprogram/utils/util.js: -------------------------------------------------------------------------------- 1 | const formatTime = date => { 2 | const year = date.getFullYear() 3 | const month = date.getMonth() + 1 4 | const day = date.getDate() 5 | const hour = date.getHours() 6 | const minute = date.getMinutes() 7 | const second = date.getSeconds() 8 | 9 | return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':') 10 | } 11 | 12 | const formatNumber = n => { 13 | n = n.toString() 14 | return n[1] ? n : '0' + n 15 | } 16 | 17 | module.exports = { 18 | formatTime: formatTime 19 | } 20 | -------------------------------------------------------------------------------- /nginx.conf: -------------------------------------------------------------------------------- 1 | http{ 2 | underscores_in_headers on; 3 | server { 4 | listen 80; 5 | server_name coughchecker; 6 | 7 | location / { 8 | proxy_pass http://host:port; 9 | } 10 | } 11 | } 12 | events { 13 | worker_connections 1024; ## Default: 1024 14 | } 15 | -------------------------------------------------------------------------------- /nginxssl.conf: -------------------------------------------------------------------------------- 1 | http{ 2 | underscores_in_headers on; 3 | server { 4 | listen 443 ssl; 5 | server_name depetrol.top; 6 | 7 | ssl on; 8 | ssl_certificate /etc/nginx/cert/1_www.depetrol.top_bundle.crt; 9 | ssl_certificate_key /etc/nginx/cert/2_www.depetrol.top.key; 10 | ssl_session_cache shared:SSL:10m; 11 | ssl_session_timeout 10m; 12 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 13 | 14 | location / { 15 | proxy_pass http://host:port; 16 | } 17 | } 18 | } 19 | events { 20 | worker_connections 1024; ## Default: 1024 21 | } 22 | --------------------------------------------------------------------------------