From 865c93c811b18715acf1163b81b3ac6962be7d1c Mon Sep 17 00:00:00 2001 From: Tian jianyong <11429339@qq.com> Date: Fri, 8 Nov 2024 23:43:57 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=B8=80=E4=BA=9B=E6=96=87?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .cursorrules | 82 ++ .gitignore | 27 + README.md | 23 + app.py | 8 + config.py | 32 + data/.DS_Store | Bin 0 -> 6148 bytes data/equipment_data_20241108.xlsx | Bin 0 -> 20833 bytes data/equipment_data_20241108_training.xlsx | Bin 0 -> 18896 bytes data/equipment_data_20241108_verify.xlsx | Bin 0 -> 15705 bytes docs/debug.md | 616 ++++++++++ docs/design.md | 433 +++++++ docs/nodejs_install.md | 136 ++ docs/requirements.md | 39 + docs/run.md | 163 +++ frontend | 1 + loiteringmunitions.md | 13 + package.json | 12 + requirements.txt | 12 + rocketparameters.md | 29 + run.py | 61 + src/__init__.py | 1 + src/api.py | 68 + src/app.py | 68 + src/cost_prediction.py | 218 ++++ src/create_template.py | 152 +++ src/data_preparation.py | 199 +++ src/database/__init__.py | 1 + src/database/db_connection.py | 28 + src/feature_analysis.py | 266 ++++ src/import_data.py | 259 ++++ src/init_data.sql | 277 +++++ src/model_trainer.py | 398 ++++++ src/pls_regression.py | 313 +++++ src/real_data.sql | 9 + src/routes.py | 1298 ++++++++++++++++++++ src/run.py | 28 + src/schema.sql | 129 ++ src/test_api.py | 192 +++ vite.config.js | 18 + 39 files changed, 5609 insertions(+) create mode 100644 .cursorrules create mode 100644 .gitignore create mode 100644 README.md create mode 100644 app.py create mode 100644 config.py create mode 100644 data/.DS_Store create mode 100644 data/equipment_data_20241108.xlsx create mode 100644 data/equipment_data_20241108_training.xlsx create mode 100644 data/equipment_data_20241108_verify.xlsx create mode 100644 docs/debug.md create mode 100644 docs/design.md create mode 100644 docs/nodejs_install.md create mode 100644 docs/requirements.md create mode 100644 docs/run.md create mode 160000 frontend create mode 100644 loiteringmunitions.md create mode 100644 package.json create mode 100644 requirements.txt create mode 100644 rocketparameters.md create mode 100644 run.py create mode 100644 src/__init__.py create mode 100644 src/api.py create mode 100644 src/app.py create mode 100644 src/cost_prediction.py create mode 100644 src/create_template.py create mode 100644 src/data_preparation.py create mode 100644 src/database/__init__.py create mode 100644 src/database/db_connection.py create mode 100644 src/feature_analysis.py create mode 100644 src/import_data.py create mode 100644 src/init_data.sql create mode 100644 src/model_trainer.py create mode 100644 src/pls_regression.py create mode 100644 src/real_data.sql create mode 100644 src/routes.py create mode 100644 src/run.py create mode 100644 src/schema.sql create mode 100644 src/test_api.py create mode 100644 vite.config.js diff --git a/.cursorrules b/.cursorrules new file mode 100644 index 0000000..f9d19c8 --- /dev/null +++ b/.cursorrules @@ -0,0 +1,82 @@ +# 开发流程 + +First ensure basic functionality works +Implement core functionality using the simplest direct approach +Ensure data flow is working correctly +Verify results are accurate +Then gradually add additional features +Add error handling +Add data validation +Add format conversion +Add logging +Improve user experience +Avoid premature optimization +Don't do complex data validation at the start +Don't worry about performance optimization early +Don't over-engineer +This development flow: +Quickly validates if core functionality works +Identifies and fixes fundamental issues early +Avoids wasting time on unnecessary optimizations +Makes code easier to maintain and debug +These principles should guide all code responses, focusing on getting the basics working first before adding complexity. + +# 代码修改最佳实践 + +1. 修改前的准备 + +- 检查相关文件和依赖关系 +- 确保命名一致性 +- 添加必要的日志记录 +- 准备回滚方案 + +2. 修改过程中 + +- 遵循统一的代码风格 +- 添加适当的错误处理 +- 保持代码的可读性 +- 避免重复代码 + +3. 修改后的验证 + +- 验证主要功能 +- 测试边界条件 +- 检查错误处理 +- 验证性能影响 + +4. 文档更新 + +- 更新相关文档 +- 添加注释说明 +- 记录重要修改 +- 更新调试信息 + +5. 代码审查要点 + +- 检查命名规范 +- 验证错误处理 +- 确认日志完整性 +- 评估代码质量 + +6. 调试建议 + +- 添加详细日志 +- 使用断点调试 +- 验证数据流 +- 检查状态变化 + +7. 性能考虑 + +- 避免过早优化 +- 关注关键路径 +- 合理使用缓存 +- 优化数据库查询 + +8. 安全性检查 + +- 验证输入数据 +- 处理异常情况 +- 保护敏感信息 +- 添加访问控制 + +These practices help maintain code quality and reduce potential issues. diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6e04c50 --- /dev/null +++ b/.gitignore @@ -0,0 +1,27 @@ +.DS_Store +node_modules +/dist +/models +/logs +/uploads +/data + +# local env files +.env.local +.env.*.local + +# Log files +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? +/frontend/node_modules diff --git a/README.md b/README.md new file mode 100644 index 0000000..b04ef07 --- /dev/null +++ b/README.md @@ -0,0 +1,23 @@ +# 数据库配置说明 + +本系统使用 MySQL 8.0+ 作为数据库。在安装 MySQL 后,需要: + +1. 创建数据库用户 + +```sql +CREATE USER 'equipment_user'@'localhost' IDENTIFIED BY 'your_password'; +GRANT ALL PRIVILEGES ON equipment_cost_db.* TO 'equipment_user'@'localhost'; +FLUSH PRIVILEGES; +``` + +2. 配置数据库字符集 +确保 MySQL 配置文件(my.cnf 或 my.ini)包含以下设置: + +```ini +[mysqld] +character-set-server=utf8mb4 +collation-server=utf8mb4_unicode_ci + +[client] +default-character-set=utf8mb4 +``` diff --git a/app.py b/app.py new file mode 100644 index 0000000..da4dbaf --- /dev/null +++ b/app.py @@ -0,0 +1,8 @@ +import logging + +# 配置日志 +logging.basicConfig( + filename='logs/api.log', + level=logging.INFO, + format='%(asctime)s - %(levelname)s - %(message)s' +) \ No newline at end of file diff --git a/config.py b/config.py new file mode 100644 index 0000000..ee008e5 --- /dev/null +++ b/config.py @@ -0,0 +1,32 @@ +import os +import secrets + +# 数据库配置 +DATABASE_URI = "mysql+pymysql://root:123456@localhost:3306/equipment_cost_db" + +# 安全密钥配置(自动生成随机密钥) +SECRET_KEY = secrets.token_hex(16) + +# 环境配置 +DEBUG = True +ENV = 'development' + +# 文件上传配置 +UPLOAD_FOLDER = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'uploads') +ALLOWED_EXTENSIONS = {'csv', 'xlsx', 'xls', 'json'} +MAX_CONTENT_LENGTH = 16 * 1024 * 1024 # 16MB 最大上传限制 + +# API配置 +API_VERSION = 'v1' +API_PREFIX = f'/api/{API_VERSION}' + +# 跨域配置 +CORS_ORIGINS = [ + "http://localhost:8080", + "http://127.0.0.1:8080", +] + +# 日志配置 +LOG_LEVEL = 'DEBUG' +LOG_FORMAT = '%(asctime)s - %(name)s - %(levelname)s - %(message)s' +LOG_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'logs/app.log') \ No newline at end of file diff --git a/data/.DS_Store b/data/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 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�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 SkM$Q=0NF3L+lc+~+y4O%!^JoN literal 0 HcmV?d00001 diff --git a/data/equipment_data_20241108_verify.xlsx b/data/equipment_data_20241108_verify.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..92a527ab11b9d1892f94450104df341139999755 GIT binary patch literal 15705 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 z +``` + +### 最佳实践 + +1. 数据库查询 + +- 使用子查询而不是 JOIN 获取特殊参数 +- 确保返回格式统一 +- 过滤无效数据 + +2. 数据处理 + +- 统一数据格式 +- 处理空值和异常 +- 保持类型一致 + +3. 前端显示 + +- 严格的条件判断 +- 类型检查 +- 格式化显示 + +4. 调试方法 + +- 使用日志跟踪数据流 +- 检查数据格式和类型 +- 验证每个环节的数据 + +## 编辑对话框问题 + +### 问题描述 + +在数据管理页面中,编辑对话框的成本信息分区和特殊参数分区显示不正确。 + +### 调试步骤 + +1. 检查数据流 + +```javascript +console.log('Editing row:', row) +console.log('Edit data response:', response.data) +console.log('Parsed custom params:', data.custom_params) +console.log('Edit form data:', editForm.value) +``` + +2. 检查模板结构 + +```vue + + + + + + +成本信息 + + + +``` + +### 关键发现 + +1. 模板结构问题 + +- el-divider 不应该嵌套在 template 中 +- 每个分区需要独立的 el-form +- 避免不必要的 template 嵌套 + +2. 数据类型问题 + +- 后端返回的数值是字符串类型 +- el-input-number 组件需要数值类型 +- 需要在前端进行类型转换 + +3. 条件渲染问题 + +- v-if 条件过于严格可能导致内容不显示 +- 某些字段应该始终显示 +- 某些字段只在有值时显示 + +### 解决方案 + +1. 修改模板结构 + +```vue + +成本信息 + + + + + +``` + +2. 数据类型转换 + +```javascript +// 转换所有数值类型字段 +Object.keys(data).forEach(key => { + if (isNumberInput(key) && data[key] !== null && data[key] !== undefined) { + data[key] = Number(data[key]) + } +}) +``` + +3. 优化条件渲染 + +```vue + + + + + + + + + +``` + +### 最佳实践 + +1. 模板结构 + +- 保持清晰的分区结构 +- 避免不必要的嵌套 +- 使用合适的组件层级 + +2. 数据处理 + +- 在获取数据后立即进行类型转换 +- 确保数据类型与组件要求匹配 +- 处理好空值和未定义值 + +3. 条件渲染 + +- 合理使用 v-if 和 v-show +- 必要字段始终显示 +- 可选字段根据条件显示 + +4. 调试方法 + +- 使用 console.log 跟踪数据流 +- 检查组件的属性要求 +- 验证数据类型和结构 + +## 特征分析功能问题 + +### 问题描述 + +特征分析页面中,第一次点击分析按钮时,图表不显示,只有标题栏。第二次点击才能正常显示图表。 + +### 调试步骤 + +1. 检查数据流 + +```javascript +console.log('Analysis result:', analysisResult.value) +console.log('Charts not ready:', { + importanceChartRef: !!importanceChartRef.value, + correlationChartRef: !!correlationChartRef.value, + analysisResult: !!analysisResult.value +}) +``` + +2. 检查渲染时机 + +```javascript +// 使用 watch 监听分析结果变化 +watch(() => analysisResult.value, async (newResult) => { + if (newResult) { + await nextTick() + setTimeout(() => { + renderCharts() + }, 100) + } +}, { deep: true }) +``` + +3. 检查图表实例管理 + +```javascript +// 销毁旧的图表实例 +if (importanceChart.value) { + importanceChart.value.dispose() +} +if (correlationChart.value) { + correlationChart.value.dispose() +} +``` + +### 关键发现 + +1. 渲染时机问题 + +- DOM 元素可能还未准备好 +- 数据更新后需要等待 DOM 更新 +- 需要正确管理图表实例 + +2. 图表实例管理 + +- 需要保存图表实例的引用 +- 重新渲染前需要销毁旧实例 +- 组件卸载时需要清理实例 + +3. 数据格式问题 + +- 特征名称需要中文映射 +- 相关性数据需要保留2位小数 +- 需要正确处理缺失值 + +### 解决方案 + +1. 优化渲染逻辑 + +```javascript +// 使用 nextTick 和延时确保 DOM 已更新 +await nextTick() +setTimeout(() => { + renderCharts() +}, 100) +``` + +2. 完善图表实例管理 + +```javascript +// 保存图表实例的引用 +const importanceChart = ref(null) +const correlationChart = ref(null) + +// 组件卸载时清理 +onUnmounted(() => { + importanceChart.value?.dispose() + correlationChart.value?.dispose() +}) +``` + +3. 优化数据处理 + +```javascript +// 使用中文特征名 +chinese_feature_names = [self.feature_names_map.get(name, name) for name in feature_names] + +// 保留2位小数 +correlation_data.append([ + i, j, + round(correlation_matrix[i][j], 2) +]) +``` + +### 最佳实践 + +1. 渲染控制 + +- 使用 watch 监听数据变化 +- 使用 nextTick 等待 DOM 更新 +- 添加适当的延时确保渲染 + +2. 实例管理 + +- 保存图表实例引用 +- 及时销毁旧实例 +- 组件卸载时清理 + +3. 数据处理 + +- 统一使用中文特征名 +- 控制数值精度 +- 处理好缺失值 + +4. 调试方法 + +- 添加详细的日志记录 +- 检查 DOM 元素状态 +- 验证数据格式 + +## 页面状态保持问题 + +### 问题描述 + +特征分析���面切换到其他页面后再返回,页面状态(分析结果和图表)会丢失,需要重新分析。 + +### 调试步骤 + +1. 检查路由配置 + +```javascript +// 错误的配置 + + + + +// 正确的配置 + + + + + +``` + +2. 检查组件定义 + +```javascript +// 错误的组件名称定义 +