Sfoglia il codice sorgente

实现数据库的交互操作

yangtaodemon 5 mesi fa
parent
commit
443e4cfe89

BIN
SoilAcidification.db → api/SoilAcidification.db


+ 1 - 1
api/api_db.py

@@ -92,7 +92,7 @@ def add_item():
 
 
 # 定义删除数据库记录的 API 接口
-@app.route('/delete_item', methods=['DELETE'])
+@app.route('/delete_item', methods=['POST'])
 def delete_item():
     data = request.get_json()
     table_name = data.get('table')

+ 4 - 0
api/app/model.py

@@ -1,20 +1,24 @@
 import pickle
 import pandas as pd
 
+
 # 加载模型
 def load_model():
     with open('model_optimize/pkl/RF_filt.pkl', 'rb') as f:
         return pickle.load(f)
 
+
 # 初始化模型
 model = load_model()   # 模型会在model.py被导入时加载一次
 
+
 # 预测函数
 def predict(input_data: pd.DataFrame):
     # 假设输入数据已经准备好
     predictions = model.predict(input_data)
     return predictions.tolist()
 
+
 if __name__ == '__main__':
     # 测试 predict 函数
     x = pd.DataFrame([{

+ 0 - 1
pages/Calculation/Calculation.js

@@ -1,4 +1,3 @@
-// pages/Calculation/Calculation.js
 Page({
   data: {
     OM: '', // 有机质含量

+ 1 - 1
pages/Calculation/Calculation.wxml

@@ -118,7 +118,7 @@
 
 <view class="page-body">
   <view class="white-box">
-    <picker mode="date" header-text="选择时间" value="{{collection_date}}" bindchange="onBindDateChange">
+    <picker mode="date" value="{{collection_date}}" bindchange="onBindDateChange">
       <view class="picker-container">
         <text class="page-section-title">采样时间:</text>
         <text class="color6">{{collection_date || '请选择日期'}}</text>

+ 171 - 99
pages/Visualization/Visualization.js

@@ -1,5 +1,6 @@
 Page({
   data: {
+    isEditing: false,
     shoopingtext: "", // 搜索框内容
     filteredRows: [], // 表格过滤后的数据
     rows: [], // 所有表格数据
@@ -8,21 +9,28 @@ Page({
     currentRow: null, // 当前选中的表格行
     // 新增数据弹窗的输入框内容
     newData: {
+      Sample_ID: "",
       OM: "",
       CL: "",
       CEC: "",
-      Hplus: "",
+      H: "",
       HN: "",
-      Al3plus: "",
-      Alumina: "",
-      IronOxides: "",
-      DeltaPH: "",
-      Day0PH: ""
+      Al: "",
+      free_alumina: "",
+      free_iron_oxides: "",
+      pH: "",
+      final_pH: "",
+      Collection_location: "",
+      Collection_date: ""
     }
   },
 
   // 页面加载时获取表格数据
   onLoad: function() {
+    this.LoadData();
+  },  
+
+  LoadData: function() {
     wx.request({
       url: 'http://localhost:5000/tables',
       method: 'POST',
@@ -31,49 +39,49 @@ Page({
       },
       data: {
         table: 'Soil_samples'
-      },
-      success: (res) => {
-        console.log('后端返回数据:', res.data.rows); // 打印返回数据,确认格式
-        
-        if (res.data && Array.isArray(res.data.rows)) {
-          const rows = res.data.rows.map(row => {
-            return {
-              '0 day pH': row[0],
-              'OM g/kg': row[1],
-              'CL g/kg': row[2],
-              'CEC cmol/kg': row[3],
-              'H+ cmol/kg': row[4],
-              'HN mg/kg': row[5],
-              'Al3plus': row[6],
-              'Free alumina g/kg': row[7],
-              'Free iron oxides g/kg': row[8],
-              '105 day pH': row[9],
-              'Collection location': row[10],
-              'Collection Date': row[11]
-            };
-          });
-  
-          this.setData({
-            rows: rows,
-            filteredRows: rows
-          });
-        } else {
-          wx.showToast({
-            title: '获取数据失败',
-            icon: 'none'
-          });
-        }
-      },
-      fail: (err) => {
+    },
+    success: (res) => {
+      console.log('后端返回数据:', res.data.rows); // 打印返回数据,确认格式
+      
+      if (res.data && Array.isArray(res.data.rows)) {
+        const rows = res.data.rows.map(row => {
+          return {
+            'Sample_ID': row[0],
+            'pH': row[1],
+            'OM': row[2],
+            'CL': row[3],
+            'CEC': row[4],
+            'H': row[5],
+            'HN': row[6],
+            'Al': row[7],
+            'free_alumina': row[8],
+            'free_iron_oxides': row[9],
+            'final_pH': row[10],
+            'Collection_location': row[11],
+            'Collection_date': row[12]
+          };
+        });
+
+        this.setData({
+          rows: rows,
+          filteredRows: rows
+        });
+      } else {
         wx.showToast({
-          title: '请求失败,请重试',
+          title: '获取数据失败',
           icon: 'none'
         });
-        console.error('请求失败:', err);
       }
+    },
+    fail: (err) => {
+      wx.showToast({
+        title: '请求失败,请重试',
+        icon: 'none'
+      });
+      console.error('请求失败:', err);
+    }
     });
-  },  
-
+  },
   // 搜索框绑定
   shoppinginput: function(e) {
     this.setData({
@@ -103,13 +111,15 @@ Page({
         OM: "",
         CL: "",
         CEC: "",
-        Hplus: "",
+        H: "",
         HN: "",
-        Al3plus: "",
-        Alumina: "",
-        IronOxides: "",
-        DeltaPH: "",
-        Day0PH: ""
+        Al: "",
+        free_alumina: "",
+        free_iron_oxides: "",
+        pH: "",
+        final_pH: "",
+        Collection_location: "",
+        Collection_date: ""
       }
     });
     console.log("showAddModal: ", this.data.showAddModal);  // 确认数据更新
@@ -133,7 +143,7 @@ Page({
   },
   onInputHplus: function(e) {
     this.setData({
-      'newData.Hplus': e.detail.value
+      'newData.H': e.detail.value
     });
   },
   onInputHN: function(e) {
@@ -143,27 +153,37 @@ Page({
   },
   onInputAl3plus: function(e) {
     this.setData({
-      'newData.Al3plus': e.detail.value
+      'newData.Al': e.detail.value
     });
   },
   onInputAlumina: function(e) {
     this.setData({
-      'newData.Alumina': e.detail.value
+      'newData.free_alumina': e.detail.value
     });
   },
   onInputIronOxides: function(e) {
     this.setData({
-      'newData.IronOxides': e.detail.value
+      'newData.free_iron_oxides': e.detail.value
+    });
+  },
+  onInputinitPH: function(e) {
+    this.setData({
+      'newData.pH': e.detail.value
+    });
+  },
+  onInputfinalPH: function(e) {
+    this.setData({
+      'newData.final_pH': e.detail.value
     });
   },
-  onInputDeltaPH: function(e) {
+  onInputlocation: function(e) {
     this.setData({
-      'newData.DeltaPH': e.detail.value
+      'newData.Collection_location': e.detail.value
     });
   },
-  onInputDay0PH: function(e) {
+  onBindDateChange: function(e) {
     this.setData({
-      'newData.Day0PH': e.detail.value
+      'newData.Collection_date': e.detail.value
     });
   },
 
@@ -198,6 +218,7 @@ Page({
             title: '新增成功',
             icon: 'success'
           });
+          this.LoadData();
         } else {
           wx.showToast({
             title: '新增失败',
@@ -216,59 +237,97 @@ Page({
   },
 
   // 取消新增数据
-  onCancelAdd: function() {
+  onCancel: function() {
     this.setData({
       showAddModal: false
     });
   },
 
   // 编辑按钮点击
-  onEdit: function() {
-    const updatedRow = this.data.currentRow.row;  // 获取当前编辑的行数据
-    wx.request({
-      url: `http://127.0.0.1:5000/delete_item?${condition}`,
-      method: 'DELETE',
-      header: {
-        'Content-Type': 'application/json'
-      },
-      success: (res) => {
-        console.log('响应数据:', res);  // 输出响应数据,检查服务器返回的内容
-        if (res.data.success) {
-          let rows = [...this.data.rows];
-          rows.splice(index, 1);  // 删除选中的行
-          this.setData({
-            rows: rows,
-            showModal: false
-          });
-          wx.showToast({
-            title: '删除成功',
-            icon: 'success'
-          });
-        } else {
-          wx.showToast({
-            title: '删除失败',
-            icon: 'none'
-          });
-        }
-      },
-      fail: (err) => {
-        console.error('请求失败:', err);
+onEdit: function(e) {
+  const { index, row } = this.data.currentRow;
+  console.log(row);
+
+  // 检查 currentRow 是否有定义并且包含数据
+  if (row) {
+    this.setData({
+      isEditing: true,
+      showModal: false,
+      showAddModal: true, // 显示编辑弹窗
+      newData: row, // 将当前行的数据复制到 newData 中,以便在表单中显示
+      currentRow: { index: index, row: row } // 保存当前行的信息,以便在提交时使用
+    });
+  } else {
+    wx.showToast({
+      title: '数据加载失败,请重试',
+      icon: 'none'
+    });
+  }
+},
+
+  // 提交编辑数据
+onSubmitEdit: function() {
+  const updatedRow = this.data.newData;
+  const { index } = this.data.currentRow;
+
+  if (Object.values(updatedRow).some(value => !value)) {
+    wx.showToast({
+      title: '所有字段都必须填写!',
+      icon: 'none'
+    });
+    return;
+  }
+
+  wx.request({
+    url: 'http://localhost:5000/update_item',
+    method: 'PUT',
+    header: {
+      'Content-Type': 'application/json'
+    },
+    data: {
+      table: 'Soil_samples',
+      item: updatedRow
+    },
+    success: (res) => {
+      if (res.data.success) {
+        // 更新成功后,更新前端数据
+        let rows = this.data.rows;
+        rows[index] = updatedRow; // 用更新后的数据替换旧数据
+        this.setData({
+          rows: rows,
+          showAddModal: false // 关闭编辑弹窗
+        });
         wx.showToast({
-          title: '请求失败,请重试',
+          title: '编辑成功',
+          icon: 'success'
+        });
+        this.LoadData();
+      } else {
+        wx.showToast({
+          title: '编辑失败',
           icon: 'none'
         });
       }
-    });    
-  },
+    },
+    fail: (err) => {
+      wx.showToast({
+        title: '请求失败,请重试',
+        icon: 'none'
+      });
+      console.error('请求失败:', err);
+    }
+  });
+},
 
   // 删除按钮点击
   onDelete: function() {
     const { index, row } = this.data.currentRow;
-    const condition = `id=${row.id}`;
+    console.log(this.data.currentRow);
+    const condition = `Sample_ID=${row.Sample_ID}`;
 
     wx.request({
       url: 'http://127.0.0.1:5000/delete_item',
-      method: 'DELETE',
+      method: 'POST',
       header: {
         'Content-Type': 'application/json'
       },
@@ -278,7 +337,7 @@ Page({
       },
       success: (res) => {
         if (res.data.success) {
-          let rows = [...this.data.rows];
+          let rows = this.data.rows;
           rows.splice(index, 1);  // 删除选中的行
           this.setData({
             rows: rows,
@@ -288,6 +347,7 @@ Page({
             title: '删除成功',
             icon: 'success'
           });
+          this.LoadData();
         } else {
           wx.showToast({
             title: '删除失败',
@@ -304,12 +364,24 @@ Page({
       }
     });
   },
-
+  onSubmit: function() {
+    if (this.data.isEditing) {
+      this.onSubmitEdit();
+    } else {
+      this.onSubmitAdd();
+    }
+  },
   // 取消编辑删除弹窗
   onCancel: function() {
-    this.setData({
-      showModal: false
-    });
+    if (this.data.showModal) {
+      this.setData({
+        showModal: false
+      });
+    } else {
+      this.setData({
+        showAddModal: false
+      });
+    }
   },
 
   // 行点击事件:显示编辑和删除弹窗

+ 40 - 28
pages/Visualization/Visualization.wxml

@@ -20,7 +20,6 @@
   <view class="table">
     <view class="table-header">
       <view class="table-cell">序号</view>
-      <view class="table-cell">0 day pH</view>
       <view class="table-cell">有机质含量</view>
       <view class="table-cell">土壤粘粒重量</view>
       <view class="table-cell">阳离子交换量</view>
@@ -29,6 +28,7 @@
       <view class="table-cell">铝离子含量</view>
       <view class="table-cell">游离氧化铝</view>
       <view class="table-cell">游离氧化铁</view>
+      <view class="table-cell">0 day pH</view>
       <view class="table-cell">105 day pH</view>
       <view class="table-cell">采集位置</view>
       <view class="table-cell">采集日期</view>
@@ -44,18 +44,19 @@
     <scroll-view wx:else scroll-y="true" class="table-body">
       <block wx:for="{{filteredRows}}" wx:key="index">
         <view class="table-row" bindtap="onRowClick" data-index="{{index}}" data-row="{{item}}">
-          <view class="table-cell">{{item['0 day pH']}}</view>
-          <view class="table-cell">{{item['OM g/kg']}}</view>
-          <view class="table-cell">{{item['CL g/kg']}}</view>
-          <view class="table-cell">{{item['CEC cmol/kg']}}</view>
-          <view class="table-cell">{{item['H+ cmol/kg']}}</view>
-          <view class="table-cell">{{item['HN mg/kg']}}</view>
-          <view class="table-cell">{{item['Al3plus']}}</view>
-          <view class="table-cell">{{item['Free alumina g/kg']}}</view>
-          <view class="table-cell">{{item['Free iron oxides g/kg']}}</view>
-          <view class="table-cell">{{item['105 day pH']}}</view>
-          <view class="table-cell">{{item['Collection location']}}</view>
-          <view class="table-cell">{{item['Collection Date']}}</view>
+          <view class="table-cell">{{item['Sample_ID']}}</view>
+          <view class="table-cell">{{item['pH']}}</view>
+          <view class="table-cell">{{item['OM']}}</view>
+          <view class="table-cell">{{item['CL']}}</view>
+          <view class="table-cell">{{item['CEC']}}</view>
+          <view class="table-cell">{{item['H']}}</view>
+          <view class="table-cell">{{item['HN']}}</view>
+          <view class="table-cell">{{item['Al']}}</view>
+          <view class="table-cell">{{item['free_alumina']}}</view>
+          <view class="table-cell">{{item['free_iron_oxides']}}</view>
+          <view class="table-cell">{{item['final_pH']}}</view>
+          <view class="table-cell">{{item['Collection_location']}}</view>
+          <view class="table-cell">{{item['Collection_date']}}</view>
         </view>
       </block>
     </scroll-view>
@@ -65,27 +66,38 @@
 <!-- 新增数据弹窗 -->
 <view class="modal" wx:if="{{showAddModal}}">
   <view class="modal-content">
-    <view class="page-section-title">游离氧化铁 (free iron oxides g/kg):</view>
-    <input 
-      class="input-field" 
-      type="text" 
-      placeholder="请输入游离氧化铁含量" 
-      data-field="IronOxides" 
-      bindinput="onInputChange" 
-    />
-
     <view class="page-section-title">有机质含量 (OM g/kg):</view>
-    <input class="input-field" placeholder="请输入OM含量" data-field="OM" bindinput="onInputChange" />
+    <input class="input-field" placeholder="请输入OM含量" data-field="OM" bindinput="onInputOM" value="{{newData.OM}}"/>
     <view class="page-section-title">土壤粘粒重量 (CL g/kg):</view>
-    <input class="input-field" placeholder="请输入CL含量" data-field="CL" bindinput="onInputChange" />
+    <input class="input-field" placeholder="请输入CL含量" data-field="CL" bindinput="onInputCL" value="{{newData.CL}}"/>
     <view class="page-section-title">阳离子交换量 (CEC cmol/kg):</view>
-    <input class="input-field" placeholder="请输入CEC含量" data-field="CEC" bindinput="onInputChange" />
+    <input class="input-field" placeholder="请输入CEC含量" data-field="CEC" bindinput="onInputCEC" value="{{newData.CEC}}"/>
     <view class="page-section-title">氢离子含量 (H+ cmol/kg):</view>
-    <input class="input-field" placeholder="请输入H+含量" data-field="Hplus" bindinput="onInputChange" />
+    <input class="input-field" placeholder="请输入H+含量" data-field="H" bindinput="onInputHplus" value="{{newData.H}}"/>
+    <view class="page-section-title">铵离子含量 (HN cmol/kg):</view>
+    <input class="input-field" placeholder="请输入HN含量" data-field="HN" bindinput="onInputHN" value="{{newData.HN}}"/>
+    <view class="page-section-title">铝离子含量 (Al3+ cmol/kg):</view>
+    <input class="input-field" placeholder="请输入Al3+含量" data-field="Al" bindinput="onInputAl3plus" value="{{newData.Al}}"/>
+    <view class="page-section-title">游离氧化铝 (free alumina g/kg):</view>
+    <input class="input-field" placeholder="请输入游离氧化铝含量" data-field="free_alumina" bindinput="onInputAlumina" value="{{newData.free_alumina}}"/>
+    <view class="page-section-title">游离氧化铁 (free iron oxides g/kg):</view>
+    <input class="input-field" placeholder="请输入游离氧化铁含量" data-field="free_iron_oxides" bindinput="onInputIronOxides"value="{{newData.free_iron_oxides}}" />
+    <view class="page-section-title">0 day pH:</view>
+    <input class="input-field" placeholder="请输入0 day pH" data-field="pH" bindinput="onInputinitPH" value="{{newData.pH}}"/>
+    <view class="page-section-title">105 day pH:</view>
+    <input class="input-field" placeholder="请输入105 day pH" data-field="final_pH" bindinput="onInputfinalPH"value="{{newData.final_pH}}" />
+    <view class="page-section-title">采样地点: </view>
+    <input class="input-field" placeholder="请输入采样地点" data-field="collection_location" bindinput="onInputlocation" value="{{newData.Collection_location}}"/>
+    <picker mode="date"value="{{newData.Collection_date}}" bindchange="onBindDateChange">
+      <view class="picker-container">
+        <text class="page-section-title">采样时间:</text>
+        <text class="color6">{{newData.Collection_date || '请选择日期'}}</text>
+      </view>
+    </picker>
 
     <view class="button-container">
-      <button class="submit-btn" bindtap="onSubmitAdd">提交</button>
-      <button class="cancel-btn" bindtap="onCancelAdd">取消</button>
+      <button class="submit-btn" bindtap="onSubmit">确认</button>
+      <button class="cancel-btn" bindtap="onCancel">取消</button>
     </view>
   </view>
 </view>

+ 10 - 0
pages/Visualization/Visualization.wxss

@@ -201,3 +201,13 @@
   flex: 1; /* 使按钮宽度相等 */
   margin: 0 10rpx; /* 按钮间隔 */
 }
+.picker-placeholder {
+  flex-grow: 1;
+  color: #888;
+  margin-right: 10px;
+}
+
+.picker {
+  flex-shrink: 0;
+  width: 100px; /* 根据需要调整宽度 */
+}

+ 1 - 1
project.config.json

@@ -1,5 +1,5 @@
 {
-  "appid": "wxc75e060d54a6f54c",
+  "appid": "wxa4088d00b5849cba",
   "compileType": "miniprogram",
   "libVersion": "trial",
   "packOptions": {