import sqlite3 from flask import jsonify, request, g, json, Flask import serial.tools.list_ports from flask_cors import CORS, cross_origin import threading, os, sys, platform import time, datetime # 0--每个方向含 跌落高度 和 跌落周期,单独存放在TestReq中, 1-- 只包含所有的方向代码,存储在DutList中 # 2--跌落方向在PLC设置,上位机负责读取,产品系列号,项目代号,阶段,测试周次上位机传给PLC # 3--基本同2,只是用于测试,testReqList由方式1产生 dutDirectionMode = 2 dtMachineService = None # 在全局或应用上下文中缓存表结构(示例使用全局字典) TABLE_SCHEMA_CACHE = {} app = Flask(__name__, static_folder='web') app.config['SECRET_KEY'] = 'secret!' # 关闭所有的日志记录 app.logger.disabled = True CORS(app) # 这会让所有的资源都支持跨域访问 CORS(app, resources=r"/*") def set_machine_service(machine_service): global dtMachineService dtMachineService = machine_service def is_json_serializable(value): try: json.dumps(value) return True except (TypeError, OverflowError): print(TypeError, OverflowError) return False def get_cached_table_schema(table_name, db_conn): """带缓存的表结构获取""" if table_name not in TABLE_SCHEMA_CACHE: # 未缓存时从数据库读取 cursor = db_conn.execute(f"PRAGMA table_info({table_name})") schema = {} for row in cursor.fetchall(): schema[row[1]] = { 'type': row[2].upper(), 'is_pk': row[5] > 0 } TABLE_SCHEMA_CACHE[table_name] = schema return TABLE_SCHEMA_CACHE[table_name] # 设置跌落机的试验参数 @app.route('/machine_control', methods=['POST']) @cross_origin() def machine_control(): global dtm_machines, dtMachineService params = request.json value_return = {"status": "error"} actionParam = {} dtMachineService.setMachineBusyFlag(True) # 检测键是否存在 if 'setParams' in params: # 设置工作站(台)测试执行参数 value_return = {"status": "error", "msg": "setParams error"} setParams = params['setParams'] actionParam = setParams print("machine_control setParams", setParams) # cyx # 使用 set 检测多个键是否存在 for setParam in setParams: required_keys = {'machine', 'com', 'station'} if required_keys.issubset(setParam.keys()): if 'dropHeight' in setParam: try: dtMachineSN = setParam['machine'] result = dtMachineService.set_station_dropheight(dtMachineSN, setParam['station'], int(setParam['dropHeight'])) except Exception as error: value_return = {'status': "error", "message": "set station dropHeght ", "error": error} if 'status' in result and result['status'] == 'success': value_return = {'status': "success", 'message': "set station dropHeight success"} pass if 'dropCycles' in setParam: try: dtMachineSN = setParam['machine'] result = dtMachineService.set_station_cycles(dtMachineSN, setParam['station'], setParam['dropCycles']) print("machine_control setParams set cycles return ", result) # cyx except Exception as error: value_return = {'status': "error", "message": "set station dropCycles ", "error": error} if 'status' in result and result['status'] == 'success': value_return = {'status': "success", 'message': "set station dropCycles success"} if 'cyclesFinished' in setParam: try: dtMachineSN = setParam['machine'] result = dtMachineService.set_station_finished(dtMachineSN, setParam['station'], setParam['cyclesFinished']) except Exception as error: value_return = {'status': "error", "message": "set station cyclesFinished ", "error": error} if 'status' in result and result['status'] == 'success': value_return = {'status': "success", 'message': "set station cyclesFinished success"} pass # return value_return if 'start' in params or 'stop' in params or 'resume' in params or 'pause' in params or 'cancel' in params \ or 'reset' in params: # 启动 停止 继续 取消 暂停 工作站(台) value_return = {'status': "error", 'message': "station start stop resume error"} param = None if 'start' in params: param = params['start'] if 'stop' in params: param = params['stop'] if 'cancel' in params: param = params['cancel'] if 'resume' in params: param = params['resume'] if 'pause' in params: param = params['pause'] if 'reset' in params: param = params['reset'] actionParam = param # 使用 set 检测多个键是否存在 required_keys = {'machine', 'station'} if required_keys.issubset(param.keys()): # 将前端发送的 start resume stop cancel pause 等命令统一按照dtStationAttachDut 处理,以便 # 统一处理工位 机台 试验样品 试验要求的状态 if 'start' in params: return dtMachineService.dtStationAttachDut(param['machine'], param['station'], 'start', None, True) if 'resume' in params: return dtMachineService.dtStationAttachDut(param['machine'], param['station'], 'resume', None, True) if 'stop' in params: return dtMachineService.dtStationDetachDut(param['machine'], param['station'], 'stop') if 'cancel' in params: return dtMachineService.dtStationDetachDut(param['machine'], param['station'], 'cancel') if 'pause' in params: return dtMachineService.dtStationAttachDut(param['machine'], param['station'], 'pause', None, True) if 'reset' in params: return dtMachineService.dtStationDetachDut(param['machine'], param['station'], 'reset') else: # print("键 'machine', 'com', 'station', 'params' 不完全存在于 JSON 中") pass # return jsonify(value_return) if 'getParams' in params: value_return = {'status': "error", 'message': "get station params error"} param = params['getParams'] print("machine_control post", params) # 使用 set 检测多个键是否存在q required_keys = {'machine', 'com', 'station'} if required_keys.issubset(param.keys()): if 'all' not in param and 'machine' in param: try: dtMachineSN = param['machine'] result = dtMachineService.read_station_cyclesFinished(dtMachineSN, param['station']) if 'status' in result and result['status'] == 'success' and 'value' in result: value_return["status"] = "success" value_return["action"] = "getParams" value_return["finished"] = result['value'] value_return["message"] = "get station params success" except Exception as error: value_return["error"] = error pass # return jsonify(value_return) if 'getStationValue' in params: # 获取机器工作站(台)的状态与数据 value_return = {'status': "error", 'message': "get station params error"} param = params['getStationValue'] # 使用 set 检测多个键是否存在q required_keys = {'machine', 'station'} if 'station' in param and 'machine' in param: if dtMachineService: result = dtMachineService.get_station_value(param['machine'], param['station']) value_return = result else: value_return = {"status": "error", "msg": "machine service is not available"} # print("键 'machine', 'com', 'station', 'params' 不完全存在于 JSON 中") pass # return jsonify(value_return) if 'getMachinesValue' in params: # 获取机器的状态与数据 value_return = {'status': "error", 'message': "get station params error"} param = params['getMachinesValue'] # print("/machine_control getMachinesValue", dtMachineService, param) if 'machines' in param: if dtMachineService: result = dtMachineService.get_machines_value(param['machines']) value_return = result else: value_return = {"status": "error", "msg": "machine service is not available"} # print("键 'machine', 'com', 'station', 'params' 不完全存在于 JSON 中") pass current_time = datetime.datetime.now().strftime('%H:%M:%S.%f')[:-3] # return jsonify(value_return) if 'attachDut' in params: # 将测试样品与机器的工作站(台)关联 value_return = {'status': "error", 'message': "station attach dut error"} param = params['attachDut'] if 'machine' in param and 'station' in param and 'dut' in param and 'action' in param: station_sn = param['station'] machine_sn = param['machine'] dut_sn = param['dut'] action = param['action'] updateTableFlag = param['updateTableFlag'] userid = param.get('userid', None) # 安排试验的用户id result = dtMachineService.dtStationAttachDut(machine_sn, station_sn, action, dut_sn, updateTableFlag, userid) # print("machine control attachDut",params) if 'status' in result and result['status'] == 'success': value_return = {'status': "success", 'message': "station attach dut success"} if 'station' in result: value_return['station'] = result['station'] # return jsonify(value_return) if 'detachDut' in params: # 测试样品与机器的工作站(台)断开关联 value_return = {'status': "error", 'message': "station detach dut error"} param = params['detachDut'] if 'machine' in param and 'station' in param and 'action' in param: station_sn = param['station'] machine_sn = param['machine'] action = param['action'] result = dtMachineService.dtStationDetachDut(machine_sn, station_sn, action) if 'status' in result and result['status'] == 'success': value_return = {'status': "success", 'message': "station detach dut success"} if 'station' in result: value_return['station'] = result['station'] # return jsonify(value_return) if 'assignTestReq' in params: # 设置测试要求 value_return = {'status': "error", 'message': "station assign testReq error"} param = params['assignTestReq'] if 'machine' in param and 'station' in param and 'dut' in param and 'testReqIndex' in param: station_sn = param['station'] machine_sn = param['machine'] dut_sn = param['dut'] testReqIndex = param['testReqIndex'] # 测试样件的测试项目index result = dtMachineService.dtStationAssignTestReq(machine_sn, station_sn, dut_sn, testReqIndex) if 'status' in result and result['status'] == 'success': value_return = {'status': "success", 'message': "station assign testReq success"} if 'station' in result: value_return['station'] = result['station'] return value_return if 'registerTest' in params: # PLC 寄存器测试 value_return = {'status': "error", 'message': "register read or write test error"} param = params['registerTest'] # 使用 set 检测多个键是否存在q required_keys = {'machine', 'station'} if 'machine' in param and 'action' in param and 'address' in param: if dtMachineService: result = dtMachineService.register_test(param['machine'], param['action'], param['address'], param.get('value', None)) value_return = result print("register_test result:", result) # cyx else: value_return = {"status": "error", "msg": "machine service is not available"} # print("键 'machine', 'com', 'station', 'params' 不完全存在于 JSON 中") pass # return jsonify(value_return) dtMachineService.setMachineBusyFlag(False) return jsonify(value_return) # 设置跌落机的试验参数 @app.route('/get_machine_config', methods=['GET']) @cross_origin() def get_machine_config(): global dtm_machines, dtMachineService json_return = {"status": "error"} print("get machine_config") if dtMachineService: json_return = {"status": "success", "data": dtMachineService.get_machine_com_config()} return jsonify(json_return) # 设置跌落机的试验参数 @app.route('/get_com_list', methods=['POST']) @cross_origin() def get_com_list(): json_return = {"status": "error"} ports = [] try: for port in serial.tools.list_ports.comports(): ports.append(port.name) json_return = {"status": "success", "data": ports} except Exception as error: json_return = {"status": "error", "message": "get com ports list error" + error} return jsonify(json_return) @app.route('/dbTableAccess', methods=['GET', 'POST']) @cross_origin() def access_table_data(): global date_span_str table = request.args.get('table') pageSize = request.args.get('pageSize', default=None, type=int) currentPage = request.args.get('currentPage', default=None, type=int) # print(f"/dbTableAccess table={table} method ={request.method} pageSize={pageSize} currentPage={currentPage}") db_path = os.path.join('db', 'dtmgtDb.db') if table is None: return jsonify({"error": "Table parameter is missing"}), 400 if g is None: db = sqlite3.connect(db_path) elif hasattr(g, 'db') == False: db = sqlite3.connect(db_path) else: db = g.db if request.method == 'GET': sql_condition_str = "" sql_params = [] parameters_to_check = [] if table == 'dutList': parameters_to_check = ['name', 'SN', 'description', 'status', 'stationAssigned', 'machineAssigned'] if table == 'dropDirection': parameters_to_check = ['code', 'label'] if table == 'testReq': parameters_to_check = ['SN', 'dropItem', 'dropHeight', 'dropCycles', 'description', 'status'] if table == 'project': parameters_to_check = ['name', 'key', 'manager', 'type', 'description'] if table == 'projectPhase': parameters_to_check = ['name', 'PN', 'description'] if table == 'dtMachine': parameters_to_check = ['label', 'SN', 'status', 'type', 'color', 'description', 'plc_address'] if table == 'testReqResult': parameters_to_check = ['SN', 'id', 'dropItem', 'dropHeight', 'dropCycles', 'description', 'status', 'userid', 'workOrder', 'inspector'] def get_parameter(param): param_sql = "" param_value = request.args.getlist(param) if param in ["SN", "id", 'status'] and table == "testReqResult": param = f"testReq.{param}" if param in ["workOrder", "inspector"] and table == "testReqResult": param = f"dutList.{param}" """ if param_value and param == "workOrder" and table == "testReqResult": param_sql = ( f'AND dutList.workOrder IS NOT NULL ' f"AND dutList.{param} IN ({','.join(['?'] * len(param_value))})" ) elif param_value and param == "inspector" and table == "testReqResult": param_sql = ( f'AND dutList.inspector IS NOT NULL ' f"AND dutList.{param} IN ({','.join(['?'] * len(param_value))})" ) """ if param_value and param != 'stationAssigned': param_sql = f" AND {param} IN ({','.join(['?'] * len(param_value))})" else: pass if param_value and param == 'stationAssigned': # param_sql = f" AND json_extract({param}, '$.dtMachine') IN ({','.join(['?'] * len(param_value))})" # cyx 2024 11 07 修改 try: station_data = json.loads(param_value[0]) # 将传入的 JSON 字符串解析为 Python 字典 if 'dtMachine' in station_data and 'station' in station_data: # 同时匹配 JSON 和其他情况 param_sql = ( f" AND (CASE WHEN json_valid({param}) THEN " f"(json_extract({param}, '$.dtMachine') = ? AND json_extract({param}, '$.station') = ?) " f"ELSE 1 END)" ) param_value = [station_data['dtMachine'], station_data['station']] elif 'dtMachine' in station_data: # 仅匹配 JSON 的 dtMachine param_sql = ( f" AND (CASE WHEN json_valid({param}) THEN " f"json_extract({param}, '$.dtMachine') = ? ELSE 1 END)" ) param_value = [station_data['dtMachine']] elif 'station' in station_data: # 仅匹配 JSON 的 station param_sql = ( f" AND (CASE WHEN json_valid({param}) THEN " f"json_extract({param}, '$.station') = ? ELSE 1 END)" ) param_value = [station_data['station']] finally: pass if param_value and param == 'machineAssigned': param = 'stationAssigned' try: # 动态构建 IN 子句 placeholders = ','.join(['?'] * len(param_value)) param_sql = ( f" AND (CASE WHEN json_valid({param}) THEN " f"json_extract({param}, '$.dtMachine') IN ({placeholders}) " f"ELSE 1 END)" ) except (json.JSONDecodeError, TypeError): # 如果解析 JSON 失败,则生成默认匹配条件 param_sql = " AND 1 = 1" param_value = [] # param_sql = f" AND json_extract({param}, '$.dtMachine') IN ({','.join(['?'] * len(param_value))})" # cyx 2024 11 07 修改 return param_sql, param_value current_time = datetime.datetime.now().strftime('%H:%M:%S.%f')[:-3] for param in parameters_to_check: param_sql, param_value = get_parameter(param) sql_condition_str += param_sql sql_params.extend(param_value) current_time = datetime.datetime.now().strftime('%H:%M:%S.%f')[:-3] try: total_count = 0 if table == 'testReqResult': """select_sql_str = ( f'SELECT testReq.* , dutList.project, dutList.phase , dutList.stationAssigned, ' f'dutList.name ,dutList.SN as dutSN, dutList.weeks, dutList.workOrder,dutList.inspector, ' f'dutList.projectType as projectType,project.name as ProjectName, projectPhase.name as projectPhase ' f'FROM testReq LEFT JOIN dutList ON testReq.SN = dutList.SN ' f'LEFT JOIN project ON dutList.project = project.key ' f'LEFT JOIN projectPhase ON dutList.phase = projectPhase.PN ' f'WHERE testReq.id > 0 ' )""" select_sql_str = ( f'SELECT * from TestReq ' f'WHERE TestReq.id > 0 ' ) elif table == 'dutList' or table == 'DUTList': select_sql_str = ( f'SELECT dutList.* , project.name AS projectName, projectPhase.name AS projectPhase ' f'FROM DUTList ' f'LEFT JOIN ' f'project ON dutList.project = project.key ' f'LEFT JOIN ' f'projectPhase ON dutList.phase = projectPhase.PN ' f'WHERE {table}.id>0 ' ) else: select_sql_str = f"SELECT * FROM {table} WHERE {table}.id > 0 " if table == 'testReqResult': date_span_str = "" if request.args.get('date1') and request.args.get('date2'): try: # 将这些字符串转化为日期对象 # 前端传入类似 date1: '2023/11/10 10:10:00', date2: '2024/6/11 10:10:00' start_date_obj = datetime.datetime.strptime(request.args.get('date1'), "%Y/%m/%d %H:%M:%S") end_date_obj = datetime.datetime.strptime(request.args.get('date2'), "%Y/%m/%d %H:%M:%S") # 然后,将这些日期对象转化为字符串,以符合数据库中日期字段的格式 formatted_start_date = start_date_obj.strftime('%Y-%m-%d %H:%M:%S') formatted_end_date = end_date_obj.strftime('%Y-%m-%d %H:%M:%S') date_span_str = f" AND STRFTIME('%Y-%m-%d %H:%M:%S',TestReq.endTime) BETWEEN '{formatted_start_date}' AND '{formatted_end_date}'" except Exception as error: print("error=", error) finally: sql_condition_str = sql_condition_str + date_span_str if pageSize and currentPage: cursor = db.cursor() if table == 'testReqResult': sql_count = ( f"SELECT COUNT(*) FROM TestReq LEFT JOIN dutList ON testReq.SN = dutList.SN WHERE testReq.id >0 " + sql_condition_str ) cursor.execute(sql_count, sql_params) else: cursor.execute(f"SELECT COUNT(*) FROM {table} WHERE id >0 " + sql_condition_str, sql_params) total_count = cursor.fetchone()[0] if pageSize and currentPage: sql_condition_str = sql_condition_str + f' LIMIT {pageSize} OFFSET {pageSize * (currentPage - 1)}' if table == 'dutList' or table == 'DUTList': # sql_str = sql_str + f" ORDER BY date(createdate) DESC" pass current_time = datetime.datetime.now().strftime('%H:%M:%S.%f')[:-3] # print(f"{current_time} dbTableAccess {table} [select sql_str:]", select_sql_str, # "[condition:]", sql_condition_str, "[sql_paramms:]", sql_params) # cyx cursor = db.cursor() cursor.execute(select_sql_str + sql_condition_str, sql_params) """ else: if pageSize and currentPage: sql_str = sql_str + f' LIMIT {pageSize} OFFSET {pageSize * (currentPage - 1)}' print("dbTableAccess sql_str", sql_str, sql_params) # cyx cursor = db.cursor() cursor.execute(sql_str, sql_params) """ except sqlite3.Error as e: print(f"dbTableAccess {table} error={e}") # cyx return jsonify({"error": f"Database error: {e}"}), 500 rows = cursor.fetchall() column_names = [description[0] for description in cursor.description] result = [] for index,row in enumerate(rows): dict_row = {col: row[idx] if row[idx] is not None else None for idx, col in enumerate(column_names)} dict_row['mysequence'] = index + 1 # 添加序号 if 'stationAssigned' in dict_row: try: station_assigned_json = json.loads(dict_row['stationAssigned']) if station_assigned_json: dict_row['dtMachine'] = station_assigned_json['dtMachine'] dict_row['station'] = station_assigned_json['station'] if dict_row.get('direction_codes'): dict_row['direction_codes'] = json.loads(dict_row['direction_codes']) except Exception as e: dict_row['dtMachine'] = "" dict_row['station'] = "" dict_row['stationAssigned'] = None finally: pass result.append(dict_row) return jsonify({'totalCount': total_count, 'length': len(rows), 'data': result}) elif request.method == 'POST': data = request.get_json() action = data['action'] records = data['records'] for record in records: # 将direction_codes 转换为字符串 if record.get('direction_codes'): try: record['direction_codes'] = json.dumps(record.get('direction_codes')) except Exception as e: record['direction_codes'] = '[]' continue if action is None: return jsonify({"status": "error", "message": "action is not specified"}) """ elif action == "insert": try: with db: cursor = db.cursor() current_date = datetime.datetime.now().strftime('%Y-%m-%d') for record in records: if 'id' in record: del record['id'] columns = ', '.join(record.keys()) placeholders = ', '.join('?' for _ in record) sql = f'INSERT INTO {table} ({columns}) VALUES ({placeholders})' cursor.execute(sql, tuple(record.values())) # db.commit() return jsonify( {"status": "success", "action": "insert", "message": f"insert records into {table} success", "recordsCnt": len(records)}) except sqlite3.Error as error: print(f'insert {table} error {error}') return jsonify( {"status": "error", "action": "insert", "message": f"insert records into {table} error"}) """ if action == "insert": try: with db: cursor = db.cursor() # 从缓存获取表结构(首次访问时自动填充缓存) table_schema = get_cached_table_schema(table, db) # 数据清洗 sanitized_records = [] for record in records: clean_record = {} for key, value in record.items(): # 字段存在性检查 if key not in table_schema: continue # 自增主键跳过 if table_schema[key]['is_pk']: continue # 类型转换 try: target_type = table_schema[key]['type'] if target_type == 'INTEGER': clean_record[key] = int(value) if value not in (None, '') else None elif target_type == 'TEXT': clean_record[key] = str(value) if value is not None else None elif target_type == 'REAL': clean_record[key] = float(value) if value not in (None, '') else None else: clean_record[key] = value except (ValueError, TypeError): clean_record[key] = None # 转换失败设为NULL sanitized_records.append(clean_record) # 动态构建插入语句(所有记录取字段并集) all_fields = set() for rec in sanitized_records: all_fields.update(rec.keys()) if not all_fields: return jsonify({"status": "error", "message": "No valid fields to insert"}) # 按字段名排序保证参数顺序一致 sorted_fields = sorted(all_fields) sql = f"INSERT INTO {table} ({','.join(sorted_fields)}) VALUES ({','.join(['?'] * len(sorted_fields))})" # 准备参数列表 params = [] for rec in sanitized_records: params.append(tuple(rec.get(field) for field in sorted_fields)) # 批量执行 cursor.executemany(sql, params) return jsonify( {"status": "success", "action": "insert", "message": f"insert records into {table} success", "recordsCnt": len(records)}) except sqlite3.Error as error: print(f'insert {table} error {error}') return jsonify( {"status": "error", "action": "insert", "message": f"insert records into {table} error"}) elif action == "update": try: update_key = 'PN' if table == 'dutList': update_key = 'SN' if table == 'dropDirection': update_key = 'code' if table == 'testReq': update_key = 'id' if table == 'project': update_key = 'key' if table == 'projectPhase': update_key = 'PN' if table == 'dtMachine': update_key = 'id' # 这里有bug,20251208 由 'SN'改成 'id' if table == 'get_counter': update_key = 'current_counter' with db: cursor = db.cursor() for record in records: pn_value = record.get(update_key, None) if pn_value is not None: cursor.execute( f'UPDATE {table} SET {", ".join(["{} = ?".format(field) for field in record])} WHERE {update_key} = ?', tuple(record.values()) + (record[update_key],)) # db.commit() return jsonify( {"status": "success", "action": "update", "message": f"update records into {table} success", "recordsCnt": len(records)}) except sqlite3.Error as error: print('update duts error', error) return jsonify( {"status": "error", "action": "update", "message": f"update records into {table} error{error}"}) elif action == "delete": try: with db: cursor = db.cursor() cursor.executemany(f"DELETE FROM {table} WHERE id = ?", [(record['id'],) for record in records]) # db.commit() return jsonify( {"status": "success", "action": "delete", "message": f"delete {table} records success", "recordsCnt": len(records)}) except sqlite3.Error as error: print('delete', error) return jsonify( {"status": "error", "action": "delete", "message": f"delete {table} records error{error}"}) # 添加一个全局错误处理器 @app.errorhandler(500) def internal_error(error): return jsonify({'error': 'Internal server error'}), 500 @app.route('/shutdown', methods=['POST']) def shutdown_flask_Server(): print("flask http server Shutting down gracefully...") """ def stop(self): Stop a running SocketIO web server. This method must be called from a HTTP or SocketIO handler function """ shutdown_func = request.environ.get('werkzeug.server.shutdown') if shutdown_func is None: print("shutdown_func is None") pass else: try: shutdown_func() except Exception as e: print('Error shutting down server:', str(e)) else: print('flask Server shutting down...') return 'flask Server shutting down...' @app.route('/login', methods=['POST']) @cross_origin() def login_validate(): json_return = {"status": "error"} params = request.json db_path = os.path.join('db', 'dtmgtDb.db') print("/login", params) # cyx if params.get('username') is None or params.get('password') is None: return jsonify({"status": "error", "error": "username or password is missing"}), 400 if g is None: db = sqlite3.connect(db_path) elif hasattr(g, 'db') == False: db = sqlite3.connect(db_path) else: db = g.db if params.get('username') == 'topAdmin' and params.get('password') == 'topAdmin': json_return = {"status": "success", "username": params.get('username'), "userid": "top999999", "role": 'super', "auth": ""} return jsonify(json_return) if params.get('username') == 'topAdmin123' and params.get('password') == 'topAdmin123': json_return = {"status": "success", "username": params.get('username'), "userid": "top888888", "role": 'super', "auth": ""} return jsonify(json_return) sql_str = f"SELECT * FROM user WHERE id > 0 and username =? and password = ?" sql_params = [params.get('username'), params.get('password')] try: cursor = db.cursor() cursor.execute(sql_str, sql_params) rows = cursor.fetchall() column_names = [description[0] for description in cursor.description] result = [] for row in rows: dict_row = {col: row[idx] if row[idx] is not None else None for idx, col in enumerate(column_names)} result.append(dict_row) # print("login result",result)#cyx if len(result) == 1: json_return = {"status": "success", "username": result[0].get('username'), "userid": result[0].get('userid'), "role": result[0].get('role'), "auth": result[0].get('auth')} except sqlite3.Error as e: print("get user info error", e) # cyx return jsonify(json_return) @app.route('/dutDirectionMode', methods=['GET']) @cross_origin() def get_dutDirectionMode(): return jsonify({"status": "success", "data": dutDirectionMode}) @app.route('/modbusServerStarted', methods=['POST']) @cross_origin() def modbus_server_started(): json_return = {"status": "success"} params = request.json print("/modbusServerStarted", params) # cyx dtMachineService.dtm_virt_machine_client_connect() return jsonify(json_return) @app.before_request def before_request(): global dtMachineService, initialized db_path = os.path.join('db', 'dtmgtDb.db') g.db = sqlite3.connect(db_path) # print("open database", g.db) """ @app.route('/') @cross_origin() def send_file(path): print("access ",path) if path != "" and path.endswith(".html"): return send_from_directory(app.static_folder, path) else: return send_from_directory(app.static_folder, path) """