Browse Source

修改界面,实现两种模型的计算。

yangtaodemon 5 months ago
parent
commit
29038326f4

+ 3 - 2
api/app/model.py

@@ -3,13 +3,14 @@ import pandas as pd
 
 
 # 加载模型
-def load_model(model_name='RF_filt'):
+def load_model(model_name):
     file_path = f'model_optimize/pkl/{model_name}.pkl'
     with open(file_path, 'rb') as f:
         return pickle.load(f)
 
+
 # 模型预测
-def predict(input_data: pd.DataFrame, model_name='RF_filt'):
+def predict(input_data: pd.DataFrame, model_name):
     # 初始化模型
     model = load_model(model_name)  # 根据指定的模型名加载模型
     predictions = model.predict(input_data)

+ 7 - 6
api/app/routes.py

@@ -1,19 +1,20 @@
 import sqlite3
 
+from flask_sqlalchemy import SQLAlchemy
 from flask import Blueprint, request, jsonify, g, current_app
 from .model import predict
 import pandas as pd
-from flask_sqlalchemy import SQLAlchemy
+
 
 # 创建蓝图 (Blueprint),用于分离路由
 bp = Blueprint('routes', __name__)
+DATABASE = 'SoilAcidification.db'
+
 
 def get_db():
     db = getattr(g, '_database', None)
     if db is None:
-        # database_url = current_app.config['DATABASE']
-        # db = g._database = sqlite3.connect(database_url)
-        db = SQLAlchemy(current_app)
+        db = g._database = sqlite3.connect(DATABASE)
     return db
 
 
@@ -21,16 +22,16 @@ def get_db():
 def predict_route():
     try:
         data = request.get_json()
-        model_name = data.get('model_name', 'RF_filt')  # 提取模型名称
+        model_name = data.get('model_name')  # 提取模型名称
         parameters = data.get('parameters', {})  # 提取所有参数
 
         input_data = pd.DataFrame([parameters])  # 转换参数为DataFrame
         predictions = predict(input_data, model_name)  # 调用预测函数
-
         return jsonify({'predictions': predictions}), 200
     except Exception as e:
         return jsonify({'error': str(e)}), 400
 
+
 # 定义添加数据库记录的 API 接口
 @bp.route('/add_item', methods=['POST'])
 def add_item():

+ 1 - 1
api/run.py

@@ -1,5 +1,5 @@
 from app import create_app
-
+import os
 # 创建 Flask 应用
 app = create_app()
 

+ 61 - 20
pages/AcidNeutralizationModel/AcidNeutralizationModel.js

@@ -1,34 +1,75 @@
-// pages/Calculation/Calculation.js
 Page({
   data: {
-    // 数据绑定
-    initialPH: '', // 土壤初始 pH
-    targetPH: '', // 土壤目标 pH
-    materials: ['石灰石(粉)CaCO3', '生石灰(粉)', '纯CaO (粉)', '熟石灰(粉)', '白云石 (粉)', '硅钙钾镁肥', '其他含CaO和MgO材料'],
-    selectedMaterialIndex: 0, // 默认选中的碱性物料索引
-    selectedMaterial: '石灰石(粉)CaCO3', // 默认物料
+    OM: '', // 有机质含量
+    CL: '', // 土壤粘粒重量
+    H: '', // 氢离子含量
+    Al: '', // 铝离子含量
+    ph: '',
   },
 
-  // 处理土壤初始 pH 的输入
-  onInitialPHChange(e) {
+  // 更新有机质含量
+  onOMChange: function(e) {
     this.setData({
-      initialPH: e.detail.value,
+      OM: e.detail.value
     });
   },
-
-  // 处理土壤目标 pH 的输入
-  onTargetPHChange(e) {
+  
+  // 更新土壤粘粒重量
+  onCLChange: function(e) {
     this.setData({
-      targetPH: e.detail.value,
+      CL: e.detail.value
     });
   },
-
-  // 处理碱性物料选择
-  onSelectMaterial(e) {
-    const index = e.detail.value;
+  
+  // 更新氢离子含量
+  onHChange: function(e) {
+    this.setData({
+      H: e.detail.value
+    });
+  },
+  
+  // 更新铝离子含量
+  onAlChange: function(e) {
     this.setData({
-      selectedMaterialIndex: index,
-      selectedMaterial: this.data.materials[index],
+      Al: e.detail.value
+    });
+  },
+  
+  onPhChange: function(e) {
+    this.setData({
+      ph: e.detail.value
+    });
+  },
+
+  // 计算方法
+  calculate: function() {
+    console.log('开始计算...');
+    const data = {
+      model_name: "rf_model_1214_1008",
+      parameters: {
+        pH: this.data.ph,
+        OM: this.data.OM,
+        CL: this.data.CL,
+        H: this.data.H,
+        Al: this.data.Al,
+      },
+    };
+    wx.request({
+      url: 'http://localhost:5000/predict',
+      method: 'POST',
+      data: JSON.stringify(data),
+      header: {
+        'content-type': 'application/json' 
+      },
+      success: (res) => {
+        console.log('预测结果:', res.data.predictions);
+        wx.navigateTo({
+          url: `/pages/Result/Result?result=${encodeURIComponent(JSON.stringify(res.data.predictions))}`
+        });
+      },
+      fail: (error) => {
+        console.error('请求失败:', error);
+      }
     });
   }
 });

+ 32 - 33
pages/AcidNeutralizationModel/AcidNeutralizationModel.wxml

@@ -1,66 +1,65 @@
-<!-- pages/Calculation/Calculation.wxml -->
 <view class="page-body">
   <view class="white-box">
-    <view class="page-section-title">土地质地:</view>
-    <radio-group name="soilType" bindchange="onSoilTypeChange" class="radio-group">
-      <label class="radio">
-        <radio value="r1" /> <text class="radio-text">壤土/黏质土</text>
-      </label>
-      <label class="radio">
-        <radio value="r2" /> <text class="radio-text">砂质土</text>
-      </label>
-    </radio-group>
+    <view class="page-section-title">土壤 pH:</view>
+    <input 
+      class="input-field" 
+      type="text" 
+      placeholder="请输入土壤pH" 
+      value="{{ph}}" 
+      bindinput="onPhChange" 
+    />
   </view>
 </view>
 
 <view class="page-body">
   <view class="white-box">
-    <view class="page-section-title">有机质含量:</view>
-    <radio-group name="soilType" bindchange="onSoilTypeChange" class="radio-group">
-      <label class="radio">
-        <radio value="r3" />大于3%
-      </label>
-      <label class="radio">
-        <radio value="r4" />小于等于3%
-      </label>
-    </radio-group>
+    <view class="page-section-title">有机质含量 (OM g/kg):</view>
+    <input 
+      class="input-field" 
+      type="text" 
+      placeholder="请输入OM含量" 
+      value="{{OM}}" 
+      bindinput="onOMChange" 
+    />
   </view>
 </view>
 
 <view class="page-body">
   <view class="white-box">
-    <view class="page-section-title">土壤初始 pH:</view>
+    <view class="page-section-title">土壤粘粒重量 (CL g/kg):</view>
     <input 
       class="input-field" 
       type="text" 
-      placeholder="4.5~6.2" 
-      value="{{initialPH}}" 
-      bindinput="onInitialPHChange" 
+      placeholder="请输入CL含量" 
+      value="{{CL}}" 
+      bindinput="onCLChange" 
     />
   </view>
 </view>
 
 <view class="page-body">
   <view class="white-box">
-    <view class="page-section-title">土壤目标 pH:</view>
+    <view class="page-section-title">氢离子含量 (H cmol/kg):</view>
     <input 
       class="input-field" 
       type="text" 
-      placeholder="4.5~7.0" 
-      value="{{targetPH}}" 
-      bindinput="onTargetPHChange" 
+      placeholder="请输入H含量" 
+      value="{{H}}" 
+      bindinput="onHChange" 
     />
   </view>
 </view>
 
 <view class="page-body">
   <view class="white-box">
-    <view class="page-section-title">碱性物料:</view>
-    <picker mode="selector" range="{{materials}}" value="{{selectedMaterialIndex}}" bindchange="onSelectMaterial">
-      <view class="input-field bold-text">
-        {{selectedMaterial || '石灰石(粉)CaCO3'}}
-      </view>
-    </picker>
+    <view class="page-section-title">铝离子含量 (Al cmol/kg):</view>
+    <input 
+      class="input-field" 
+      type="text" 
+      placeholder="请输入Al3+含量" 
+      value="{{Al}}" 
+      bindinput="onAlChange" 
+    />
   </view>
 </view>
 

+ 15 - 21
pages/Calculation/Calculation.js

@@ -8,8 +8,7 @@ Page({
     Al: '', // 铝离子含量
     free_alumina: '', // 游离氧化铝含量
     free_iron_oxides: '', // 游离氧化铁含量
-    collection_location: '', // 采样地点
-    collection_date: '', // 采样时间
+    delta_ph: '',
   },
 
   // 更新有机质含量
@@ -68,17 +67,9 @@ Page({
     });
   },
   
-  // 更新采样地点
-  onCollectionLocationChange: function(e) {
+  onDeltaPhChange: function(e) {
     this.setData({
-      collection_location: e.detail.value
-    });
-  },
-  
-  // 更新采样时间
-  onBindDateChange: function(e) {
-    this.setData({
-      collection_date: e.detail.value
+      delta_ph: e.detail.value
     });
   },
 
@@ -86,15 +77,18 @@ Page({
   calculate: function() {
     console.log('开始计算...');
     const data = {
-      organic_matter: this.data.OM,
-      chloride: this.data.CL,
-      cec: this.data.CEC,
-      h_concentration: this.data.H,
-      hn: this.data.HN,
-      al_concentration: this.data.Al,
-      free_alumina: this.data.free_alumina,
-      free_iron: this.data.free_iron_oxides,
-      delta_ph: 4.5,
+      model_name: "RF_filt",
+      parameters: {
+        organic_matter: this.data.OM,
+        chloride: this.data.CL,
+        cec: this.data.CEC,
+        h_concentration: this.data.H,
+        hn: this.data.HN,
+        al_concentration: this.data.Al,
+        free_alumina: this.data.free_alumina,
+        free_iron: this.data.free_iron_oxides,
+        delta_ph: this.data.delta_ph,
+      },
     };
     wx.request({
       url: 'http://localhost:5000/predict',

+ 4 - 15
pages/Calculation/Calculation.wxml

@@ -105,28 +105,17 @@
 
 <view class="page-body">
   <view class="white-box">
-    <view class="page-section-title">采样地点:</view>
+    <view class="page-section-title">pH差值:</view>
     <input 
       class="input-field" 
       type="text" 
-      placeholder="请输入采样地点" 
-      value="{{collection_location}}" 
-      bindinput="onCollectionLocationChange" 
+      placeholder="请输入pH差值" 
+      value="{{delta_ph}}" 
+      bindinput="onDeltaPhChange" 
     />
   </view>
 </view>
 
-<view class="page-body">
-  <view class="white-box">
-    <picker mode="date" value="{{collection_date}}" bindchange="onBindDateChange">
-      <view class="picker-container">
-        <text class="page-section-title">采样时间:</text>
-        <text class="color6">{{collection_date || '请选择日期'}}</text>
-      </view>
-    </picker>
-  </view>
-</view>
-
 <view class="green-btn">
   <button class="btn" bindtap="calculate">计算</button>
 </view>

+ 3 - 4
pages/Result/Result.wxml

@@ -1,8 +1,7 @@
+<page-meta>
+  <navigation-bar title="结果" back="{{true}}" color="black" background="#FFF"></navigation-bar>
+</page-meta>
 <view class="container">
-  <page-meta>
-    <navigation-bar title="结果" back="{{true}}" color="black" background="#FFF"></navigation-bar>
-  </page-meta>
-  
   <view class="page-body">
     <view class="result-container">
       <view class="result-title">计算结果</view>

+ 83 - 14
pages/Visualization/Visualization.wxss

@@ -109,27 +109,28 @@
 
 /* 模态框背景 */
 .modal {
-  position: fixed; /* 固定定位,始终在屏幕中央 */
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 0;
   display: flex;
   justify-content: center;
   align-items: center;
-  background-color: rgba(0, 0, 0, 0.6); /* 半透明背景色,增加一点深度感 */
-  z-index: 1000; /* 提高层级,确保模态框在其他元素之上 */
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background-color: rgba(0, 0, 0, 0.5); /* 半透明背景 */
+  z-index: 1000; /* 确保弹窗在最上层 */
 }
 
 /* 模态框内容 */
 .modal-content {
-  background-color: #fff; /* 模态框内容背景为白色 */
-  border-radius: 16px; /* 圆角 */
-  width: 80%; /* 宽度占80% */
-  max-width: 500rpx; /* 最大宽度限制 */
-  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.1); /* 添加阴影效果,增加浮动感 */
-  padding: 20rpx; /* 内边距 */
-  transition: transform 0.3s ease-out; /* 平滑的动画过渡 */
+  background-color: #fff; /* 白色背景 */
+  padding: 20px;
+  border-radius: 8px;
+  width: 90%;
+  max-width: 400px; /* 最大宽度 */
+  max-height: 80vh; /* 最大高度,留出一些空间以便滚动条显示 */
+  overflow-y: auto; /* 垂直方向溢出时显示滚动条 */
+  overflow-x: hidden; /* 隐藏水平滚动条 */
 }
 
 /* 每个选项项 */
@@ -210,4 +211,72 @@
 .picker {
   flex-shrink: 0;
   width: 100px; /* 根据需要调整宽度 */
+}
+
+/* 选择器容器样式 */
+.picker-container {
+  display: flex;
+  align-items: center;
+  margin-bottom: 15px;
+}
+
+/* 选择器文本样式 */
+.picker-container text {
+  margin-right: 10px;
+}
+
+/* 按钮悬停效果 */
+.submit-btn:hover,
+.cancel-btn:hover {
+  opacity: 0.8;
+}
+
+/* 输入字段样式 */
+.input-field {
+  width: 100%;
+  padding: 10rpx;
+  font-size: 28rpx;
+  color: #333;
+  border: none;
+  border-bottom: 1px solid #ddd;
+}
+
+/* 输入字段聚焦时的样式 */
+.input-field:focus {
+  border-color: #007bff; /* 聚焦时边框颜色 */
+  outline: none; /* 去除默认的聚焦轮廓 */
+  box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); /* 聚焦时的阴影效果 */
+}
+
+/* 输入字段禁用时的样式 */
+.input-field:disabled {
+  background-color: #e9ecef; /* 背景色 */
+  opacity: 0.65; /* 不透明度 */
+  cursor: not-allowed; /* 禁用时的鼠标样式 */
+}
+
+/* 输入字段的占位符样式 */
+.input-field::placeholder {
+  color: #6c757d; /* 占位符文本颜色 */
+  font-style: italic; /* 斜体 */
+}
+
+/* 输入字段的动画效果 */
+.input-field:active, .input-field:focus {
+  transition: all 0.15s ease-in-out;
+}
+
+/* 输入字段的响应式设计 */
+@media (max-width: 768px) {
+  .input-field {
+    font-size: 14px; /* 在小屏幕上减小字体大小 */
+  }
+}
+
+/* 页面标题样式 */
+.page-section-title {
+  font-size: 30rpx;
+  font-weight: bold;
+  color: #333;
+  margin-bottom: 10rpx;
 }