JS中用innerHTML生成<s:select>的问题

本文探讨了使用JavaScript动态生成HTML代码时出现的问题,特别是当预期生成一个包含select元素的div时,却意外生成了额外的table相关元素。文章分析了问题产生的原因,并探讨了解决方案。
the_cell=newrow.insertCell(4);
the_cell.innerHTML="<div><s:select id='shequxuanze' headerValue='--Please select--' headerKey='' list='#request.resultList' listKey='#request.shequ.sqName' listValue='#request.shequ.sqName'></s:select></div>";



实际生成的代码:
the_cell=newrow.insertCell(4);
the_cell.innerHTML="<div>
<tr>
<td class="tdLabel"></td>
<td><select name="" id="shequxuanze">
<option value="">--Please select--</option>
<option value="健翔园社区">健翔园社区</option>
<option value="安翔里社区">安翔里社区</option>
</select>
</td>
</tr>
</div>";


为什么会这样呢 多了tr td
<!-- 权限管理 --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="../../layui/css/layui.css"> <link rel="stylesheet" href="../../css/diy.css"> <style> .layui-body { overflow-x: scroll; } </style> </head> <body> <div class="section1"> <!-- 内容主体区域 --> <div class="manu auth" style="padding: 15px;"> <form class="layui-form" action=""> <div class="form-input-box-t layui-form-item"> <div class="input-box"> <label class="layui-form-label">权限名</label> <div class="layui-input-block input-i block"> <input type="text" name="mod_name" required lay-verify="required" autocomplete="off" class="layui-input"> <!--通过lay-verify="required"实现输入验证,确保必填字段非空--> </div> </div> <div class="input-box"> <!--查询部分--> <label class="layui-form-label">用户组</label> <div class="layui-input-block select block"> <select name="user_group" lay-filter="required" id="user_group"> <option value=""></option> </select> </div> </div> <div class="input-box"> <label class="layui-form-label">添加权限</label> <div class="layui-input-block select block"> <select name="add" lay-filter="required"> <option value=""></option> <option value="0">无</option> <option value="1">有</option> </select> </div> </div> <div class="input-box"> <label class="layui-form-label">修改权限</label> <div class="layui-input-block select block"> <select name="set" lay-filter="required"> <option value=""></option> <option value="0">无</option> <option value="1">有</option> </select> </div> </div> <div class="input-box"> <label class="layui-form-label">删除权限</label> <div class="layui-input-block select block"> <select name="del" lay-filter="required"> <option value=""></option> <option value="0">无</option> <option value="1">有</option> </select> </div> </div> <div class="input-box"> <label class="layui-form-label">查询权限</label> <div class="layui-input-block select block"> <select name="get" lay-filter="required"> <option value=""></option> <option value="0">无</option> <option value="1">有</option> </select> </div> </div> </div> </form> <div class="buts"> <button type="button" class="layui-btn layui-btn-normal" id="inquire"><span>查询</span></button> <button type="button" class="layui-btn layui-btn-normal" id="reset"><span>重置</span></button> </div> <div class="Customize-the-box"> <div class="circle"></div> <div class="circle"></div> <div class="card-inner"></div> </div> </div> <h1>数据列表</h1> <div class="table"> <table class="layui-hide" id="newsClassification" lay-filter="newsClassification"></table> <script type="text/html" id="toolbarDemo"> <div class="layui-btn-container"> <button class="layui-btn layui-btn-sm" lay-event="add">修改</button> </div> </script> </div> </div> <script src="../../layui/layui.js"></script> <script src="../../js/axios.min.js"></script> <script src="../../js/index.js"></script> <script src="../../js/base.js" charset="utf-8"></script> <script> var BaseUrl = baseUrl() layui.use(['element', 'layer', 'util'], function () { var element = layui.element , table = layui.table , layer = layui.layer , util = layui.util , $ = layui.$; let personInfo = JSON.parse(sessionStorage.personInfo) let user_group = personInfo.user_group let token = sessionStorage.token || null //头部事件 util.event('lay-header-event', { //左侧菜单事件 menuLeft: function (othis) { layer.msg('展开左侧菜单的操作', {icon: 0}); } , menuRight: function () { layer.open({ type: 1 , content: '<div style="padding: 15px;">处理右侧面板的操作</div>' , area: ['260px', '100%'] , offset: 'rt' //右上角 , anim: 5 , shadeClose: true }); } }); // table 事件 table.render({ elem: '#newsClassification' , toolbar: true , url: BaseUrl + '/api/auth/get_list' , headers: { 'x-auth-token': token, 'Content-Type': 'application/json' } ,limits: [10] , page: { //支持传入 laypage 组件的所有参数(某些参数除外,如:jump/elem) - 详见文档 layout: ['limit', 'count', 'prev', 'page', 'next', 'skip'] //自定义分页布局 //,curr: 5 //设定初始在第 5 页 , groups: 1 //只显示 1 个连续页码 , first: false //不显示首页 , last: false //不显示尾页 } , cols: [[ {type: 'checkbox'} , {field: 'user_group', width: '10%', title: '用户组'} , {field: 'mod_name', width: '10%', title: '权限名称', templet: function (d) { if (d.path.replace('/'+d.table_name+'/','')=='table') { return "<div>"+d.mod_name+"后台列表</div>" } if (d.path.replace('/'+d.table_name+'/','')=='view') { return "<div>"+d.mod_name+"后台详情</div>" } if (d.path.replace('/'+d.table_name+'/','')=='list') { return "<div>"+d.mod_name+"前台列表</div>" } if (d.path.replace('/'+d.table_name+'/','')=='details') { return "<div>"+d.mod_name+"前台详情</div>" } if (d.path.replace('/'+d.table_name+'/','')=='edit') { return "<div>"+d.mod_name+"前台编辑</div>" } } } , { field: 'add', width: '10%', title: '<span>添加</span>权限', templet: function (d) { if (d.add == '0') { return "<div>无</div>" } else { return "<div>有</div>" } } } , { field: 'del', width: '10%', title: '<span>删除</span>权限', templet: function (d) { if (d.del == '0') { return "<div>无</div>" } else { return "<div>有</div>" } } } , { field: 'set', width: '10%', title: '修改权限', templet: function (d) { if (d.set == '0') { return "<div>无</div>" } else { return "<div>有</div>" } } } , { field: 'get', width: '10%', title: '<span>查询</span>权限', templet: function (d) { if (d.get == '0') { return "<div>无</div>" } else { return "<div>有</div>" } } } , { field: 'create_time', width: '15%', title: '新增时间', sort: true, templet: "<div>{{layui.util.toDateString(d.create_time, 'yyyy-MM-dd HH:mm:ss')}}</div>" } , { field: 'update_time', width: '15%', title: '更新时间', sort: true, templet: "<div>{{layui.util.toDateString(d.update_time, 'yyyy-MM-dd HH:mm:ss')}}</div>" } , {field: 'operate', title: '操作', toolbar: "#toolbarDemo"} ]] , page: true, request: { limitName: 'size' }, response: { statusName: 'code', //规定返回/Back的状态码字段为code statusCode: 200 //规定成功的状态码味200 }, parseData: function (res) { return { "code": 200, "msg": "", "count": res.result.count, "data": res.result.list } }, where: {like: 0, size: 10} }); layui.table.on('tool(newsClassification)', function (obj) { //注:tool是工具条事件名,test是table原始容器的属性 lay-filter="对应的值" var data = obj.data; //获得当前行数据 var layEvent = obj.event; //获得 lay-event 对应的值(也可以是表头的 event 参数对应的值) var tr = obj.tr; //获得当前行 tr 的DOM对象 if (layEvent == "add") { let auth_id = data.auth_id // window.location = ('./view.html?' + auth_id) layopen_dateil('./view.html?' + auth_id) } }); // 请求参数: let request = {like: 0, size: 10, page: 1, mod_name: '', user_group: '',add:'',set:'',del:'',get:'',orderby: 'create_time desc'} // <span>重置</span>/Reset参数 let resetName = {like: 0, size: 10, page: 1, orderby: 'create_time desc'} fun('newsClassification', BaseUrl + '/api/auth/del', 'auth_id', request, resetName) async function get_list_user_group() { $.ajax({ url: BaseUrl + "/api/user_group/get_list", type: "get", async: false, success: function (data) { if (data && typeof data === 'string'){ data = JSON.parse(data); } if (data.result) { // 拿到单选框的父级节点 let select = document.querySelector("#user_group") let op1 = document.createElement('option') select.appendChild(op1) // 收集数据 长度 let count // 收集数据 数组 let arr = [] count = data.result.count arr = data.result.list for (let i = 0; i < arr.length; i++) { // 创建节点 let op = document.createElement('option') // 给节点赋值 op.innerHTML = arr[i].name op.value = arr[i].name // 新增/Add节点 select.appendChild(op) layui.form.render('select') } } } }); } get_list_user_group(); }); </script> </body> </html> 分析一下以上代码,不要自己加内容
05-28
js:// script.js // 订单表单提交 document.querySelector('.myForm').onsubmit = function (e) { e.preventDefault(); const fields = { orderNum: '订单编号', orderDate: '订单日期', orderDeliveryDate: '订单交期', productName: '产品名称', productNum: '产品编号', orderOutstandingQuantity: '订单未交数', specificationInfo: '规格信息', orderQuantity: '订单数量' }; const data = { type: "order" }; const missing = []; for (const [key, label] of Object.entries(fields)) { const val = document.getElementsByName(key)[0]?.value.trim(); if (!val) missing.push(label); data[key] = val || ''; } if (missing.length > 0) { alert(`以下字段不能为空:\n${missing.join('、')}`); return; } // remarks 可为空 data.remarks = document.getElementsByName('remarks')[0]?.value.trim() || ''; fetch('/submit', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }) .then(r => r.json()) .then(res => alert(res.message)) .catch(e => alert('提交失败: ' + e.message)); }; // 产线表单提交 document.querySelector('.myForm1').onsubmit = function (e) { e.preventDefault(); const rules = { productionLineName: { label: '产线名称', required: true }, productionLineNumb: { label: '产线编号', required: true }, productionCapacity: { label: '产线生产速率', required: true, validate: v => !isNaN(parseFloat(v)) && parseFloat(v) >= 0, msg: '必须为非负数' }, yieldRate: { label: '良品率', required: true, validate: v => { const n = parseFloat(v); return !isNaN(n) && n >= 0 && n <= 100; }, msg: '必须是 0~100 的数字' }, opStatus: { label: '产线状态', required: true }, productionNum: { label: '生产产品编号', required: true }, // 允许为空: productionName: { label: '生产产品名称', required: false }, specificationInfo: { label: '产品规格', required: false } }; const data = { type: "production_line" }; const missing = []; const invalid = []; for (const [key, rule] of Object.entries(rules)) { const input = document.getElementsByName(key)[0]; if (!input) continue; const val = input.value.trim(); data[key] = val; if (rule.required && !val) { missing.push(rule.label); continue; } if (rule.validate && val && !rule.validate(val)) { invalid.push(`${rule.label}: ${rule.msg}`); } } if (missing.length > 0) { alert(`以下必填字段为空:\n${missing.join('、')}`); return; } if (invalid.length > 0) { alert(`输入错误:\n${invalid.join('\n')}`); return; } fetch('/submit', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }) .then(r => r.json()) .then(res => alert(res.message)) .catch(e => alert('提交失败: ' + e.message)); }; // 上传订单 Excel document.getElementById('excelSubmit').addEventListener('submit', function (e) { e.preventDefault(); const file = document.getElementById('file').files[0]; if (!file) return alert("请选择一个文件"); const fd = new FormData(); fd.append('file', file); fetch('/upload/order', { method: 'POST', body: fd }) .then(r => r.json()) .then(res => alert(res.message)) .catch(() => alert("上传失败")); }); // 上传产线 Excel document.getElementById('excelSubmit1').addEventListener('submit', function (e) { e.preventDefault(); const file = document.getElementById('file1').files[0]; if (!file) return alert("请选择一个文件"); const fd = new FormData(); fd.append('file1', file); fetch('/upload/line', { method: 'POST', body: fd }) .then(r => r.json()) .then(res => alert(res.message)) .catch(() => alert("上传失败")); }); // 运行排程 document.getElementById('mat').addEventListener('click', function () { const resultDiv = document.getElementById('result'); resultDiv.innerHTML = '<div class="loading"></div>排程中...'; fetch('/run_schedule', { method: 'POST' }) .then(r => r.json()) .then(data => { if (data.success) { resultDiv.innerHTML = `<a href="/downloads/${data.file_name}" target="_blank">📥 下载排程结果.xlsx</a>`; } else { resultDiv.innerHTML = '运行失败: ' + data.error; } }) .catch(err => { resultDiv.innerHTML = '请求出错: ' + err.message; }); }); // 清空数据按钮 document.getElementById('clearOrdersBtn').addEventListener('click', () => { if (confirm("确定要清空所有订单数据吗?")) { fetch('/clear/orders', { method: 'POST' }) .then(r => r.json()) .then(res => alert(res.message)); } }); document.getElementById('clearLinesBtn').addEventListener('click', () => { if (confirm("确定要清空所有产线数据吗?")) { fetch('/clear/lines', { method: 'POST' }) .then(r => r.json()) .then(res => alert(res.message)); } }); html<!-- index.html --> <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <title>百景作品</title> <link rel="stylesheet" href="./static/css/style.css" /> </head> <body> <div class="container"> <!-- 表单区域 --> <div class="form-section"> <!-- 订单表单 --> <form class="myForm card"> <h3>订单录入</h3> <div class="inputBox"><label>订单编号</label><input type="text" name="orderNum" placeholder="请输入订单号"/></div> <div class="inputBox"><label>订单日期</label><input type="date" name="orderDate"/></div> <div class="inputBox"><label>订单交期</label><input type="date" name="orderDeliveryDate"/></div> <div class="inputBox"><label>产品名称</label><input type="text" name="productName" placeholder="请输入产品名称"/></div> <div class="inputBox"><label>产品编号</label><input type="text" name="productNum" placeholder="请输入产品编号"/></div> <div class="inputBox"><label>订单未交数</label><input type="number" name="orderOutstandingQuantity" min="0" placeholder="未交数量"/></div> <div class="inputBox"><label>规格信息</label><input type="text" name="specificationInfo" placeholder="请输入规格信息"/></div> <div class="inputBox"><label>备注</label><input type="text" name="remarks" placeholder="可备注"/></div> <div class="inputBox"><label>订单数量</label><input type="number" name="orderQuantity" min="1" placeholder="总订单量"/></div> <button class="submitButton" type="submit">提交订单</button> </form> <!-- 产线表单 --> <form class="myForm1 card"> <h3>产线配置</h3> <div class="inputBox"><label>产线名称</label><input type="text" name="productionLineName" placeholder="如:A线"/></div> <div class="inputBox"><label>产线编号</label><input type="text" name="productionLineNumb" placeholder="PL-001"/></div> <div class="inputBox"><label>生产速率</label><input type="number" step="0.1" name="productionCapacity" min="0" placeholder="件/小时"/></div> <div class="inputBox"><label>良品率%</label><input type="number" step="0.1" name="yieldRate" min="0" max="100" placeholder="95.5"/></div> <div class="inputBox"><label>产线状态</label><input type="text" name="opStatus" placeholder="正常 / 停止"/></div> <div class="inputBox"><label>生产产品编号</label><input type="text" name="productionNum" placeholder="对应产品编号"/></div> <div class="inputBox"><label>生产产品名称</label><input type="text" name="productionName" placeholder="如:电机"/></div> <div class="inputBox"><label>产品规格</label><input type="text" name="specificationInfo" placeholder="尺寸/功率等"/></div> <button class="submitButton" type="submit">提交产线</button> </form> </div> <!-- 文件上传 --> <div class="upload-section"> <form id="excelSubmit" enctype="multipart/form-data"> <input type="file" id="file" accept=".xlsx,.xls" /> <button class="xlsFile" type="submit">上传并导入订单文件</button> </form> <form id="excelSubmit1" enctype="multipart/form-data"> <input type="file" id="file1" accept=".xlsx,.xls" /> <button class="xlsFile1" type="submit">上传并导入产线文件</button> </form> </div> <!-- 排程与清空 --> <div class="action-section"> <button id="mat" class="mat">运行排程</button> <div id="result"></div> <div class="clear-buttons"> <button id="clearOrdersBtn" class="danger-btn">清空订单数据</button> <button id="clearLinesBtn" class="danger-btn">清空产线数据</button> </div> </div> </div> <script src="./static/js/script.js"></script> </body> </html> bj.py:import pymysql import pandas as pd import matlab.engine import os import threading _eng_lock = threading.Lock() _eng = None def getConn(): return pymysql.connect( host='localhost', user='baijing', password='12345', database='baijing', charset='utf8mb4', autocommit=False ) def insertHtmlData(orderNum, orderDate, orderDeliveryDate, productName, productNum, orderOutstandingQuantity, specificationInfo, remarks, orderQuantity): """插入订单数据""" sql = """ INSERT INTO orderinfo (orderNumber, orderDate, orderDeliveryDate, productName, productNumber, outstandingOrderQuantity, specificationInfo, Remarks, orderQuantity) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s) """ conn = getConn() try: with conn.cursor() as cursor: cursor.execute(sql, ( orderNum, orderDate, orderDeliveryDate, productName, productNum, int(orderOutstandingQuantity), specificationInfo, remarks or None, int(orderQuantity) )) conn.commit() except Exception as e: conn.rollback() print(f"[订单插入失败] {e}") raise finally: conn.close() def insertHtmlData1(productionLineName, productionLineNumb, productionCapacity, yieldRate, opStatus, productNum, productName, productSpecification): """插入产线数据""" sql = """ INSERT INTO productionlineinfo (productionLineName, productionLineNumber, productionCapacity, yieldRate, opStatus, productNum, productName, productSpecification) VALUES (%s, %s, %s, %s, %s, %s, %s, %s) """ conn = getConn() try: with conn.cursor() as cursor: cursor.execute(sql, ( productionLineName, productionLineNumb, float(productionCapacity), float(yieldRate), opStatus, productNum, productName, productSpecification or None )) conn.commit() except Exception as e: conn.rollback() print(f"[产线插入失败] {e}") raise finally: conn.close() # 批量导入 def clean_nan(val): """安全转换 NaN / None / 空字符串""" if pd.isna(val): return None if isinstance(val, float) and val == float('inf'): return None return str(int(val)) if isinstance(val, float) and val.is_integer() else str(val) def insert_batch_data(df): """批量导入订单 Excel""" required_cols = ['orderNumber', 'orderDate', 'orderDeliveryDate', 'productName', 'productNumber', 'outstandingOrderQuantity', 'specificationInfo', 'Remarks', 'orderQuantity'] if len(df.columns) < len(required_cols): raise ValueError(f"列数不足,期望 {len(required_cols)} 列") df = df.iloc[:, :9] df.columns = required_cols conn = getConn() try: with conn.cursor() as cursor: sql = """ INSERT INTO orderinfo (orderNumber, orderDate, orderDeliveryDate, productName, productNumber, outstandingOrderQuantity, specificationInfo, Remarks, orderQuantity) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s) """ for idx, row in df.iterrows(): try: cleaned = [clean_nan(row[col]) for col in required_cols] cursor.execute(sql, tuple(cleaned)) except Exception as e: print(f"跳过第 {idx + 1} 行: {e}") continue conn.commit() except Exception as e: conn.rollback() raise finally: conn.close() def insert_batch_data1(df): """批量导入产线 Excel""" required_cols = ['productionLineName', 'productionLineNumber', 'productionCapacity', 'yieldRate', 'opStatus', 'productNum', 'productName', 'productSpecification'] if len(df.columns) < len(required_cols): raise ValueError(f"产线表列数不足,期望 {len(required_cols)} 列") df = df.iloc[:, :8] df.columns = required_cols conn = getConn() try: with conn.cursor() as cursor: sql = """ INSERT INTO productionlineinfo (productionLineName, productionLineNumber, productionCapacity, yieldRate, opStatus, productNum, productName, productSpecification) VALUES (%s, %s, %s, %s, %s, %s, %s, %s) """ for idx, row in df.iterrows(): try: cleaned = [clean_nan(row[col]) for col in required_cols] cursor.execute(sql, tuple(cleaned)) except Exception as e: print(f"跳过第 {idx + 1} 行: {e}") continue conn.commit() except Exception as e: conn.rollback() raise finally: conn.close() # 清空表 def clear_table(table_name): allowed_tables = ["orderinfo", "productionlineinfo"] if table_name not in allowed_tables: raise ValueError("非法表名") conn = getConn() try: with conn.cursor() as cursor: cursor.execute(f"TRUNCATE TABLE `{table_name}`") conn.commit() finally: conn.close() # MATLAB 调度 def get_matlab_engine(): global _eng with _eng_lock: if _eng is None: _eng = matlab.engine.start_matlab() current_dir = os.path.dirname(os.path.abspath(__file__)) _eng.addpath(current_dir, nargout=0) return _eng def run_matlab(): try: eng = get_matlab_engine() current_dir = os.path.dirname(os.path.abspath(__file__)) output_folder = os.path.join(current_dir, "downloads") os.makedirs(output_folder, exist_ok=True) result = eng.GA_schedule(nargout=0) excel_path = os.path.join(output_folder, "排程结果.xlsx") if not os.path.exists(excel_path): raise FileNotFoundError("排程结果文件未生成") return excel_path except Exception as e: print(f"MATLAB 运行失败: {e}") raise # 订单数据库获取 def fetch_orders(): conn = getConn() cursor = conn.cursor() query = "SELECT * FROM orderinfo" cursor.execute(query) result = cursor.fetchall() orders_df = pd.DataFrame(result, columns=["TABLELINE_ID", "ORDER_ID", "ORDER_DATE", "DUE_DATE", "PRODUCT_NAME", "PRODUCT_ID", "OUTSTANDING_QUANTITY", "SPECIFICATION_INFO", "REMARKS", "ORDER_QUANTITY",]) cursor.close() conn.close() return orders_df # 从 MySQL 中获取生产线数据 def fetch_production_lines(): # 数据库连接 conn = getConn() # 创建指向对象 cursor = conn.cursor() # 读取生产线数据 query = "SELECT * FROM productionlineinfo" cursor.execute(query) result = cursor.fetchall() # 将结果转换为 DataFrame(使用 pandas 方便处理) production_lines_df = pd.DataFrame(result, columns=["TABLELINE_ID", "LINE_NAME", "LINE_ID", "LINE_RATE", "YIELD_RATE", "STATUS", "PRODUCT_ID", "PRODUCT_NAME", "PRODUCT_SPECIFICATION"]) # 关闭连接 cursor.close() conn.close() return production_lines_df main.py:import bj import webbrowser import threading import os from flask import Flask, render_template, request, jsonify, send_from_directory import pandas as pd app = Flask(__name__, static_folder='static') app.config['UPLOAD_FOLDER'] = 'uploads' os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True) app.config['ALLOWED_EXTENSIONS'] = {'xls', 'xlsx'} DOWNLOAD_FOLDER = os.path.join(os.path.dirname(os.path.abspath(__file__)), "downloads") os.makedirs(DOWNLOAD_FOLDER, exist_ok=True) @app.route('/') def index(): return render_template('index.html') # 统一提交接口 @app.route('/submit', methods=['POST']) def submit(): data = request.json form_type = data.get("type") if form_type == "order": orderNum = data.get('orderNum') orderDate = data.get('orderDate') orderDeliveryDate = data.get('orderDeliveryDate') productName = data.get('productName') productNum = data.get('productNum') orderOutstandingQuantity = data.get('orderOutstandingQuantity') specificationInfo = data.get('specificationInfo') remarks = data.get('remarks') orderQuantity = data.get('orderQuantity') print(f"收到订单: {orderNum}, {productName}") bj.insertHtmlData(orderNum, orderDate, orderDeliveryDate, productName, productNum, orderOutstandingQuantity, specificationInfo, remarks, orderQuantity) elif form_type == "production_line": productionLineName = data.get('productionLineName') productionLineNumb = data.get('productionLineNumb') productionCapacity = data.get('productionCapacity') yieldRate = data.get('yieldRate') opStatus = data.get('opStatus') productionNum = data.get('productionNum') productionName = data.get('productionName') specificationInfo = data.get('specificationInfo') print(f"收到产线: {productionLineName}, {productionLineNumb}") bj.insertHtmlData1(productionLineName, productionLineNumb, productionCapacity, yieldRate, opStatus, productionNum, productionName, specificationInfo) else: return jsonify({"message": "未知表单类型"}), 400 return jsonify({"message": "已提交"}) # 上传订单 Excel @app.route('/upload/order', methods=['POST']) def upload_order_file(): file = request.files.get('file') if not file or file.filename == '': return jsonify({"message": "未选择订单文件"}), 400 if not allowed_file(file.filename): return jsonify({"message": "订单文件格式不支持,仅支持 .xls 或 .xlsx"}), 400 filepath = os.path.join(app.config['UPLOAD_FOLDER'], file.filename) file.save(filepath) try: df = pd.read_excel(filepath) bj.insert_batch_data(df) return jsonify({"message": "订单数据导入成功!", "success": True}) except Exception as e: print(f"订单导入异常: {e}") return jsonify({"message": f"导入失败: {str(e)}", "success": False}), 500 # 上传产线 Excel @app.route('/upload/line', methods=['POST']) def upload_line_file(): file = request.files.get('file1') if not file or file.filename == '': return jsonify({"message": "未选择产线文件"}), 400 if not allowed_file(file.filename): return jsonify({"message": "产线文件格式不支持,仅支持 .xls 或 .xlsx"}), 400 filepath = os.path.join(app.config['UPLOAD_FOLDER'], file.filename) file.save(filepath) try: df = pd.read_excel(filepath) bj.insert_batch_data1(df) return jsonify({"message": "产线数据导入成功!", "success": True}) except Exception as e: print(f"产线导入异常: {e}") return jsonify({"message": f"导入失败: {str(e)}", "success": False}), 500 def allowed_file(filename): """检查文件扩展名是否合法""" return '.' in filename and filename.rsplit('.', 1)[1].lower() in app.config['ALLOWED_EXTENSIONS'] # 清空订单表 @app.route('/clear/orders', methods=['POST']) def clear_orders(): try: bj.clear_table("orderinfo") return jsonify({"message": "订单表已清空", "success": True}) except Exception as e: return jsonify({"message": f"清空失败: {e}", "success": False}), 500 # 清空产线表 @app.route('/clear/lines', methods=['POST']) def clear_lines(): try: bj.clear_table("productionlineinfo") return jsonify({"message": "产线表已清空", "success": True}) except Exception as e: return jsonify({"message": f"清空失败: {e}", "success": False}), 500 # 运行排程 @app.route('/run_schedule', methods=['POST']) def run_schedule(): try: excel_path = bj.run_matlab() file_name = os.path.basename(excel_path) return jsonify({"success": True, "file_name": file_name}) except Exception as e: return jsonify({"success": False, "error": str(e)}) # 下载结果文件 @app.route('/downloads/<filename>') def download_file(filename): return send_from_directory(DOWNLOAD_FOLDER, filename, as_attachment=True) # 自动打开浏览器 if __name__ == '__main__': def open_browser(): webbrowser.open_new('http://127.0.0.1:5000') threading.Timer(1.0, open_browser).start() app.run(debug=True, threaded=True) 在哪改
最新发布
10-31
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值