Quellcode durchsuchen

1.增加农事活动相关页面;2.完善个人主页中农业服务模块

jiuling vor 11 Monaten
Ursprung
Commit
c63c9c7236
54 geänderte Dateien mit 8794 neuen und 128 gelöschten Zeilen
  1. 114 1
      pages.json
  2. 7 6
      pages/about/index.vue
  3. 1226 0
      pages/activity/activity-detail.vue
  4. 721 5
      pages/activity/index.vue
  5. 2 2
      pages/device/device-list/detail-camera.vue
  6. 4 2
      pages/privacy/index.vue
  7. 434 0
      pages/service/certification.vue
  8. 654 0
      pages/service/expert-chat.vue
  9. 368 0
      pages/service/expert-detail.vue
  10. 401 0
      pages/service/expert.vue
  11. 473 0
      pages/service/insurance.vue
  12. 485 0
      pages/service/mall-detail.vue
  13. 419 0
      pages/service/mall.vue
  14. 647 0
      pages/service/my-publish.vue
  15. 710 0
      pages/service/purchase-publish.vue
  16. 630 0
      pages/service/sales-detail.vue
  17. 751 0
      pages/service/sales-publish.vue
  18. 540 0
      pages/service/sales.vue
  19. 44 47
      pages/settings/index.vue
  20. 72 65
      pages/user/index.vue
  21. BIN
      static/icons/add_task.png
  22. 5 0
      static/icons/arrow_down.svg
  23. 5 0
      static/icons/arrow_left.svg
  24. 5 0
      static/icons/arrow_right.svg
  25. 5 0
      static/icons/arrow_up.svg
  26. 5 0
      static/icons/arrow_up_active.svg
  27. 4 0
      static/icons/auto_mode.svg
  28. BIN
      static/icons/certification.png
  29. 7 0
      static/icons/emergency_stop.svg
  30. 4 0
      static/icons/engine_start.svg
  31. 4 0
      static/icons/engine_stop.svg
  32. BIN
      static/icons/expert.png
  33. 6 0
      static/icons/home.svg
  34. BIN
      static/icons/insurance.png
  35. BIN
      static/icons/mall.png
  36. BIN
      static/icons/professor.png
  37. BIN
      static/icons/sales.png
  38. BIN
      static/icons/upload_add.png
  39. 42 0
      static/images/products/README.md
  40. BIN
      static/images/products/agriculture-tools.jpg
  41. BIN
      static/images/products/corn-seeds-new.jpg
  42. BIN
      static/images/products/farming-equipment.jpg
  43. BIN
      static/images/products/fertilizer.jpg
  44. BIN
      static/images/products/greenhouse-film.jpg
  45. BIN
      static/images/products/insecticide.jpg
  46. BIN
      static/images/products/machinery-parts.jpg
  47. BIN
      static/images/products/organic-fertilizer-new.jpg
  48. BIN
      static/images/products/pesticide.jpg
  49. BIN
      static/images/products/plant-protection.jpg
  50. BIN
      static/images/products/plastic-film.jpg
  51. BIN
      static/images/products/rice-seeds.jpg
  52. BIN
      static/images/products/seeds-packets.jpg
  53. BIN
      static/images/products/soil-test.jpg
  54. BIN
      static/images/products/wheat-seeds.jpg

+ 114 - 1
pages.json

@@ -35,11 +35,20 @@
 	    "navigationBarTitleText": "用户信息"
 	  }
 	},
-    {
+     {
       "path": "pages/activity/index",
       "style": {
         "navigationBarTitleText": "农事活动"
       }
+    },
+    {
+      "path": "pages/activity/activity-detail",
+      "style": {
+        "navigationBarTitleText": "农事任务详情",
+        "navigationBarBackgroundColor": "#ffffff",
+        "navigationBarTextStyle": "black",
+        "enablePullDownRefresh": true
+      }
     },
 	    {
 	      "path": "pages/device/index",
@@ -160,6 +169,110 @@
       "style": {
         "navigationBarTitleText": "选择地块"
       }
+    },
+        {
+      "path": "pages/service/mall",
+      "style": {
+        "navigationBarTitleText": "农资商城",
+        "navigationBarBackgroundColor": "#ffffff",
+        "navigationBarTextStyle": "black",
+        "enablePullDownRefresh": true
+      }
+    },
+    {
+      "path": "pages/service/mall-detail",
+      "style": {
+        "navigationBarTitleText": "商品详情",
+        "navigationBarBackgroundColor": "#ffffff",
+        "navigationBarTextStyle": "black",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/service/sales",
+      "style": {
+        "navigationBarTitleText": "农品交易",
+        "navigationBarBackgroundColor": "#ffffff",
+        "navigationBarTextStyle": "black"
+      }
+    },
+    {
+      "path": "pages/service/expert",
+      "style": {
+        "navigationBarTitleText": "专家咨询",
+        "navigationBarBackgroundColor": "#ffffff",
+        "navigationBarTextStyle": "black"
+      }
+    },
+    {
+      "path": "pages/service/expert-detail",
+      "style": {
+        "navigationBarTitleText": "专家详情",
+        "navigationBarBackgroundColor": "#ffffff",
+        "navigationBarTextStyle": "black",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/service/expert-chat",
+      "style": {
+        "navigationBarTitleText": "专家咨询",
+        "navigationBarBackgroundColor": "#ffffff",
+        "navigationBarTextStyle": "black",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/service/certification",
+      "style": {
+        "navigationBarTitleText": "绿色认证申请",
+        "navigationBarBackgroundColor": "#ffffff",
+        "navigationBarTextStyle": "black"
+      }
+    },
+    {
+      "path": "pages/service/insurance",
+      "style": {
+        "navigationBarTitleText": "保险接入",
+        "navigationBarBackgroundColor": "#ffffff",
+        "navigationBarTextStyle": "black"
+      }
+    },
+    {
+      "path": "pages/service/sales-publish",
+      "style": {
+        "navigationBarTitleText": "发布农产品",
+        "navigationBarBackgroundColor": "#ffffff",
+        "navigationBarTextStyle": "black",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/service/my-publish",
+      "style": {
+        "navigationBarTitleText": "我的发布",
+        "navigationBarBackgroundColor": "#ffffff",
+        "navigationBarTextStyle": "black",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/service/purchase-publish",
+      "style": {
+        "navigationBarTitleText": "发布收购信息",
+        "navigationBarBackgroundColor": "#ffffff",
+        "navigationBarTextStyle": "black",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/service/sales-detail",
+      "style": {
+        "navigationBarTitleText": "产品详情",
+        "navigationBarBackgroundColor": "#ffffff",
+        "navigationBarTextStyle": "black",
+        "enablePullDownRefresh": false
+      }
     }
   ],
   "tabBar": {

+ 7 - 6
pages/about/index.vue

@@ -53,8 +53,9 @@ export default {
   data() {
     return {
       version: '1.0.0'
-    }
+    };
   },
+  
   methods: {
     // 复制文本
     copyText(text) {
@@ -64,9 +65,9 @@ export default {
           uni.showToast({
             title: '已复制到剪贴板',
             icon: 'none'
-          })
+          });
         }
-      })
+      });
     },
 
     // 拨打电话
@@ -74,12 +75,12 @@ export default {
       uni.makePhoneCall({
         phoneNumber: '400-xxx-xxxx',
         fail: () => {
-          this.copyText('400-xxx-xxxx')
+          this.copyText('400-xxx-xxxx');
         }
-      })
+      });
     }
   }
-}
+};
 </script>
 
 <style lang="scss">

+ 1226 - 0
pages/activity/activity-detail.vue

@@ -0,0 +1,1226 @@
+<template>
+  <view class="page-container">
+    <!-- 页面滚动区域 -->
+    <scroll-view class="page-scroll" scroll-y>
+      <!-- 地块信息卡片 -->
+      <view class="info-card">
+        <view class="card-title">
+          <text>地块信息</text>
+        </view>
+        <view class="info-item">
+          <text class="info-label">地块名称</text>
+          <text class="info-value">{{ formData.plotName || '东区水稻田' }}</text>
+        </view>
+        <view class="info-item">
+          <text class="info-label">作物名称</text>
+          <text class="info-value">{{ formData.crop || '水稻' }}</text>
+        </view>
+        <view class="info-item">
+          <text class="info-label">负责人</text>
+          <text class="info-value">{{ formData.manager || '张农夫' }}</text>
+        </view>
+      </view>
+
+      <!-- 任务填写表单 -->
+      <view class="form-card">
+        <view class="card-title">
+          <text>任务信息</text>
+        </view>
+        
+        <!-- 任务名称 -->
+        <view class="form-item">
+          <view class="form-label required">任务名称</view>
+          <input 
+            v-model="formData.taskName"
+            placeholder="请输入任务名称,例如:水稻田施肥"
+            :disabled="pageMode === 'view'"
+            class="form-input"
+          />
+        </view>
+
+        <!-- 任务类型 -->
+        <view class="form-item" @click="pageMode !== 'view' && showTaskTypeSelector()">
+          <view class="form-label required">任务类型</view>
+          <view class="select-wrapper">
+            <input 
+              v-model="formData.taskType"
+              placeholder="请选择任务类型"
+              disabled
+              class="form-input select-input"
+            />
+            <view v-if="pageMode !== 'view'" class="select-arrow">
+              <text>▼</text>
+            </view>
+          </view>
+        </view>
+
+        <!-- 执行时间 -->
+        <view class="form-item" @click="pageMode !== 'view' && selectExecuteTime()">
+          <view class="form-label required">执行时间</view>
+          <view class="select-wrapper">
+            <input 
+              v-model="formattedExecuteTime"
+              placeholder="请选择任务计划时间"
+              disabled
+              class="form-input select-input"
+            />
+            <view v-if="pageMode !== 'view'" class="select-arrow">
+              <text>选择</text>
+            </view>
+          </view>
+        </view>
+
+        <!-- 任务说明 -->
+        <view class="form-item">
+          <view class="form-label">任务说明</view>
+          <textarea 
+            v-model="formData.taskRemark"
+            placeholder="请输入任务要点,例如:每亩用肥20kg"
+            :disabled="pageMode === 'view'"
+            class="form-textarea"
+            maxlength="200"
+          ></textarea>
+          <view class="char-count">{{ (formData.taskRemark || '').length }}/200</view>
+        </view>
+
+        <!-- 任务完成情况 -->
+        <view class="section-divider"></view>
+        <view class="section-title">
+          <text>任务完成情况</text>
+        </view>
+
+        <!-- 完成状态选择 - 新建和编辑模式 -->
+        <view class="form-item" v-if="pageMode === 'create' || pageMode === 'edit'">
+          <view class="form-label">完成状态</view>
+          <view class="radio-group">
+            <view 
+              class="radio-item" 
+              v-for="(item, index) in completionStatusOptions" 
+              :key="index"
+              @click="selectCompletionStatus(item.value)"
+            >
+              <view class="radio-circle" :class="{'radio-checked': formData.completionStatus === item.value}">
+                <view v-if="formData.completionStatus === item.value" class="radio-dot"></view>
+              </view>
+              <text class="radio-label">{{ item.label }}</text>
+            </view>
+          </view>
+        </view>
+
+        <!-- 查看模式显示完成状态 -->
+        <view class="form-item" v-if="pageMode === 'view'">
+          <view class="form-label">完成状态</view>
+          <view class="status-completed">
+            <text class="status-icon">✓</text>
+            <text>已完成</text>
+          </view>
+        </view>
+
+        <!-- 完成时间 -->
+        <view class="form-item" v-if="formData.completionStatus === 'completed'">
+          <view class="form-label" :class="{'required': (pageMode === 'create' || pageMode === 'edit') && formData.completionStatus === 'completed'}">完成时间</view>
+                     <view class="select-wrapper" @click="(pageMode === 'create' || pageMode === 'edit') && formData.completionStatus === 'completed' && selectCompletionTime()">
+            <input 
+              v-model="formattedCompletionTime"
+              placeholder="请选择实际完成时间"
+              disabled
+              class="form-input select-input"
+            />
+                         <view v-if="(pageMode === 'create' || pageMode === 'edit') && formData.completionStatus === 'completed'" class="select-arrow">
+               <text>选择</text>
+             </view>
+          </view>
+        </view>
+
+        <!-- 完成说明 -->
+        <view class="form-item" v-if="formData.completionStatus === 'completed'">
+          <view class="form-label" :class="{'required': (pageMode === 'create' || pageMode === 'edit') && formData.completionStatus === 'completed'}">完成说明</view>
+          <textarea 
+            v-model="formData.completionDesc"
+            placeholder="请输入完成说明,例如:已完成并拍照记录"
+            :disabled="pageMode === 'view'"
+            class="form-textarea"
+            maxlength="300"
+          ></textarea>
+          <view class="char-count">{{ (formData.completionDesc || '').length }}/300</view>
+          <view class="form-error" v-if="formErrors.completionDesc">
+            {{ formErrors.completionDesc }}
+          </view>
+        </view>
+
+        <!-- 现场图片 -->
+        <view class="form-item" v-if="formData.completionStatus === 'completed'">
+          <view class="form-label">现场图片</view>
+          
+          <!-- 新建和编辑模式 -->
+          <view v-if="pageMode === 'create' || pageMode === 'edit'" class="image-upload">
+            <view class="image-list">
+              <view 
+                class="image-preview" 
+                v-for="(item, index) in formData.images" 
+                :key="index"
+                @click="previewImage(item, index)"
+              >
+                <image :src="item.url || item.path" mode="aspectFill"/>
+                <view class="delete-btn" @click.stop="deletePic(index)">
+                  <text>×</text>
+                </view>
+              </view>
+              <view 
+                v-if="formData.images.length < 6" 
+                class="upload-btn" 
+                @click="chooseImage"
+              >
+                <text class="upload-icon">+</text>
+                <text class="upload-text">添加图片</text>
+              </view>
+            </view>
+            <view class="upload-tip">最多可上传6张图片</view>
+          </view>
+
+          <!-- 查看模式 -->
+          <view v-else-if="pageMode === 'view' && formData.images && formData.images.length > 0" class="image-view">
+            <view class="image-list">
+              <view 
+                class="image-preview" 
+                v-for="(item, index) in formData.images" 
+                :key="index"
+                @click="previewImage(item, index)"
+              >
+                <image :src="item.url || item.path" mode="aspectFill"/>
+              </view>
+            </view>
+          </view>
+
+          <!-- 无图片提示 -->
+          <view v-else class="no-images">
+            <text>暂无图片</text>
+          </view>
+        </view>
+      </view>
+
+      <!-- 底部占位 -->
+      <view class="bottom-safe"></view>
+    </scroll-view>
+
+    <!-- 底部提交按钮 -->
+    <view class="footer-safe" v-if="pageMode !== 'view'">
+      <view class="footer-content">
+        <button 
+          class="submit-button"
+          :class="{'loading': isSubmitting}"
+          @click="submitForm"
+          :disabled="isSubmitting"
+        >
+          {{ isSubmitting ? '提交中...' : submitButtonText }}
+        </button>
+      </view>
+    </view>
+
+
+
+    <!-- 遮罩层 -->
+    <view v-if="showTaskTypePicker || showDateTimeSelector" class="picker-mask" @click="closePickers"></view>
+    
+    <!-- 任务类型选择弹窗 -->
+    <view v-if="showTaskTypePicker" class="picker-popup">
+      <view class="picker-header">
+        <text class="picker-cancel" @click="showTaskTypePicker = false">取消</text>
+        <text class="picker-title">选择任务类型</text>
+        <text class="picker-confirm" @click="confirmTaskType">确定</text>
+      </view>
+      <view class="picker-content">
+        <view 
+          class="picker-item" 
+          v-for="(item, index) in taskTypeOptions" 
+          :key="index"
+          :class="{'selected': tempTaskTypeIndex === index}"
+          @click="tempTaskTypeIndex = index"
+        >
+          <text>{{ item.label }}</text>
+          <text v-if="tempTaskTypeIndex === index" class="check-mark">✓</text>
+        </view>
+      </view>
+    </view>
+
+    <!-- 日期时间选择弹窗 -->
+    <view v-if="showDateTimeSelector" class="picker-popup datetime-picker">
+      <view class="picker-header">
+        <text class="picker-cancel" @click="cancelDateTime">取消</text>
+        <text class="picker-title">选择时间</text>
+        <text class="picker-confirm" @click="confirmDateTime">确定</text>
+      </view>
+      <view class="datetime-picker-content">
+        <picker-view 
+          class="datetime-picker-view"
+          :value="dateTimePickerValue" 
+          @change="onDateTimePickerChange"
+        >
+          <picker-view-column v-for="(range, index) in dateTimePickerRange" :key="index">
+            <view 
+              class="picker-view-item" 
+              v-for="(item, itemIndex) in range" 
+              :key="itemIndex"
+            >
+              {{ item }}
+            </view>
+          </picker-view-column>
+        </picker-view>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      // 页面模式:create-新建, edit-编辑, view-查看
+      pageMode: 'create',
+      
+      // 选择器显示状态
+      showTaskTypePicker: false,
+      showDateTimeSelector: false,
+      
+      // 临时选择的任务类型索引
+      tempTaskTypeIndex: 0,
+      
+      // 时间选择器相关
+      currentTimeType: '', // 当前选择的时间类型
+      dateTimePickerValue: [0, 0, 0, 0, 0], // 年月日时分的选择值
+      dateTimePickerRange: [], // 选择器的范围数据
+      
+      // 表单数据
+      formData: {
+        // 地块基础信息
+        plotName: '',
+        crop: '',
+        manager: '',
+        
+        // 任务信息
+        taskName: '',
+        taskType: '',
+        executeTime: new Date().getTime(),
+        taskRemark: '',
+        
+        // 完成情况
+        completionStatus: 'pending',
+        completionTime: new Date().getTime(),
+        completionDesc: '',
+        images: []
+      },
+      
+      // 任务类型选项
+      taskTypeOptions: [
+        { label: '施肥', value: '施肥' },
+        { label: '灌溉', value: '灌溉' },
+        { label: '打药', value: '打药' },
+        { label: '采摘', value: '采摘' },
+        { label: '巡检', value: '巡检' },
+        { label: '除草', value: '除草' },
+        { label: '其他', value: '其他' }
+      ],
+      
+      // 完成状态选项
+      completionStatusOptions: [
+        { label: '待完成', value: 'pending' },
+        { label: '已完成', value: 'completed' }
+      ],
+      
+      // 是否正在提交
+      isSubmitting: false,
+      
+      // 表单验证错误
+      formErrors: {
+        completionDesc: ''
+      }
+    }
+  },
+  
+  computed: {
+    // 页面标题
+    pageTitle() {
+      switch (this.pageMode) {
+        case 'create':
+          return '新建农事任务';
+        case 'edit':
+          return '编辑农事任务';
+        default:
+          return '农事任务详情';
+      }
+    },
+    
+    // 提交按钮文字
+    submitButtonText() {
+      switch (this.pageMode) {
+        case 'create':
+          return '创建任务';
+        case 'edit':
+          return '保存修改';
+        default:
+          return '';
+      }
+    },
+    
+    // 格式化后的执行时间
+    formattedExecuteTime() {
+      return this.formatDateTime(this.formData.executeTime);
+    },
+    
+    // 格式化后的完成时间
+    formattedCompletionTime() {
+      return this.formatDateTime(this.formData.completionTime);
+    },
+    
+    // 任务类型标签数组
+    taskTypeLabels() {
+      return this.taskTypeOptions.map(item => item.label);
+    },
+    
+    // 当前任务类型索引
+    taskTypeIndex() {
+      const index = this.taskTypeOptions.findIndex(item => item.value === this.formData.taskType);
+      return index >= 0 ? index : 0;
+    }
+  },
+  
+  onLoad(options) {
+    console.log('页面加载,接收参数:', options);
+    
+    // 设置页面模式
+    if (options.mode) {
+      this.pageMode = options.mode;
+    }
+    
+    // 设置地块基础信息
+    this.formData.plotName = decodeURIComponent(options.plotName || '东区水稻田');
+    this.formData.crop = decodeURIComponent(options.crop || '水稻');
+    this.formData.manager = decodeURIComponent(options.manager || '张农夫');
+    
+    // 如果是编辑或查看模式,填充任务数据
+    if (options.taskName) {
+      this.formData.taskName = decodeURIComponent(options.taskName);
+      this.formData.taskType = decodeURIComponent(options.taskType || '');
+      this.formData.taskRemark = decodeURIComponent(options.taskRemark || '');
+      
+      // 处理执行时间
+      if (options.executeTime) {
+        const executeTimeStr = decodeURIComponent(options.executeTime);
+        if (executeTimeStr.includes('-')) {
+          this.formData.executeTime = new Date(executeTimeStr + ' 09:00:00').getTime();
+        } else {
+          this.formData.executeTime = parseInt(executeTimeStr) || new Date().getTime();
+        }
+      }
+      
+      // 如果是已完成任务,设置完成信息
+      if (options.taskStatus === 'completed') {
+        this.setupCompletionData();
+      }
+    }
+    
+    // 设置导航栏标题
+    uni.setNavigationBarTitle({
+      title: this.pageTitle
+    });
+    
+    // 初始化时间选择器数据
+    this.initDateTimeRange();
+  },
+  
+  methods: {
+    // 初始化时间选择器范围数据
+    initDateTimeRange() {
+      const currentYear = new Date().getFullYear();
+      
+      // 年份:当前年-5 到 当前年+5
+      const years = [];
+      for (let i = currentYear - 5; i <= currentYear + 5; i++) {
+        years.push(i + '年');
+      }
+      
+      // 月份:1-12月
+      const months = [];
+      for (let i = 1; i <= 12; i++) {
+        months.push(i + '月');
+      }
+      
+      // 日期:1-31日 (动态更新)
+      const days = [];
+      for (let i = 1; i <= 31; i++) {
+        days.push(i + '日');
+      }
+      
+      // 小时:0-23时
+      const hours = [];
+      for (let i = 0; i <= 23; i++) {
+        hours.push(i.toString().padStart(2, '0') + '时');
+      }
+      
+      // 分钟:0-59分
+      const minutes = [];
+      for (let i = 0; i <= 59; i++) {
+        minutes.push(i.toString().padStart(2, '0') + '分');
+      }
+      
+      this.dateTimePickerRange = [years, months, days, hours, minutes];
+    },
+    
+    // 更新日期范围(根据选择的年月)
+    updateDaysRange() {
+      const yearIndex = this.dateTimePickerValue[0];
+      const monthIndex = this.dateTimePickerValue[1];
+      
+      const baseYear = new Date().getFullYear() - 5;
+      const year = baseYear + yearIndex;
+      const month = monthIndex + 1;
+      
+      // 获取该月的天数
+      const daysInMonth = new Date(year, month, 0).getDate();
+      const days = [];
+      for (let i = 1; i <= daysInMonth; i++) {
+        days.push(i + '日');
+      }
+      
+      this.dateTimePickerRange[2] = days;
+      
+      // 如果当前选择的日期超过了该月的天数,调整为该月最后一天
+      if (this.dateTimePickerValue[2] >= daysInMonth) {
+        this.dateTimePickerValue[2] = daysInMonth - 1;
+      }
+    },
+    
+    // 显示任务类型选择器
+    showTaskTypeSelector() {
+      this.tempTaskTypeIndex = this.taskTypeIndex;
+      this.showTaskTypePicker = true;
+    },
+    
+    // 确认任务类型选择
+    confirmTaskType() {
+      this.formData.taskType = this.taskTypeOptions[this.tempTaskTypeIndex].value;
+      this.showTaskTypePicker = false;
+    },
+    
+    // 选择执行时间
+    selectExecuteTime() {
+      this.currentTimeType = 'executeTime';
+      this.initDateTimePicker(this.formData.executeTime);
+      this.showDateTimeSelector = true;
+    },
+    
+    // 选择完成时间
+    selectCompletionTime() {
+      this.currentTimeType = 'completionTime';
+      this.initDateTimePicker(this.formData.completionTime);
+      this.showDateTimeSelector = true;
+    },
+    
+    // 初始化日期时间选择器
+    initDateTimePicker(timestamp) {
+      const date = new Date(timestamp);
+      const currentYear = date.getFullYear();
+      const currentMonth = date.getMonth();
+      const currentDate = date.getDate();
+      const currentHour = date.getHours();
+      const currentMinute = date.getMinutes();
+      
+      const baseYear = new Date().getFullYear() - 5; // 基准年份
+      
+      // 设置选择器的初始值
+      this.dateTimePickerValue = [
+        currentYear - baseYear, // 年份索引
+        currentMonth, // 月份索引(0-11)
+        currentDate - 1, // 日期索引(0开始)
+        currentHour, // 小时索引
+        currentMinute // 分钟索引
+      ];
+      
+      // 更新日期范围
+      this.updateDaysRange();
+    },
+    
+    // 日期时间选择器变更
+    onDateTimePickerChange(e) {
+      this.dateTimePickerValue = e.detail.value;
+      // 当年月变更时,更新日期范围
+      this.updateDaysRange();
+    },
+    
+    // 确认时间选择
+    confirmDateTime() {
+      const values = this.dateTimePickerValue;
+      const baseYear = new Date().getFullYear() - 5;
+      const year = baseYear + values[0];
+      const month = values[1];
+      const date = values[2] + 1;
+      const hour = values[3];
+      const minute = values[4];
+      
+      const selectedTime = new Date(year, month, date, hour, minute).getTime();
+      
+      if (this.currentTimeType === 'executeTime') {
+        this.formData.executeTime = selectedTime;
+      } else if (this.currentTimeType === 'completionTime') {
+        this.formData.completionTime = selectedTime;
+      }
+      
+      this.showDateTimeSelector = false;
+      
+      uni.showToast({
+        title: '时间已设置',
+        icon: 'success',
+        duration: 1500
+      });
+    },
+    
+    // 取消时间选择
+    cancelDateTime() {
+      this.showDateTimeSelector = false;
+    },
+    
+    // 关闭所有选择器
+    closePickers() {
+      this.showTaskTypePicker = false;
+      this.showDateTimeSelector = false;
+    },
+    
+    // 选择完成状态
+    selectCompletionStatus(value) {
+      this.formData.completionStatus = value;
+      if (value === 'completed') {
+        this.formData.completionTime = new Date().getTime();
+      }
+    },
+    
+    // 格式化日期时间
+    formatDateTime(timestamp) {
+      if (!timestamp) return '';
+      const date = new Date(timestamp);
+      const year = date.getFullYear();
+      const month = String(date.getMonth() + 1).padStart(2, '0');
+      const day = String(date.getDate()).padStart(2, '0');
+      const hour = String(date.getHours()).padStart(2, '0');
+      const minute = String(date.getMinutes()).padStart(2, '0');
+      return `${year}-${month}-${day} ${hour}:${minute}`;
+    },
+    
+    // 选择图片
+    chooseImage() {
+      uni.chooseImage({
+        count: 6 - this.formData.images.length,
+        sizeType: ['original', 'compressed'],
+        sourceType: ['album', 'camera'],
+        success: (res) => {
+          console.log('选择图片成功:', res);
+          
+          res.tempFilePaths.forEach((path, index) => {
+            const imageItem = {
+              url: path,
+              path: path,
+              status: 'success'
+            };
+            this.formData.images.push(imageItem);
+          });
+          
+          if (res.tempFilePaths.length > 0) {
+            uni.showToast({
+              title: `已选择${res.tempFilePaths.length}张图片`,
+              icon: 'success'
+            });
+          }
+        },
+        fail: (err) => {
+          console.error('选择图片失败:', err);
+          uni.showToast({
+            title: '选择图片失败',
+            icon: 'none'
+          });
+        }
+      });
+    },
+
+    // 删除图片
+    deletePic(index) {
+      uni.showModal({
+        title: '确认删除',
+        content: '确定要删除这张图片吗?',
+        success: (res) => {
+          if (res.confirm) {
+            this.formData.images.splice(index, 1);
+            uni.showToast({
+              title: '已删除',
+              icon: 'none'
+            });
+          }
+        }
+      });
+    },
+
+    // 预览图片
+    previewImage(item, index) {
+      const urls = this.formData.images.map(file => file.url || file.path);
+      uni.previewImage({
+        urls: urls,
+        current: index
+      });
+    },
+    
+    // 表单验证
+    validateForm() {
+      // 重置错误信息
+      this.formErrors = {
+        completionDesc: ''
+      };
+      
+      // 基本字段验证
+      if (!this.formData.taskName.trim()) {
+        uni.showToast({
+          title: '请输入任务名称',
+          icon: 'none'
+        });
+        return false;
+      }
+      
+      if (!this.formData.taskType) {
+        uni.showToast({
+          title: '请选择任务类型',
+          icon: 'none'
+        });
+        return false;
+      }
+      
+      // 新建和编辑模式且已完成状态下的验证
+      if ((this.pageMode === 'create' || this.pageMode === 'edit') && this.formData.completionStatus === 'completed') {
+        if (!this.formData.completionDesc.trim()) {
+          this.formErrors.completionDesc = '请填写完成说明';
+          uni.showToast({
+            title: '请填写完成说明',
+            icon: 'none'
+          });
+          return false;
+        }
+      }
+      
+      return true;
+    },
+    
+    // 提交表单
+    submitForm() {
+      if (!this.validateForm()) {
+        return;
+      }
+      
+      this.isSubmitting = true;
+      
+      // 构建提交数据
+      const submitData = {
+        ...this.formData,
+        taskStatus: this.formData.completionStatus || 'pending',
+        imageUrls: this.formData.images.map(item => item.url || item.path)
+      };
+      
+      console.log('提交数据:', submitData);
+      
+      uni.showLoading({
+        title: '提交中...',
+        mask: true
+      });
+      
+      // 模拟提交过程
+      setTimeout(() => {
+        this.isSubmitting = false;
+        uni.hideLoading();
+        
+        const successMessage = this.pageMode === 'create' ? '任务创建成功' : '保存修改成功';
+        
+        uni.showToast({
+          title: successMessage,
+          icon: 'success',
+          duration: 1500
+        });
+        
+        setTimeout(() => {
+          uni.navigateBack();
+        }, 1500);
+      }, 1500);
+    },
+    
+    // 设置完成情况数据(用于编辑和查看模式)
+    setupCompletionData() {
+      this.formData.completionStatus = 'completed';
+      this.formData.completionTime = this.formData.executeTime + 8 * 60 * 60 * 1000;
+      this.formData.completionDesc = '已按要求完成任务,现场情况良好,所有步骤都按标准执行';
+      this.formData.images = [
+        {
+          url: 'https://cdn.uviewui.com/uview/album/1.jpg',
+          status: 'success'
+        },
+        {
+          url: 'https://cdn.uviewui.com/uview/album/2.jpg',
+          status: 'success'
+        }
+      ];
+    }
+  }
+}
+</script>
+
+<style scoped>
+.page-container {
+  height: 100vh;
+  background-color: #F5F5F5;
+  display: flex;
+  flex-direction: column;
+}
+
+.page-scroll {
+  flex: 1;
+  overflow: hidden;
+}
+
+/* 地块基础信息卡片 */
+.info-card {
+  background: #F9F9F9;
+  margin: 24rpx;
+  padding: 24rpx;
+  border-radius: 8rpx;
+  border: 1rpx solid #E5E5E5;
+}
+
+.card-title {
+  font-size: 30rpx;
+  font-weight: 600;
+  color: #333333;
+  margin-bottom: 16rpx;
+  padding-bottom: 12rpx;
+  border-bottom: 1rpx solid #E5E5E5;
+}
+
+.info-item {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 12rpx;
+  padding: 8rpx 0;
+}
+
+.info-item:last-child {
+  margin-bottom: 0;
+}
+
+.info-label {
+  font-size: 28rpx;
+  color: #666666;
+  flex-shrink: 0;
+}
+
+.info-value {
+  font-size: 28rpx;
+  color: #333333;
+  font-weight: 500;
+}
+
+/* 任务填写表单 */
+.form-card {
+  background: #FFFFFF;
+  margin: 0 24rpx 24rpx;
+  padding: 24rpx;
+  border-radius: 8rpx;
+  border: 1rpx solid #E5E5E5;
+}
+
+.section-divider {
+  height: 1rpx;
+  background: #F0F0F0;
+  margin: 32rpx 0 24rpx;
+}
+
+.section-title {
+  font-size: 30rpx;
+  font-weight: 600;
+  color: #333333;
+  margin-bottom: 16rpx;
+  padding-bottom: 12rpx;
+  border-bottom: 1rpx solid #F0F0F0;
+}
+
+.form-item {
+  margin-bottom: 24rpx;
+}
+
+.form-item:last-child {
+  margin-bottom: 0;
+}
+
+.form-label {
+  font-size: 28rpx;
+  color: #333333;
+  margin-bottom: 12rpx;
+  font-weight: 500;
+}
+
+.form-label.required::before {
+  content: '*';
+  color: #FF6B6B;
+  margin-right: 4rpx;
+}
+
+.form-input {
+  width: 100%;
+  height: 80rpx;
+  background: #F8F8F8;
+  border: 1rpx solid #E5E5E5;
+  border-radius: 8rpx;
+  padding: 0 16rpx;
+  font-size: 28rpx;
+  color: #333333;
+  box-sizing: border-box;
+}
+
+.form-input:focus {
+  background: #FFFFFF;
+  border-color: #3BB44A;
+}
+
+.form-input::placeholder {
+  color: #CCCCCC;
+}
+
+.form-input:disabled {
+  background: #F8F8F8;
+  color: #999999;
+}
+
+.select-wrapper {
+  position: relative;
+  width: 100%;
+}
+
+.select-input {
+  cursor: pointer;
+}
+
+.select-arrow {
+  position: absolute;
+  right: 16rpx;
+  top: 50%;
+  transform: translateY(-50%);
+  color: #999999;
+  font-size: 20rpx;
+  pointer-events: none;
+}
+
+.form-textarea {
+  width: 100%;
+  min-height: 120rpx;
+  background: #F8F8F8;
+  border: 1rpx solid #E5E5E5;
+  border-radius: 8rpx;
+  padding: 16rpx;
+  font-size: 28rpx;
+  color: #333333;
+  box-sizing: border-box;
+  resize: none;
+  line-height: 1.5;
+}
+
+.form-textarea:focus {
+  background: #FFFFFF;
+  border-color: #3BB44A;
+}
+
+.form-textarea::placeholder {
+  color: #CCCCCC;
+}
+
+.form-textarea:disabled {
+  background: #F8F8F8;
+  color: #999999;
+}
+
+.char-count {
+  font-size: 24rpx;
+  color: #CCCCCC;
+  text-align: right;
+  margin-top: 8rpx;
+}
+
+.form-error {
+  font-size: 24rpx;
+  color: #FF6B6B;
+  margin-top: 8rpx;
+}
+
+/* 单选按钮样式 */
+.radio-group {
+  display: flex;
+  gap: 32rpx;
+}
+
+.radio-item {
+  display: flex;
+  align-items: center;
+  cursor: pointer;
+}
+
+.radio-circle {
+  width: 32rpx;
+  height: 32rpx;
+  border: 2rpx solid #CCCCCC;
+  border-radius: 50%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-right: 8rpx;
+}
+
+.radio-circle.radio-checked {
+  border-color: #3BB44A;
+  background-color: #3BB44A;
+}
+
+.radio-dot {
+  width: 12rpx;
+  height: 12rpx;
+  background-color: #FFFFFF;
+  border-radius: 50%;
+}
+
+.radio-label {
+  font-size: 28rpx;
+  color: #333333;
+}
+
+/* 完成状态样式 */
+.status-completed {
+  display: flex;
+  align-items: center;
+  color: #3BB44A;
+  font-size: 28rpx;
+}
+
+.status-icon {
+  width: 32rpx;
+  height: 32rpx;
+  background: #3BB44A;
+  color: #FFFFFF;
+  border-radius: 50%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-right: 8rpx;
+  font-size: 20rpx;
+  line-height: 1;
+}
+
+/* 图片上传样式 */
+.image-upload, .image-view {
+  width: 100%;
+}
+
+.image-list {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 16rpx;
+}
+
+.image-preview {
+  position: relative;
+  width: 160rpx;
+  height: 160rpx;
+  border-radius: 8rpx;
+  overflow: hidden;
+  background: #F5F5F5;
+}
+
+.image-preview image {
+  width: 100%;
+  height: 100%;
+}
+
+.delete-btn {
+  position: absolute;
+  top: -6rpx;
+  right: -6rpx;
+  width: 32rpx;
+  height: 32rpx;
+  background: rgba(0, 0, 0, 0.6);
+  color: #FFFFFF;
+  border-radius: 50%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  font-size: 20rpx;
+  line-height: 1;
+}
+
+.upload-btn {
+  width: 160rpx;
+  height: 160rpx;
+  background: #F8F8F8;
+  border: 2rpx dashed #DDDDDD;
+  border-radius: 8rpx;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+}
+
+.upload-icon {
+  font-size: 32rpx;
+  margin-bottom: 8rpx;
+  color: #999999;
+}
+
+.upload-text {
+  font-size: 24rpx;
+  color: #999999;
+}
+
+.upload-tip {
+  font-size: 24rpx;
+  color: #999999;
+  margin-top: 12rpx;
+}
+
+.no-images {
+  padding: 40rpx 0;
+  text-align: center;
+  color: #CCCCCC;
+  font-size: 28rpx;
+}
+
+/* 底部安全区域 */
+.bottom-safe {
+  height: 120rpx;
+}
+
+.footer-safe {
+  background: #FFFFFF;
+  border-top: 1rpx solid #E5E5E5;
+  padding-bottom: constant(safe-area-inset-bottom);
+  padding-bottom: env(safe-area-inset-bottom);
+}
+
+.footer-content {
+  padding: 24rpx;
+}
+
+.submit-button {
+  width: 100%;
+  height: 88rpx;
+  background: #3BB44A;
+  color: #FFFFFF;
+  border: none;
+  border-radius: 8rpx;
+  font-size: 32rpx;
+  font-weight: 600;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.submit-button:active {
+  background: #2D8C3C;
+}
+
+.submit-button:disabled,
+.submit-button.loading {
+  background: #CCCCCC;
+}
+
+/* 选择器弹窗样式 */
+.picker-mask {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background: rgba(0, 0, 0, 0.5);
+  z-index: 999;
+}
+
+.picker-popup {
+  position: fixed;
+  bottom: 0;
+  left: 0;
+  width: 100%;
+  background: #FFFFFF;
+  border-radius: 16rpx 16rpx 0 0;
+  z-index: 1000;
+  padding-bottom: constant(safe-area-inset-bottom);
+  padding-bottom: env(safe-area-inset-bottom);
+}
+
+.picker-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 24rpx;
+  border-bottom: 1rpx solid #E5E5E5;
+}
+
+.picker-cancel, .picker-confirm {
+  font-size: 30rpx;
+  color: #3BB44A;
+}
+
+.picker-title {
+  font-size: 32rpx;
+  font-weight: 600;
+  color: #333333;
+}
+
+.picker-content {
+  max-height: 400rpx;
+  overflow-y: auto;
+}
+
+.picker-item {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 24rpx;
+  border-bottom: 1rpx solid #F0F0F0;
+  font-size: 30rpx;
+  color: #333333;
+}
+
+.picker-item.selected {
+  color: #3BB44A;
+}
+
+.picker-item:last-child {
+  border-bottom: none;
+}
+
+.check-mark {
+  color: #3BB44A;
+  font-size: 28rpx;
+}
+
+/* 日期时间选择器样式 */
+.datetime-picker {
+  height: 60vh;
+}
+
+.datetime-picker-content {
+  height: calc(100% - 100rpx);
+  padding: 0;
+}
+
+.datetime-picker-view {
+  width: 100%;
+  height: 100%;
+}
+
+.picker-view-item {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  height: 80rpx;
+  font-size: 32rpx;
+  color: #333333;
+}
+</style> 

+ 721 - 5
pages/activity/index.vue

@@ -1,15 +1,731 @@
 <template>
-  <view class="container">
-    农事活动页面开发中...
+  <view class="activity-container">
+    <view class="fixed-content">
+      <!-- 顶部地块信息卡片 -->
+      <view class="plot-info-card">
+        <view class="plot-header">
+          <text class="plot-name">{{ plotData.name }}</text>
+          <text class="plot-area">{{ plotData.area }}亩</text>
+        </view>
+        <view class="plot-details">
+          <view class="plot-item">
+            <text class="item-label">作物:</text>
+            <text class="item-value">{{ plotData.crop }}</text>
+          </view>
+          <view class="plot-item">
+            <text class="item-label">负责人:</text>
+            <text class="item-value">{{ plotData.manager }}</text>
+          </view>
+        </view>
+      </view>
+
+      <!-- 任务状态筛选 -->
+      <view class="tab-filter">
+        <view class="tab-container">
+            <view 
+              class="tab-item" 
+              v-for="(status, index) in taskStatus" 
+              :key="index"
+              :class="{ active: currentStatus === status.value }"
+              @click="switchStatus(status.value)"
+            >
+              <text>{{ status.label }}</text>
+              <view class="badge" v-if="status.value === 'pending' && pendingTaskCount > 0">
+                {{ pendingTaskCount > 99 ? '99+' : pendingTaskCount }}
+              </view>
+              <view class="active-line" v-if="currentStatus === status.value"></view>
+            </view>
+          </view>
+      </view>
+    </view>
+
+    <!-- 任务列表 - 可滚动区域 -->
+    <scroll-view class="task-list-scroll" scroll-y 
+      @scrolltolower="loadMore" 
+      @refresherrefresh="refreshData" 
+      refresher-enabled
+      :refresher-triggered="isRefreshing">
+      <view class="task-list">
+        <view class="task-card" v-for="(task, index) in taskList" :key="index" @click="viewTaskDetail(task)">
+          <!-- 头部区域:任务名称和状态标签 -->
+          <view class="task-header">
+            <view class="task-name">{{ task.name }}</view>
+            <view class="task-status" :class="{ 'status-completed': task.status === 'completed' }">
+              {{ task.status === 'pending' ? '待完成' : '已完成' }}
+            </view>
+          </view>
+          
+          <!-- 信息行:类型、时间、责任人统一放在一行,类型在前 -->
+          <view class="task-info-row">
+            <!-- 类型标签放在最左侧 -->
+            <view class="info-type">
+              <image src="/static/icons/task_icon.png" mode="aspectFit" class="info-icon"></image>
+              <text class="info-text">{{ task.type }}</text>
+            </view>
+            
+            <!-- 时间信息放在中间 -->
+            <view class="info-time">
+              <image src="/static/icons/clock_icon.png" mode="aspectFit" class="info-icon"></image>
+              <text class="info-text">{{ task.executeTime }}</text>
+            </view>
+            
+            <!-- 责任人信息放在右侧 -->
+            <view class="info-person">
+              <image src="/static/icons/user.png" mode="aspectFit" class="info-icon"></image>
+              <text class="info-text">{{ task.assignee }}</text>
+            </view>
+          </view>
+          
+          <!-- 备注区域 -->
+          <view class="task-remark" v-if="task.remark" @click.stop="toggleRemark(index)">
+            <text class="remark-label">备注:</text>
+            <text class="remark-content" :class="{'remark-expanded': task.remarkExpanded}">{{ task.remark }}</text>
+            <text class="expand-btn" v-if="task.remark.length > 50 && !task.remarkExpanded">展开</text>
+            <text class="expand-btn" v-if="task.remarkExpanded">收起</text>
+          </view>
+        </view>
+        
+        <view class="loading-more" v-if="isLoading">
+          <view class="loading-icon"></view>
+          <text>加载中...</text>
+        </view>
+        <view class="no-more-data" v-if="noMoreData && taskList.length > 0">
+          <text>没有更多数据了</text>
+        </view>
+        <view class="empty-list" v-if="taskList.length === 0 && !isLoading">
+          <image src="/static/icons/warning_icon.png" mode="aspectFit"></image>
+          <text>暂无农事任务</text>
+        </view>
+      </view>
+    </scroll-view>
+
+    <!-- 新增任务按钮 -->
+    <view class="add-task-button" @click="createNewTask">
+      <image src="/static/icons/add_task.png" mode="aspectFit" class="add-icon"></image>
+    </view>
   </view>
 </template>
 
-<script setup>
+<script>
+export default {
+  data() {
+    return {
+      // 地块数据
+      plotData: {
+        id: 1,
+        name: '东区水稻田',
+        area: '128',
+        crop: '水稻',
+        manager: '张农夫'
+      },
+
+      // 待完成任务数
+      pendingTaskCount: 5,
+
+      // 当前筛选状态
+      currentStatus: 'all',
+
+      // 筛选相关数据
+      taskStatus: [
+        { label: '全部', value: 'all' },
+        { label: '待完成', value: 'pending' },
+        { label: '已完成', value: 'completed' }
+      ],
+      
+      // 任务列表数据
+      taskList: [],
+      isLoading: false,
+      isRefreshing: false,
+      noMoreData: false,
+      page: 1,
+      pageSize: 10,
+
+      // 模拟任务数据
+      mockTasks: [
+        {
+          id: 1,
+          name: '水稻田施肥',
+          type: '施肥',
+          status: 'pending',
+          executeTime: '2023-06-15',
+          assignee: '李明',
+          remark: '使用复合肥,每亩用量20kg',
+          remarkExpanded: false
+        },
+        {
+          id: 2,
+          name: '病虫害防治喷药',
+          type: '喷药',
+          status: 'completed',
+          executeTime: '2023-06-10',
+          assignee: '王强',
+          remark: '使用杀虫剂,注意安全防护',
+          remarkExpanded: false
+        },
+        {
+          id: 3,
+          name: '早稻收割',
+          type: '采摘',
+          status: 'pending',
+          executeTime: '2023-06-20',
+          assignee: '张农夫',
+          remark: '天气晴好时进行',
+          remarkExpanded: false
+        },
+        {
+          id: 4,
+          name: '水渠疏通',
+          type: '灌溉',
+          status: 'pending',
+          executeTime: '2023-06-12',
+          assignee: '周华',
+          remark: '',
+          remarkExpanded: false
+        },
+        {
+          id: 5,
+          name: '田间除草',
+          type: '除草',
+          status: 'pending',
+          executeTime: '2023-06-18',
+          assignee: '刘艳',
+          remark: '使用除草剂,避开雨天',
+          remarkExpanded: false
+        }
+      ]
+    }
+  },
+  
+  components: {
+    // No longer needed as we're using standard image icons
+  },
+  
+  methods: {
+    // 根据任务类型返回颜色
+    getTypeColor(type, mode = 'bg') {
+      const colors = {
+        '施肥': {
+          bg: 'linear-gradient(135deg, rgba(59, 180, 74, 0.8), rgba(59, 180, 74, 0.6))',
+          text: '#3BB44A'
+        },
+        '喷药': {
+          bg: 'linear-gradient(135deg, rgba(255, 82, 82, 0.8), rgba(255, 82, 82, 0.6))',
+          text: '#FF5252'
+        },
+        '灌溉': {
+          bg: 'linear-gradient(135deg, rgba(64, 158, 255, 0.8), rgba(64, 158, 255, 0.6))',
+          text: '#409EFF'
+        },
+        '采摘': {
+          bg: 'linear-gradient(135deg, rgba(250, 173, 20, 0.8), rgba(250, 173, 20, 0.6))',
+          text: '#FAAD14'
+        },
+        '播种': {
+          bg: 'linear-gradient(135deg, rgba(121, 85, 72, 0.8), rgba(121, 85, 72, 0.6))',
+          text: '#795548'
+        },
+        '除草': {
+          bg: 'linear-gradient(135deg, rgba(156, 39, 176, 0.8), rgba(156, 39, 176, 0.6))',
+          text: '#9C27B0'
+        }
+      };
+      
+      const defaultColor = {
+        bg: 'linear-gradient(135deg, rgba(158, 158, 158, 0.8), rgba(158, 158, 158, 0.6))',
+        text: '#909399'
+      };
+      
+      return (colors[type] || defaultColor)[mode];
+    },
+
+    // 切换任务状态筛选
+    switchStatus(status) {
+      if (this.currentStatus === status) return;
+      
+      this.currentStatus = status;
+      this.page = 1;
+      this.noMoreData = false;
+      this.loadTaskData();
+    },
+    
+    // 加载任务数据
+    loadTaskData() {
+      this.isLoading = true;
+      
+      // 模拟API请求延迟
+      setTimeout(() => {
+        // 模拟筛选
+        let filteredTasks = [...this.mockTasks];
+        
+        // 按状态筛选
+        if (this.currentStatus !== 'all') {
+          filteredTasks = filteredTasks.filter(task => task.status === this.currentStatus);
+        }
+        
+        // 分页处理
+        const start = (this.page - 1) * this.pageSize;
+        const end = start + this.pageSize;
+        const pageData = filteredTasks.slice(start, end);
+        
+        if (this.page === 1) {
+          this.taskList = pageData;
+        } else {
+          this.taskList = [...this.taskList, ...pageData];
+        }
+        
+        this.noMoreData = end >= filteredTasks.length;
+        this.isLoading = false;
+        this.isRefreshing = false;
+        
+        // 更新待完成任务数
+        this.pendingTaskCount = this.mockTasks.filter(task => task.status === 'pending').length;
+      }, 500);
+    },
+
+    // 下拉刷新
+    refreshData(e) {
+      this.isRefreshing = true;
+      this.page = 1;
+      this.noMoreData = false;
+      
+      // 模拟API请求延迟
+      setTimeout(() => {
+        this.loadTaskData();
+        // 显示刷新成功的提示
+        uni.showToast({
+          title: '刷新成功',
+          icon: 'success',
+          duration: 1000
+        });
+      }, 1000);
+    },
+
+    // 上拉加载更多
+    loadMore() {
+      if (!this.isLoading && !this.noMoreData) {
+        this.page++;
+        this.loadTaskData();
+      }
+    },
+
+    // 查看任务详情
+    viewTaskDetail(task) {
+      // 根据任务状态决定跳转到不同模式的页面
+      let mode = '';
+      if (task.status === 'pending') {
+        // 待完成任务跳转到编辑页面
+        mode = 'edit';
+      } else if (task.status === 'completed') {
+        // 已完成任务跳转到查看页面
+        mode = 'view';
+      }
+      
+      console.log(`点击任务: ${task.name}, 状态: ${task.status}, 跳转模式: ${mode}`);
+      console.log('地块数据:', this.plotData);
+      console.log('任务数据:', task);
+      
+      // 使用简化的URL参数传递
+      const url = `/pages/activity/activity-detail?id=${task.id}&mode=${mode}&plotName=${encodeURIComponent(this.plotData.name)}&crop=${encodeURIComponent(this.plotData.crop)}&manager=${encodeURIComponent(this.plotData.manager)}&taskName=${encodeURIComponent(task.name)}&taskType=${encodeURIComponent(task.type)}&executeTime=${encodeURIComponent(task.executeTime)}&taskRemark=${encodeURIComponent(task.remark || '')}&taskStatus=${task.status}&assignee=${encodeURIComponent(task.assignee)}`;
+      
+      console.log('跳转URL:', url);
+      
+      uni.navigateTo({
+        url: url
+      });
+    },
+
+    // 创建新任务
+    createNewTask() {
+      console.log('点击新建任务按钮,跳转到创建页面');
+      console.log('地块数据:', this.plotData);
+      
+      // 使用简化的URL参数传递
+      const url = `/pages/activity/activity-detail?id=new&mode=create&plotName=${encodeURIComponent(this.plotData.name)}&crop=${encodeURIComponent(this.plotData.crop)}&manager=${encodeURIComponent(this.plotData.manager)}`;
+      
+      console.log('跳转URL:', url);
+      
+      // 跳转到新建任务页面
+      uni.navigateTo({
+        url: url
+      });
+    },
+    
+    // 切换备注展开/收起状态
+    toggleRemark(index) {
+      if (this.taskList[index].remark && this.taskList[index].remark.length > 50) {
+        this.$set(this.taskList[index], 'remarkExpanded', !this.taskList[index].remarkExpanded);
+      }
+    }
+  },
+  
+  // 页面加载时获取数据
+  onLoad() {
+    this.loadTaskData();
+  }
+}
 </script>
 
 <style scoped>
-.container {
-  padding: 40rpx;
+.activity-container {
+  position: relative;
+  height: 100vh;
+  background-color: #f8f8f8;
+  display: flex;
+  flex-direction: column;
+  overflow: hidden;
+}
+
+/* 固定内容区域 */
+.fixed-content {
+  flex-shrink: 0;
+  width: 100%;
+}
+
+/* 地块信息卡片 */
+.plot-info-card {
+  margin: 20rpx 30rpx 30rpx;
+  padding: 30rpx;
+  background: linear-gradient(135deg, #3BB44A, #2D8C3C);
+  border-radius: 16rpx;
+  box-shadow: 0 4rpx 12rpx rgba(59, 180, 74, 0.2);
+  position: relative;
+  color: #fff;
+  width: calc(100% - 60rpx);
+  box-sizing: border-box;
+}
+
+.plot-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 20rpx;
+}
+
+.plot-name {
+  font-size: 32rpx;
+  font-weight: bold;
+}
+
+.plot-area {
+  font-size: 28rpx;
+  background-color: rgba(255, 255, 255, 0.2);
+  padding: 4rpx 16rpx;
+  border-radius: 20rpx;
+}
+
+.plot-details {
+  display: flex;
+  flex-wrap: wrap;
+}
+
+.plot-item {
+  display: flex;
+  align-items: center;
+  margin-right: 40rpx;
+  margin-bottom: 10rpx;
+}
+
+.item-label {
+  font-size: 26rpx;
+  opacity: 0.8;
+}
+
+.item-value {
+  font-size: 28rpx;
+  font-weight: 500;
+}
+
+/* 任务状态筛选 */
+.tab-filter {
+  margin: 0 30rpx 20rpx;
+  background-color: #fff;
+  border-radius: 16rpx;
+  box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
+  overflow: hidden;
+  z-index: 10;
+  width: calc(100% - 60rpx);
+  box-sizing: border-box;
+}
+
+.tab-container {
+  display: flex;
+  width: 100%;
+  height: 90rpx;
+}
+
+.tab-item {
+  flex: 1;
+  position: relative;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  height: 100%;
+  min-width: 150rpx;
+  transition: all 0.3s ease;
+}
+
+.tab-item text {
+  font-size: 28rpx;
+  color: #666;
+  transition: color 0.3s ease;
+}
+
+.tab-item.active text {
+  color: #3BB44A;
+  font-weight: bold;
+}
+
+.active-line {
+  position: absolute;
+  bottom: 0;
+  left: 25%;
+  width: 50%;
+  height: 4rpx;
+  background-color: #3BB44A;
+  border-radius: 4rpx;
+  transition: all 0.3s ease;
+}
+
+.badge {
+  position: absolute;
+  top: 16rpx;
+  right: 20%;
+  min-width: 32rpx;
+  height: 32rpx;
+  line-height: 32rpx;
+  border-radius: 16rpx;
+  background: linear-gradient(135deg, #FF5252, #FF7676);
+  color: #fff;
+  font-size: 20rpx;
+  padding: 0 8rpx;
+  text-align: center;
+  box-shadow: 0 2rpx 4rpx rgba(255, 82, 82, 0.2);
+  transform: scale(0.9);
+}
+
+/* 滚动区域 */
+.task-list-scroll {
+  flex: 1;
+  height: 0; /* 关键属性:使滚动区域占据剩余高度 */
+  overflow: hidden;
+}
+
+.task-list {
+  padding: 0 30rpx;
+  box-sizing: border-box;
+  width: 100%;
+}
+
+.task-card {
+  background-color: #fff;
+  border-radius: 16rpx;
+  padding: 24rpx;
+  margin-bottom: 20rpx;
+  box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
+  position: relative;
+  transition: transform 0.3s ease;
+  width: calc(100% - 0rpx);
+  box-sizing: border-box;
+  overflow: hidden;
+}
+
+.task-card:active {
+  transform: scale(0.98);
+}
+
+/* 任务卡片头部样式优化 */
+.task-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 16rpx;
+}
+
+.task-name {
   font-size: 32rpx;
+  font-weight: bold;
+  color: #333;
+  padding-right: 80rpx; /* 为右侧状态标签留出空间 */
+}
+
+.task-status {
+  position: absolute;
+  top: 24rpx;
+  right: 24rpx;
+  font-size: 24rpx;
+  padding: 4rpx 16rpx;
+  border-radius: 20rpx;
+  background: linear-gradient(135deg, rgba(255, 82, 82, 0.8), rgba(255, 82, 82, 0.6));
+  color: #fff;
+  z-index: 1;
+  max-width: 120rpx;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+.status-completed {
+  background: linear-gradient(135deg, rgba(59, 180, 74, 0.8), rgba(59, 180, 74, 0.6));
+}
+
+/* 信息行样式优化 */
+.task-info-row {
+  display: flex;
+  align-items: center;
+  margin-bottom: 16rpx;
+  padding: 6rpx 0;
+  width: 100%;
+}
+
+.info-type, .info-time, .info-person {
+  display: flex;
+  align-items: center;
+}
+
+.info-type {
+  flex: 0 0 auto;
+  margin-right: 30rpx;
+}
+
+.info-time {
+  flex: 0 0 auto;
+  margin-right: 30rpx;
+}
+
+.info-person {
+  flex: 0 0 auto;
+  min-width: 100rpx;
+}
+
+.info-icon {
+  width: 28rpx;
+  height: 28rpx;
+  margin-right: 8rpx;
+  opacity: 0.7;
+  flex-shrink: 0;
+}
+
+.info-text {
+  font-size: 26rpx;
+  color: #666;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+/* 删除旧的类型标签样式 */
+.type-tag {
+  display: none;
+}
+
+.task-remark {
+  background-color: rgba(0, 0, 0, 0.03);
+  padding: 16rpx;
+  border-radius: 10rpx;
+  display: flex;
+  margin-bottom: 10rpx;
+  position: relative;
+  flex-wrap: wrap;
+}
+
+.remark-label {
+  font-size: 26rpx;
+  color: #999;
+  margin-right: 8rpx;
+}
+
+.remark-content {
+  flex: 1;
+  font-size: 26rpx;
+  color: #666;
+  display: -webkit-box;
+  -webkit-box-orient: vertical;
+  -webkit-line-clamp: 2;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  word-break: break-all;
+}
+
+.remark-expanded {
+  -webkit-line-clamp: unset;
+}
+
+.expand-btn {
+  font-size: 24rpx;
+  color: #3BB44A;
+  margin-left: auto;
+  padding-left: 20rpx;
+}
+
+.loading-more, .no-more-data, .empty-list {
+  text-align: center;
+  padding: 30rpx 0;
+}
+
+.loading-icon {
+  display: inline-block;
+  width: 40rpx;
+  height: 40rpx;
+  border: 3rpx solid #f3f3f3;
+  border-top: 3rpx solid #3BB44A;
+  border-radius: 50%;
+  vertical-align: middle;
+  animation: spin 1s linear infinite;
+}
+
+@keyframes spin {
+  0% { transform: rotate(0deg); }
+  100% { transform: rotate(360deg); }
+}
+
+.loading-more text, .no-more-data text {
+  font-size: 24rpx;
+  color: #999;
+  margin-left: 10rpx;
+}
+
+.empty-list {
+  padding: 100rpx 0;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+}
+
+.empty-list image {
+  width: 120rpx;
+  height: 120rpx;
+  margin-bottom: 20rpx;
+  opacity: 0.5;
+}
+
+.empty-list text {
+  font-size: 28rpx;
+  color: #999;
+}
+
+/* 新增任务按钮 */
+.add-task-button {
+  position: fixed;
+  right: 40rpx;
+  bottom: 120rpx;
+  width: 100rpx;
+  height: 100rpx;
+  border-radius: 50%;
+  background: linear-gradient(135deg, #3BB44A, #2D8C3C);
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  box-shadow: 0 6rpx 16rpx rgba(59, 180, 74, 0.3);
+  z-index: 100;
+  transition: transform 0.2s ease;
+}
+
+.add-task-button:active {
+  transform: scale(0.95);
+}
+
+.add-icon {
+  width: 48rpx;
+  height: 48rpx;
 }
 </style>

+ 2 - 2
pages/device/device-list/detail-camera.vue

@@ -248,8 +248,8 @@ export default {
         lastUpdate: '',
         deviceType: 'weather' ,// 默认类型,会根据API返回更新
       	deviceTypeId:null,
-		streamUrl: '',
-        originalStreamUrl: 'http://121.4.16.100:6080/rtp/34020000001110000001_34020000001320000012.live.flv',
+		    streamUrl: '',
+        originalStreamUrl: 'ws://121.4.16.100:6080/rtp/34020000001110000001_34020000001320000012.live.flv',
 
       },
       isPlaying: false,

+ 4 - 2
pages/privacy/index.vue

@@ -84,8 +84,10 @@
   </view>
 </template>
 
-<script setup>
-// 无需特殊逻辑
+<script>
+export default {
+  // 隐私政策页面无需特殊逻辑,但仍需符合Vue 2格式
+};
 </script>
 
 <style lang="scss">

+ 434 - 0
pages/service/certification.vue

@@ -0,0 +1,434 @@
+<template>
+  <view class="certification-container">
+    <!-- 顶部横幅 -->
+    <view class="banner-section">
+      <view class="banner-content">
+        <image class="banner-bg" src="/static/images/agriculture/rice-field1.svg" mode="aspectFill"></image>
+        <view class="banner-overlay">
+          <view class="banner-text">
+            <text class="main-title">绿色认证服务</text>
+            <text class="sub-title">推动绿色农业发展,打造生态优质农产品</text>
+          </view>
+        </view>
+      </view>
+    </view>
+
+    <!-- 什么是绿色认证 -->
+    <view class="info-card">
+      <view class="card-header">
+        <text class="card-title">什么是绿色认证?</text>
+      </view>
+      <view class="card-content">
+        <text class="description-text">
+          绿色食品认证是指符合无污染、无公害标准的农产品生产体系,经权威机构审核颁发的绿色标识,具有较高市场认可度。绿色认证不仅代表着农产品的高品质和安全性,更是农业可持续发展的重要标志,有助于提升农产品市场竞争力和消费者信任度。
+        </text>
+      </view>
+    </view>
+
+    <!-- 认证流程 -->
+    <view class="info-card">
+      <view class="card-header">
+        <text class="card-title">认证流程</text>
+      </view>
+      <view class="card-content">
+        <view class="process-list">
+          <view class="process-item">
+            <view class="process-step">
+              <view class="step-number">1</view>
+            </view>
+            <view class="process-content">
+              <text class="step-title">提交申请</text>
+              <text class="step-desc">准备相关资料,提交绿色认证申请</text>
+            </view>
+          </view>
+          
+          <view class="process-item">
+            <view class="process-step">
+              <view class="step-number">2</view>
+            </view>
+            <view class="process-content">
+              <text class="step-title">资料审核</text>
+              <text class="step-desc">专业机构进行现场检查和资料评审</text>
+            </view>
+          </view>
+          
+          <view class="process-item">
+            <view class="process-step">
+              <view class="step-number">3</view>
+            </view>
+            <view class="process-content">
+              <text class="step-title">获取证书</text>
+              <text class="step-desc">审核通过后颁发绿色认证证书</text>
+            </view>
+          </view>
+        </view>
+      </view>
+    </view>
+
+    <!-- 认证优势 -->
+    <view class="info-card">
+      <view class="card-header">
+        <text class="card-title">认证优势</text>
+      </view>
+      <view class="card-content">
+        <view class="advantage-list">
+          <view class="advantage-item">
+            <text class="advantage-text">提升农产品销售价格</text>
+          </view>
+          <view class="advantage-item">
+            <text class="advantage-text">增强产品质量安全保障</text>
+          </view>
+          <view class="advantage-item">
+            <text class="advantage-text">可用于政府扶持与项目申报</text>
+          </view>
+        </view>
+      </view>
+    </view>
+
+    <!-- 适用范围 -->
+    <view class="info-card">
+      <view class="card-header">
+        <text class="card-title">适用范围</text>
+      </view>
+      <view class="card-content">
+        <view class="scope-content">
+          <text class="scope-text">
+            适用于种植类地块(如水稻、玉米、葡萄等农作物),申请人需具备土地权属证明或经营权证明,并通过农残检测。认证范围涵盖农产品生产、加工、包装、储存、运输等全产业链环节,确保产品从田间到餐桌的全程质量安全。
+          </text>
+        </view>
+      </view>
+    </view>
+
+    <!-- 联系方式 -->
+    <view class="info-card">
+      <view class="card-header">
+        <text class="card-title">联系方式</text>
+      </view>
+      <view class="card-content">
+        <view class="contact-list">
+          <view class="contact-item">
+            <view class="contact-label">联系人:</view>
+            <text class="contact-value">李老师</text>
+          </view>
+          <view class="contact-item">
+            <view class="contact-label">联系电话:</view>
+            <text class="contact-phone" @click="makePhoneCall">400-123-4567</text>
+          </view>
+          <view class="contact-item">
+            <view class="contact-label">服务时间:</view>
+            <text class="contact-value">工作日 9:00-17:30</text>
+          </view>
+        </view>
+      </view>
+    </view>
+
+    <!-- 底部提示信息 -->
+    <view class="notice-card">
+      <view class="notice-content">
+        <text class="notice-text">
+          绿色认证服务需线下办理,平台仅提供政策引导与信息对接。如需办理,请拨打联系电话。
+        </text>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  name: 'Certification',
+  methods: {
+    // 拨打电话
+    makePhoneCall() {
+      uni.makePhoneCall({
+        phoneNumber: '400-123-4567',
+        fail: (err) => {
+          console.log('拨打电话失败:', err);
+          uni.showToast({
+            title: '拨打电话失败',
+            icon: 'none'
+          });
+        }
+      });
+    }
+  }
+}
+</script>
+
+<style lang="scss">
+.certification-container {
+  min-height: 100vh;
+  background-color: #f5f5f5;
+  padding-bottom: 40rpx;
+}
+
+// 顶部横幅
+.banner-section {
+  position: relative;
+  height: 400rpx;
+  overflow: hidden;
+}
+
+.banner-content {
+  position: relative;
+  width: 100%;
+  height: 100%;
+}
+
+.banner-bg {
+  width: 100%;
+  height: 100%;
+  position: absolute;
+  top: 0;
+  left: 0;
+}
+
+.banner-overlay {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background: linear-gradient(135deg, rgba(76, 175, 80, 0.85) 0%, rgba(46, 125, 50, 0.9) 100%);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.banner-text {
+  text-align: center;
+  color: #fff;
+  padding: 0 40rpx;
+}
+
+.main-title {
+  font-size: 52rpx;
+  font-weight: 700;
+  margin-bottom: 20rpx;
+  display: block;
+  letter-spacing: 2rpx;
+  text-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.2);
+}
+
+.sub-title {
+  font-size: 30rpx;
+  opacity: 0.95;
+  line-height: 1.5;
+  display: block;
+  font-weight: 400;
+  text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.1);
+}
+
+// 信息卡片
+.info-card {
+  margin: 20rpx;
+  background-color: #fff;
+  border-radius: 20rpx;
+  box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.06);
+  overflow: hidden;
+  border: 1rpx solid #f5f5f5;
+}
+
+.card-header {
+  display: flex;
+  align-items: center;
+  padding: 32rpx;
+  background: linear-gradient(135deg, #f8fffe 0%, #f0fdf4 100%);
+  border-bottom: 1rpx solid #e8f5e8;
+}
+
+
+
+.card-title {
+  font-size: 34rpx;
+  font-weight: 600;
+  color: #1a1a1a;
+}
+
+.card-content {
+  padding: 30rpx;
+}
+
+// 描述文字
+.description-text {
+  font-size: 30rpx;
+  color: #4a5568;
+  line-height: 1.7;
+  font-weight: 400;
+}
+
+// 认证流程
+.process-list {
+  display: flex;
+  flex-direction: column;
+  gap: 28rpx;
+}
+
+.process-item {
+  display: flex;
+  align-items: flex-start;
+  gap: 24rpx;
+  padding: 24rpx;
+  background: linear-gradient(135deg, #f7fafc 0%, #edf2f7 100%);
+  border-radius: 16rpx;
+  border: 1rpx solid #e2e8f0;
+  transition: all 0.3s ease;
+  
+  &:hover {
+    transform: translateY(-2rpx);
+    box-shadow: 0 8rpx 20rpx rgba(0, 0, 0, 0.08);
+  }
+}
+
+.process-step {
+  flex-shrink: 0;
+}
+
+.step-number {
+  width: 64rpx;
+  height: 64rpx;
+  background: linear-gradient(135deg, #4CAF50 0%, #66BB6A 100%);
+  color: #fff;
+  border-radius: 32rpx;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  font-size: 32rpx;
+  font-weight: 600;
+  box-shadow: 0 4rpx 12rpx rgba(76, 175, 80, 0.3);
+}
+
+.process-content {
+  flex: 1;
+  padding-top: 4rpx;
+}
+
+.step-title {
+  font-size: 32rpx;
+  font-weight: 600;
+  color: #2d3748;
+  margin-bottom: 12rpx;
+  display: block;
+}
+
+.step-desc {
+  font-size: 28rpx;
+  color: #718096;
+  line-height: 1.5;
+  display: block;
+}
+
+// 认证优势
+.advantage-list {
+  display: flex;
+  flex-direction: column;
+  gap: 20rpx;
+}
+
+.advantage-item {
+  padding: 24rpx;
+  background: linear-gradient(135deg, #f8fff8 0%, #f0fdf4 100%);
+  border-radius: 16rpx;
+  border: 1rpx solid #e8f5e8;
+  transition: all 0.3s ease;
+  border-left: 4rpx solid #4CAF50;
+  
+  &:hover {
+    transform: translateY(-2rpx);
+    box-shadow: 0 8rpx 16rpx rgba(76, 175, 80, 0.1);
+  }
+}
+
+
+
+.advantage-text {
+  font-size: 30rpx;
+  color: #2c3e50;
+  font-weight: 500;
+  line-height: 1.4;
+}
+
+// 适用范围
+.scope-content {
+  padding: 28rpx;
+  background: linear-gradient(135deg, #f0fff4 0%, #ecfdf5 100%);
+  border-radius: 16rpx;
+  border: 1rpx solid #d1fae5;
+}
+
+.scope-text {
+  font-size: 30rpx;
+  color: #4a5568;
+  line-height: 1.7;
+  font-weight: 400;
+}
+
+// 联系方式
+.contact-list {
+  display: flex;
+  flex-direction: column;
+  gap: 24rpx;
+}
+
+.contact-item {
+  display: flex;
+  align-items: center;
+  padding: 20rpx 24rpx;
+  background: linear-gradient(135deg, #f7fafc 0%, #edf2f7 100%);
+  border-radius: 12rpx;
+  border: 1rpx solid #e2e8f0;
+}
+
+.contact-label {
+  font-size: 30rpx;
+  color: #718096;
+  width: 150rpx;
+  flex-shrink: 0;
+  font-weight: 500;
+}
+
+.contact-value {
+  font-size: 30rpx;
+  color: #2d3748;
+  font-weight: 600;
+}
+
+.contact-phone {
+  font-size: 30rpx;
+  color: #4CAF50;
+  font-weight: 600;
+  padding: 8rpx 16rpx;
+  background-color: #f0fdf4;
+  border-radius: 8rpx;
+  border: 1rpx solid #d1fae5;
+  transition: all 0.3s ease;
+  
+  &:active {
+    transform: scale(0.98);
+    background-color: #dcfce7;
+  }
+}
+
+// 底部提示
+.notice-card {
+  margin: 20rpx;
+  background: linear-gradient(135deg, #fff8e1 0%, #fffde7 100%);
+  border: 1rpx solid #f9e79f;
+  border-radius: 16rpx;
+  padding: 28rpx;
+  box-shadow: 0 4rpx 12rpx rgba(255, 193, 7, 0.1);
+}
+
+.notice-content {
+  text-align: center;
+}
+
+
+
+.notice-text {
+  font-size: 28rpx;
+  color: #8d4e00;
+  line-height: 1.6;
+  flex: 1;
+  font-weight: 500;
+}
+</style> 

+ 654 - 0
pages/service/expert-chat.vue

@@ -0,0 +1,654 @@
+<template>
+  <view class="chat-container">
+    <!-- 聊天消息列表 -->
+    <scroll-view 
+      class="message-list" 
+      scroll-y 
+      :scroll-top="scrollTop"
+      :scroll-with-animation="true"
+      @scroll="onScroll"
+    >
+      <view class="message-wrapper">
+        <!-- 日期分隔符 -->
+        <view class="date-divider" v-if="messageList.length > 0">
+          <text class="date-text">{{ getCurrentDate() }}</text>
+        </view>
+
+        <!-- 消息列表 -->
+        <view 
+          class="message-item"
+          :class="{ 'message-right': message.type === 'user', 'message-left': message.type === 'expert' }"
+          v-for="(message, index) in messageList"
+          :key="index"
+        >
+          <!-- 专家消息(左侧) -->
+          <template v-if="message.type === 'expert'">
+            <view class="avatar-container">
+              <image class="message-avatar" :src="expertInfo.avatar" mode="aspectFill"></image>
+            </view>
+            <view class="message-content-wrapper">
+              <view class="message-bubble expert-bubble">
+                <!-- 文本消息 -->
+                <text class="message-text" v-if="message.contentType === 'text'">{{ message.content }}</text>
+                
+                <!-- 图片消息 -->
+                <image 
+                  v-if="message.contentType === 'image'" 
+                  class="message-image" 
+                  :src="message.content" 
+                  mode="aspectFit"
+                  @click="previewImage(message.content)"
+                ></image>
+              </view>
+              <view class="message-time">{{ formatTime(message.timestamp) }}</view>
+            </view>
+          </template>
+
+          <!-- 用户消息(右侧) -->
+          <template v-else>
+            <view class="message-content-wrapper user-content">
+              <view class="message-bubble user-bubble">
+                <!-- 文本消息 -->
+                <text class="message-text" v-if="message.contentType === 'text'">{{ message.content }}</text>
+                
+                <!-- 图片消息 -->
+                <image 
+                  v-if="message.contentType === 'image'" 
+                  class="message-image" 
+                  :src="message.content" 
+                  mode="aspectFit"
+                  @click="previewImage(message.content)"
+                ></image>
+              </view>
+              <view class="message-time user-time">{{ formatTime(message.timestamp) }}</view>
+            </view>
+            <view class="avatar-container">
+              <image class="message-avatar" src="/static/icons/user icon.png" mode="aspectFill"></image>
+            </view>
+          </template>
+        </view>
+
+        <!-- 打字中状态 -->
+        <view class="typing-indicator" v-if="isTyping">
+          <view class="avatar-container">
+            <image class="message-avatar" :src="expertInfo.avatar" mode="aspectFill"></image>
+          </view>
+          <view class="typing-bubble">
+            <view class="typing-dots">
+              <view class="dot"></view>
+              <view class="dot"></view>
+              <view class="dot"></view>
+            </view>
+          </view>
+        </view>
+      </view>
+    </scroll-view>
+
+    <!-- 输入区域 -->
+    <view class="input-area">
+      <!-- 图片预览 -->
+      <view class="image-preview" v-if="selectedImages.length > 0">
+        <view class="preview-list">
+          <view 
+            class="preview-item"
+            v-for="(image, index) in selectedImages"
+            :key="index"
+          >
+            <image class="preview-image" :src="image" mode="aspectFill"></image>
+            <view class="remove-btn" @click="removeImage(index)">
+              <text class="remove-icon">×</text>
+            </view>
+          </view>
+        </view>
+      </view>
+
+      <!-- 输入工具栏 -->
+      <view class="input-toolbar">
+        <!-- 添加图片按钮 -->
+        <view class="tool-btn" @click="chooseImage">
+          <image class="tool-icon" src="/static/icons/camera.png" mode="aspectFit"></image>
+        </view>
+
+        <!-- 输入框 -->
+        <view class="input-wrapper">
+          <textarea 
+            class="message-input"
+            v-model="inputMessage"
+            placeholder="请输入您的问题..."
+            placeholder-style="color: #999;"
+            :auto-height="true"
+            :maxlength="500"
+            @focus="onInputFocus"
+            @blur="onInputBlur"
+          ></textarea>
+        </view>
+
+        <!-- 发送按钮 -->
+        <view 
+          class="send-btn"
+          :class="{ active: canSend }"
+          @click="sendMessage"
+        >
+          <text class="send-text">发送</text>
+        </view>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      expertId: '',
+      expertName: '',
+      inputMessage: '',
+      selectedImages: [],
+      scrollTop: 0,
+      isTyping: false,
+      
+      expertInfo: {
+        id: '',
+        name: '',
+        avatar: '/static/icons/professor.png'
+      },
+      
+      // 消息列表
+      messageList: [
+        {
+          id: 1,
+          type: 'expert',
+          contentType: 'text',
+          content: '您好!我是张教授,很高兴为您提供农业技术咨询服务。请问您遇到了什么问题?',
+          timestamp: Date.now() - 3600000
+        },
+        {
+          id: 2,
+          type: 'user',
+          contentType: 'text',
+          content: '教授您好,我想咨询一下水稻种植的相关问题',
+          timestamp: Date.now() - 3500000
+        },
+        {
+          id: 3,
+          type: 'expert',
+          contentType: 'text',
+          content: '好的,请您详细描述一下具体是什么问题?比如是关于播种、施肥、病虫害防治还是其他方面的?',
+          timestamp: Date.now() - 3400000
+        }
+      ]
+    }
+  },
+  
+  computed: {
+    canSend() {
+      return this.inputMessage.trim().length > 0 || this.selectedImages.length > 0;
+    }
+  },
+  
+  onLoad(options) {
+    if (options.expertId) {
+      this.expertId = options.expertId;
+      this.expertName = decodeURIComponent(options.expertName || '专家');
+      this.loadExpertInfo();
+    }
+    
+    // 设置页面标题
+    uni.setNavigationBarTitle({
+      title: this.expertName
+    });
+    
+    // 滚动到底部
+    this.$nextTick(() => {
+      this.scrollToBottom();
+    });
+  },
+  
+  methods: {
+    // 加载专家信息
+    loadExpertInfo() {
+      this.expertInfo = {
+        id: this.expertId,
+        name: this.expertName,
+        avatar: '/static/icons/professor.png'
+      };
+    },
+    
+    // 发送消息
+    sendMessage() {
+      if (!this.canSend) return;
+      
+      // 发送文本消息
+      if (this.inputMessage.trim()) {
+        const textMessage = {
+          id: Date.now(),
+          type: 'user',
+          contentType: 'text',
+          content: this.inputMessage.trim(),
+          timestamp: Date.now()
+        };
+        this.messageList.push(textMessage);
+        this.inputMessage = '';
+      }
+      
+      // 发送图片消息
+      if (this.selectedImages.length > 0) {
+        this.selectedImages.forEach(image => {
+          const imageMessage = {
+            id: Date.now() + Math.random(),
+            type: 'user',
+            contentType: 'image',
+            content: image,
+            timestamp: Date.now()
+          };
+          this.messageList.push(imageMessage);
+        });
+        this.selectedImages = [];
+      }
+      
+      // 滚动到底部
+      this.$nextTick(() => {
+        this.scrollToBottom();
+      });
+      
+      // 模拟专家回复
+      this.simulateExpertReply();
+    },
+    
+    // 模拟专家回复
+    simulateExpertReply() {
+      this.isTyping = true;
+      
+      setTimeout(() => {
+        this.isTyping = false;
+        
+        const replies = [
+          '根据您的描述,我建议您可以从以下几个方面来处理...',
+          '这个问题比较常见,通常是由于以下原因造成的...',
+          '从您提供的信息来看,建议您先检查一下土壤情况...',
+          '我理解您的担心,这种情况下最好的解决方案是...'
+        ];
+        
+        const randomReply = replies[Math.floor(Math.random() * replies.length)];
+        
+        const expertMessage = {
+          id: Date.now(),
+          type: 'expert',
+          contentType: 'text',
+          content: randomReply,
+          timestamp: Date.now()
+        };
+        
+        this.messageList.push(expertMessage);
+        
+        this.$nextTick(() => {
+          this.scrollToBottom();
+        });
+      }, 2000);
+    },
+    
+    // 选择图片
+    chooseImage() {
+      const maxImages = 3 - this.selectedImages.length;
+      if (maxImages <= 0) {
+        uni.showToast({
+          title: '最多可选择3张图片',
+          icon: 'none'
+        });
+        return;
+      }
+      
+      uni.chooseImage({
+        count: maxImages,
+        sizeType: ['compressed'],
+        sourceType: ['album', 'camera'],
+        success: (res) => {
+          this.selectedImages = this.selectedImages.concat(res.tempFilePaths);
+        }
+      });
+    },
+    
+    // 移除图片
+    removeImage(index) {
+      this.selectedImages.splice(index, 1);
+    },
+    
+    // 预览图片
+    previewImage(current) {
+      // 收集所有图片消息的URL
+      const imageUrls = this.messageList
+        .filter(msg => msg.contentType === 'image')
+        .map(msg => msg.content);
+      
+      uni.previewImage({
+        current: current,
+        urls: imageUrls
+      });
+    },
+    
+    // 滚动到底部
+    scrollToBottom() {
+      const query = uni.createSelectorQuery().in(this);
+      query.select('.message-wrapper').boundingClientRect();
+      query.exec((res) => {
+        if (res[0]) {
+          this.scrollTop = res[0].height;
+        }
+      });
+    },
+    
+    // 滚动事件
+    onScroll(e) {
+      // 可以在这里处理滚动相关逻辑
+    },
+    
+    // 输入框聚焦
+    onInputFocus() {
+      setTimeout(() => {
+        this.scrollToBottom();
+      }, 300);
+    },
+    
+    // 输入框失焦
+    onInputBlur() {
+      // 可以在这里处理失焦逻辑
+    },
+    
+    // 格式化时间
+    formatTime(timestamp) {
+      const date = new Date(timestamp);
+      const now = new Date();
+      const diff = now - date;
+      
+      if (diff < 60000) { // 1分钟内
+        return '刚刚';
+      } else if (diff < 3600000) { // 1小时内
+        return `${Math.floor(diff / 60000)}分钟前`;
+      } else if (date.toDateString() === now.toDateString()) { // 今天
+        return date.toLocaleTimeString('zh-CN', { hour12: false, hour: '2-digit', minute: '2-digit' });
+      } else {
+        return date.toLocaleDateString('zh-CN', { month: '2-digit', day: '2-digit' });
+      }
+    },
+    
+    // 获取当前日期
+    getCurrentDate() {
+      return new Date().toLocaleDateString('zh-CN', { 
+        year: 'numeric', 
+        month: 'long', 
+        day: 'numeric' 
+      });
+    }
+  }
+}
+</script>
+
+<style lang="scss">
+.chat-container {
+  height: 100vh;
+  display: flex;
+  flex-direction: column;
+  background-color: #f5f5f5;
+}
+
+// 消息列表
+.message-list {
+  flex: 1;
+  padding: 20rpx 0;
+}
+
+.message-wrapper {
+  padding: 0 20rpx;
+}
+
+// 日期分隔符
+.date-divider {
+  text-align: center;
+  margin: 20rpx 0;
+}
+
+.date-text {
+  padding: 8rpx 20rpx;
+  background-color: rgba(0, 0, 0, 0.1);
+  color: #666;
+  font-size: 22rpx;
+  border-radius: 16rpx;
+}
+
+// 消息项
+.message-item {
+  display: flex;
+  margin-bottom: 20rpx;
+  
+  &.message-left {
+    justify-content: flex-start;
+  }
+  
+  &.message-right {
+    justify-content: flex-end;
+  }
+}
+
+.avatar-container {
+  flex-shrink: 0;
+  margin: 0 16rpx;
+}
+
+.message-avatar {
+  width: 80rpx;
+  height: 80rpx;
+  border-radius: 40rpx;
+  border: 2rpx solid #f0f0f0;
+}
+
+// 消息内容
+.message-content-wrapper {
+  max-width: 500rpx;
+  
+  &.user-content {
+    display: flex;
+    flex-direction: column;
+    align-items: flex-end;
+  }
+}
+
+.message-bubble {
+  padding: 16rpx 20rpx;
+  border-radius: 20rpx;
+  margin-bottom: 8rpx;
+  word-wrap: break-word;
+  
+  &.expert-bubble {
+    background-color: #fff;
+    border-top-left-radius: 8rpx;
+    box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
+  }
+  
+  &.user-bubble {
+    background-color: #4CAF50;
+    border-top-right-radius: 8rpx;
+    
+    .message-text {
+      color: #fff;
+    }
+  }
+}
+
+.message-text {
+  font-size: 28rpx;
+  line-height: 1.4;
+  color: #333;
+}
+
+.message-image {
+  max-width: 300rpx;
+  max-height: 300rpx;
+  border-radius: 12rpx;
+}
+
+.message-time {
+  font-size: 22rpx;
+  color: #999;
+  
+  &.user-time {
+    text-align: right;
+  }
+}
+
+// 打字中指示器
+.typing-indicator {
+  display: flex;
+  align-items: center;
+  margin-bottom: 20rpx;
+}
+
+.typing-bubble {
+  background-color: #fff;
+  padding: 16rpx 20rpx;
+  border-radius: 20rpx;
+  border-top-left-radius: 8rpx;
+  margin-left: 16rpx;
+  box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
+}
+
+.typing-dots {
+  display: flex;
+  gap: 6rpx;
+}
+
+.dot {
+  width: 8rpx;
+  height: 8rpx;
+  background-color: #999;
+  border-radius: 50%;
+  animation: typing 1.4s infinite;
+  
+  &:nth-child(2) {
+    animation-delay: 0.2s;
+  }
+  
+  &:nth-child(3) {
+    animation-delay: 0.4s;
+  }
+}
+
+@keyframes typing {
+  0%, 60%, 100% {
+    transform: translateY(0);
+    opacity: 0.5;
+  }
+  30% {
+    transform: translateY(-10rpx);
+    opacity: 1;
+  }
+}
+
+// 输入区域
+.input-area {
+  background-color: #fff;
+  border-top: 1rpx solid #e5e5e5;
+  padding-bottom: env(safe-area-inset-bottom);
+}
+
+// 图片预览
+.image-preview {
+  padding: 20rpx;
+  border-bottom: 1rpx solid #f0f0f0;
+}
+
+.preview-list {
+  display: flex;
+  gap: 16rpx;
+}
+
+.preview-item {
+  position: relative;
+  width: 120rpx;
+  height: 120rpx;
+}
+
+.preview-image {
+  width: 100%;
+  height: 100%;
+  border-radius: 12rpx;
+}
+
+.remove-btn {
+  position: absolute;
+  top: -8rpx;
+  right: -8rpx;
+  width: 32rpx;
+  height: 32rpx;
+  background-color: #ff4757;
+  border-radius: 16rpx;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.remove-icon {
+  color: #fff;
+  font-size: 20rpx;
+  font-weight: bold;
+}
+
+// 输入工具栏
+.input-toolbar {
+  display: flex;
+  align-items: flex-end;
+  padding: 20rpx;
+  gap: 16rpx;
+}
+
+.tool-btn {
+  width: 60rpx;
+  height: 60rpx;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background-color: #f5f5f5;
+  border-radius: 30rpx;
+}
+
+.tool-icon {
+  width: 32rpx;
+  height: 32rpx;
+}
+
+.input-wrapper {
+  flex: 1;
+  background-color: #f8f8f8;
+  border-radius: 24rpx;
+  padding: 16rpx 20rpx;
+  min-height: 48rpx;
+  max-height: 200rpx;
+}
+
+.message-input {
+  width: 100%;
+  font-size: 28rpx;
+  line-height: 1.4;
+  min-height: 48rpx;
+}
+
+.send-btn {
+  padding: 16rpx 24rpx;
+  background-color: #e0e0e0;
+  border-radius: 24rpx;
+  transition: background-color 0.2s ease;
+  
+  &.active {
+    background-color: #4CAF50;
+    
+    .send-text {
+      color: #fff;
+    }
+  }
+}
+
+.send-text {
+  font-size: 28rpx;
+  color: #999;
+  font-weight: bold;
+}
+</style> 

+ 368 - 0
pages/service/expert-detail.vue

@@ -0,0 +1,368 @@
+<template>
+  <view class="expert-detail-container">
+    <!-- 专家基本信息卡片 -->
+    <view class="expert-info-card">
+      <view class="expert-header">
+        <view class="avatar-section">
+          <view class="avatar-container">
+            <image class="expert-avatar" :src="expertInfo.avatar" mode="aspectFill"></image>
+            <view class="online-status" v-if="expertInfo.isOnline"></view>
+          </view>
+        </view>
+        
+        <view class="basic-info">
+          <view class="expert-name">{{ expertInfo.name }}</view>
+          <view class="expert-title">{{ expertInfo.title }}</view>
+          <view class="expert-unit">{{ expertInfo.unit }}</view>
+          
+          <view class="stats-row">
+            <view class="stat-item">
+              <text class="stat-number">{{ expertInfo.rating }}</text>
+              <text class="stat-label">评分</text>
+            </view>
+            <view class="stat-item">
+              <text class="stat-number">{{ expertInfo.consultCount }}</text>
+              <text class="stat-label">咨询数</text>
+            </view>
+            <view class="stat-item">
+              <text class="stat-number">{{ expertInfo.experience }}</text>
+              <text class="stat-label">从业年限</text>
+            </view>
+          </view>
+        </view>
+      </view>
+    </view>
+
+    <!-- 擅长领域 -->
+    <view class="expertise-card">
+      <view class="card-title">
+        <text>擅长领域</text>
+      </view>
+      <view class="expertise-tags">
+        <view 
+          class="expertise-tag"
+          v-for="(tag, index) in expertInfo.expertise"
+          :key="index"
+        >
+          {{ tag }}
+        </view>
+      </view>
+    </view>
+
+    <!-- 专家简介 -->
+    <view class="introduction-card">
+      <view class="card-title">
+        <text>专家简介</text>
+      </view>
+      <view class="introduction-content">
+        <text class="introduction-text">{{ expertInfo.introduction }}</text>
+      </view>
+    </view>
+
+    <!-- 服务时间 -->
+    <view class="service-time-card">
+      <view class="card-title">
+        <text>服务时间</text>
+      </view>
+      <view class="service-time-content">
+        <view class="time-item">
+          <text class="time-label">工作日:</text>
+          <text class="time-value">{{ expertInfo.serviceTime.weekday }}</text>
+        </view>
+        <view class="time-item">
+          <text class="time-label">周末:</text>
+          <text class="time-value">{{ expertInfo.serviceTime.weekend }}</text>
+        </view>
+      </view>
+    </view>
+
+    <!-- 底部咨询按钮 -->
+    <view class="bottom-action-bar">
+      <view class="action-btn" @click="startConsult">
+        <text class="btn-text">在线咨询</text>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      expertId: '',
+      expertInfo: {
+        id: '',
+        name: '',
+        title: '',
+        unit: '',
+        avatar: '',
+        expertise: [],
+        introduction: '',
+        isOnline: false,
+        rating: 0,
+        consultCount: 0,
+        experience: 0,
+        serviceTime: {
+          weekday: '',
+          weekend: ''
+        }
+      }
+    }
+  },
+  
+  onLoad(options) {
+    if (options.id) {
+      this.expertId = options.id;
+      this.loadExpertDetail();
+    }
+  },
+  
+  methods: {
+    // 加载专家详情
+    loadExpertDetail() {
+      uni.showLoading({ title: '加载中...' });
+      
+      // 模拟API调用,实际应用中需要根据expertId从API获取数据
+      setTimeout(() => {
+                 const mockData = {
+           id: this.expertId,
+           name: '张教授',
+           title: '研究员',
+           unit: '农业科学院植物保护研究所',
+           avatar: '/static/icons/professor.png',
+           expertise: ['水稻种植', '病虫害防治', '土壤改良', '绿色防控', '有机农业'],
+          introduction: '农业技术推广研究员,从事农作物病虫害防治和绿色种植技术研究20余年。主持完成国家和省部级科研项目10余项,发表学术论文50多篇,获得农业技术推广奖3项。擅长水稻、小麦等主要粮食作物的病虫害综合防治,在生物防治、绿色防控等方面有丰富的实践经验。',
+          isOnline: true,
+          rating: 4.9,
+          consultCount: 156,
+          experience: 20,
+          serviceTime: {
+            weekday: '09:00-18:00',
+            weekend: '09:00-17:00'
+          }
+        };
+        
+        this.expertInfo = mockData;
+        
+        // 设置页面标题
+        uni.setNavigationBarTitle({
+          title: `${mockData.name} - 专家详情`
+        });
+        
+        uni.hideLoading();
+      }, 1000);
+    },
+    
+    // 开始咨询
+    startConsult() {
+      uni.navigateTo({
+        url: `/pages/service/expert-chat?expertId=${this.expertInfo.id}&expertName=${encodeURIComponent(this.expertInfo.name)}`
+      });
+    }
+  }
+}
+</script>
+
+<style lang="scss">
+.expert-detail-container {
+  min-height: 100vh;
+  background-color: #f5f5f5;
+  padding-bottom: calc(120rpx + env(safe-area-inset-bottom));
+}
+
+// 专家信息卡片
+.expert-info-card {
+  margin: 20rpx;
+  background-color: #fff;
+  border-radius: 16rpx;
+  padding: 30rpx;
+  box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
+}
+
+.expert-header {
+  display: flex;
+  align-items: center;
+  gap: 24rpx;
+}
+
+.avatar-section {
+  flex-shrink: 0;
+}
+
+.avatar-container {
+  position: relative;
+}
+
+.expert-avatar {
+  width: 120rpx;
+  height: 120rpx;
+  border-radius: 60rpx;
+  border: 4rpx solid #f0f0f0;
+}
+
+.online-status {
+  position: absolute;
+  bottom: 0;
+  right: 0;
+  width: 32rpx;
+  height: 32rpx;
+  background-color: #52c41a;
+  border-radius: 16rpx;
+  border: 4rpx solid #fff;
+}
+
+.basic-info {
+  flex: 1;
+}
+
+.expert-name {
+  font-size: 36rpx;
+  font-weight: bold;
+  color: #333;
+  margin-bottom: 8rpx;
+}
+
+.expert-title {
+  font-size: 28rpx;
+  color: #4CAF50;
+  margin-bottom: 4rpx;
+}
+
+.expert-unit {
+  font-size: 26rpx;
+  color: #666;
+  margin-bottom: 16rpx;
+}
+
+.stats-row {
+  display: flex;
+  gap: 24rpx;
+}
+
+.stat-item {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+}
+
+.stat-number {
+  font-size: 28rpx;
+  font-weight: bold;
+  color: #4CAF50;
+}
+
+.stat-label {
+  font-size: 22rpx;
+  color: #999;
+  margin-top: 4rpx;
+}
+
+// 通用卡片样式
+.expertise-card,
+.introduction-card,
+.service-time-card {
+  margin: 0 20rpx 20rpx;
+  background-color: #fff;
+  border-radius: 16rpx;
+  padding: 30rpx;
+  box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
+}
+
+.card-title {
+  font-size: 30rpx;
+  font-weight: bold;
+  color: #333;
+  margin-bottom: 20rpx;
+  padding-bottom: 16rpx;
+  border-bottom: 2rpx solid #f5f5f5;
+}
+
+// 擅长领域
+.expertise-tags {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 12rpx;
+}
+
+.expertise-tag {
+  padding: 8rpx 16rpx;
+  background-color: #e6f7ff;
+  color: #1890ff;
+  font-size: 26rpx;
+  border-radius: 16rpx;
+  white-space: nowrap;
+}
+
+// 专家简介
+.introduction-content {
+  padding: 20rpx;
+  background-color: #f8f9fa;
+  border-radius: 12rpx;
+  border-left: 4rpx solid #4CAF50;
+}
+
+.introduction-text {
+  font-size: 28rpx;
+  color: #666;
+  line-height: 1.6;
+}
+
+// 服务时间
+.service-time-content {
+  display: flex;
+  flex-direction: column;
+  gap: 16rpx;
+}
+
+.time-item {
+  display: flex;
+  align-items: center;
+}
+
+.time-label {
+  font-size: 28rpx;
+  color: #666;
+  width: 120rpx;
+}
+
+.time-value {
+  font-size: 28rpx;
+  color: #333;
+  font-weight: 500;
+}
+
+// 底部操作按钮
+.bottom-action-bar {
+  position: fixed;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  padding: 20rpx 30rpx;
+  padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
+  background-color: #fff;
+  border-top: 1rpx solid #f0f0f0;
+  z-index: 100;
+  box-shadow: 0 -2rpx 8rpx rgba(0, 0, 0, 0.05);
+}
+
+.action-btn {
+  width: 100%;
+  height: 88rpx;
+  background-color: #4CAF50;
+  border-radius: 44rpx;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  transition: background-color 0.2s ease;
+  
+  &:active {
+    background-color: #45a049;
+  }
+}
+
+.btn-text {
+  font-size: 32rpx;
+  color: #fff;
+  font-weight: bold;
+}
+</style> 

+ 401 - 0
pages/service/expert.vue

@@ -0,0 +1,401 @@
+<template>
+  <view class="expert-container">
+    <!-- 分类筛选区域 -->
+    <view class="category-section">
+      <scroll-view class="category-scroll" scroll-x show-scrollbar="false">
+        <view class="category-list">
+          <view 
+            class="category-item"
+            :class="{ active: selectedCategory === item.value }"
+            v-for="item in categoryList"
+            :key="item.value"
+            @click="selectCategory(item.value)"
+          >
+            <text class="category-text">{{ item.label }}</text>
+          </view>
+        </view>
+      </scroll-view>
+    </view>
+
+    <!-- 搜索区域 -->
+    <view class="search-section">
+      <view class="search-box">
+        <image class="search-icon" src="/static/icons/search.png" mode="aspectFit"></image>
+        <input 
+          class="search-input" 
+          placeholder="搜索专家姓名或擅长方向" 
+          placeholder-style="color: #999;"
+          v-model="searchKeyword"
+          @confirm="handleSearch"
+        />
+      </view>
+    </view>
+
+    <!-- 专家列表 -->
+    <view class="expert-list-container">
+      <view class="expert-list">
+        <view 
+          class="expert-card"
+          v-for="expert in filteredExpertList"
+          :key="expert.id"
+          @click="navigateToDetail(expert)"
+        >
+          <view class="expert-info">
+            <!-- 左侧头像和基本信息 -->
+            <view class="expert-basic">
+              <view class="avatar-container">
+                <image class="expert-avatar" :src="expert.avatar" mode="aspectFill"></image>
+                <view class="online-status" v-if="expert.isOnline"></view>
+              </view>
+              <view class="expert-details">
+                <view class="expert-name">{{ expert.name }}</view>
+                <view class="expert-title">{{ expert.title }}</view>
+                <view class="expert-unit">{{ expert.unit }}</view>
+              </view>
+            </view>
+            
+            <!-- 右侧擅长领域和咨询按钮 -->
+            <view class="expert-actions">
+              <view class="expertise-tags">
+                <view 
+                  class="expertise-tag"
+                  v-for="(tag, index) in expert.expertise.slice(0, 3)"
+                  :key="index"
+                >
+                  {{ tag }}
+                </view>
+              </view>
+              <view class="consult-btn" @click.stop="startConsult(expert)">
+                <text class="consult-text">咨询</text>
+              </view>
+            </view>
+          </view>
+        </view>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      selectedCategory: 'all',
+      searchKeyword: '',
+      
+      // 分类选项
+      categoryList: [
+        { label: '全部', value: 'all' },
+        { label: '种植技术', value: 'planting' },
+        { label: '植物保护', value: 'protection' },
+        { label: '土壤肥料', value: 'soil' },
+        { label: '气象指导', value: 'weather' },
+        { label: '病虫害防治', value: 'pest' },
+        { label: '农机使用', value: 'machinery' }
+      ],
+      
+      // 专家列表数据
+      expertList: [
+        {
+          id: 1,
+          name: '张教授',
+          title: '研究员',
+          unit: '农业科学院',
+          avatar: '/static/icons/professor.png',
+          expertise: ['水稻种植', '病虫害防治', '土壤改良'],
+          category: 'planting',
+          isOnline: true,
+          rating: 4.9,
+          consultCount: 156
+        },
+        {
+          id: 2,
+          name: '李专家',
+          title: '高级农艺师',
+          unit: '植保站',
+          avatar: '/static/icons/professor.png',
+          expertise: ['植物保护', '农药使用', '生物防治'],
+          category: 'protection',
+          isOnline: false,
+          rating: 4.8,
+          consultCount: 203
+        },
+        {
+          id: 3,
+          name: '王老师',
+          title: '副教授',
+          unit: '农业大学',
+          avatar: '/static/icons/professor.png',
+          expertise: ['土壤检测', '施肥技术', '营养诊断'],
+          category: 'soil',
+          isOnline: true,
+          rating: 4.7,
+          consultCount: 89
+        },
+        {
+          id: 4,
+          name: '陈工程师',
+          title: '农机专家',
+          unit: '农机推广站',
+          avatar: '/static/icons/professor.png',
+          expertise: ['农机维修', '设备选型', '机械化作业'],
+          category: 'machinery',
+          isOnline: true,
+          rating: 4.6,
+          consultCount: 134
+        },
+        {
+          id: 5,
+          name: '刘博士',
+          title: '气象专家',
+          unit: '气象局',
+          avatar: '/static/icons/professor.png',
+          expertise: ['天气预报', '灾害预警', '农业气象'],
+          category: 'weather',
+          isOnline: false,
+          rating: 4.8,
+          consultCount: 178
+        }
+      ]
+    }
+  },
+  
+  computed: {
+    filteredExpertList() {
+      let list = this.expertList;
+      
+      // 按分类筛选
+      if (this.selectedCategory !== 'all') {
+        list = list.filter(expert => expert.category === this.selectedCategory);
+      }
+      
+      // 按搜索关键词筛选
+      if (this.searchKeyword.trim()) {
+        const keyword = this.searchKeyword.trim().toLowerCase();
+        list = list.filter(expert => 
+          expert.name.toLowerCase().includes(keyword) ||
+          expert.expertise.some(tag => tag.toLowerCase().includes(keyword)) ||
+          expert.title.toLowerCase().includes(keyword) ||
+          expert.unit.toLowerCase().includes(keyword)
+        );
+      }
+      
+      return list;
+    }
+  },
+  
+  methods: {
+    // 选择分类
+    selectCategory(category) {
+      this.selectedCategory = category;
+    },
+    
+    // 搜索处理
+    handleSearch() {
+      // 搜索逻辑已在computed中处理
+    },
+    
+    // 导航到专家详情页
+    navigateToDetail(expert) {
+      uni.navigateTo({
+        url: `/pages/service/expert-detail?id=${expert.id}&name=${encodeURIComponent(expert.name)}`
+      });
+    },
+    
+    // 开始咨询
+    startConsult(expert) {
+      uni.navigateTo({
+        url: `/pages/service/expert-chat?expertId=${expert.id}&expertName=${encodeURIComponent(expert.name)}`
+      });
+    }
+  }
+}
+</script>
+
+<style lang="scss">
+.expert-container {
+  min-height: 100vh;
+  background-color: #f5f5f5;
+}
+
+// 分类筛选区域
+.category-section {
+  background-color: #fff;
+  border-bottom: 1rpx solid #f0f0f0;
+}
+
+.category-scroll {
+  white-space: nowrap;
+}
+
+.category-list {
+  display: inline-flex;
+  padding: 0 20rpx;
+}
+
+.category-item {
+  flex-shrink: 0;
+  padding: 24rpx 32rpx;
+  margin-right: 8rpx;
+  font-size: 28rpx;
+  color: #666;
+  border-radius: 32rpx;
+  transition: all 0.2s ease;
+  
+  &.active {
+    color: #4CAF50;
+    background-color: #f0fdf4;
+    font-weight: bold;
+  }
+}
+
+// 搜索区域
+.search-section {
+  background-color: #fff;
+  padding: 20rpx;
+  border-bottom: 1rpx solid #f0f0f0;
+}
+
+.search-box {
+  display: flex;
+  align-items: center;
+  background-color: #f8f8f8;
+  border-radius: 32rpx;
+  padding: 16rpx 24rpx;
+}
+
+.search-icon {
+  width: 32rpx;
+  height: 32rpx;
+  margin-right: 16rpx;
+}
+
+.search-input {
+  flex: 1;
+  font-size: 28rpx;
+  line-height: 1.5;
+}
+
+// 专家列表
+.expert-list-container {
+  padding: 20rpx;
+}
+
+.expert-list {
+  display: flex;
+  flex-direction: column;
+  gap: 16rpx;
+}
+
+.expert-card {
+  background-color: #fff;
+  border-radius: 16rpx;
+  padding: 24rpx;
+  box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
+  transition: transform 0.2s ease;
+  
+  &:active {
+    transform: scale(0.98);
+  }
+}
+
+.expert-info {
+  display: flex;
+  justify-content: space-between;
+  align-items: flex-start;
+}
+
+// 左侧基本信息
+.expert-basic {
+  display: flex;
+  align-items: center;
+  flex: 1;
+  margin-right: 20rpx;
+}
+
+.avatar-container {
+  position: relative;
+  margin-right: 20rpx;
+}
+
+.expert-avatar {
+  width: 100rpx;
+  height: 100rpx;
+  border-radius: 50rpx;
+  border: 3rpx solid #f0f0f0;
+}
+
+.online-status {
+  position: absolute;
+  bottom: 0;
+  right: 0;
+  width: 24rpx;
+  height: 24rpx;
+  background-color: #52c41a;
+  border-radius: 12rpx;
+  border: 3rpx solid #fff;
+}
+
+.expert-details {
+  flex: 1;
+}
+
+.expert-name {
+  font-size: 32rpx;
+  font-weight: bold;
+  color: #333;
+  margin-bottom: 8rpx;
+}
+
+.expert-title {
+  font-size: 26rpx;
+  color: #4CAF50;
+  margin-bottom: 4rpx;
+}
+
+.expert-unit {
+  font-size: 24rpx;
+  color: #999;
+}
+
+// 右侧操作区域
+.expert-actions {
+  display: flex;
+  flex-direction: column;
+  align-items: flex-end;
+  gap: 16rpx;
+}
+
+.expertise-tags {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 8rpx;
+  justify-content: flex-end;
+}
+
+.expertise-tag {
+  padding: 6rpx 12rpx;
+  background-color: #e6f7ff;
+  color: #1890ff;
+  font-size: 22rpx;
+  border-radius: 12rpx;
+  white-space: nowrap;
+}
+
+.consult-btn {
+  padding: 12rpx 24rpx;
+  background-color: #4CAF50;
+  border-radius: 20rpx;
+  transition: background-color 0.2s ease;
+  
+  &:active {
+    background-color: #45a049;
+  }
+}
+
+.consult-text {
+  font-size: 26rpx;
+  color: #fff;
+  font-weight: bold;
+}
+</style> 

+ 473 - 0
pages/service/insurance.vue

@@ -0,0 +1,473 @@
+<template>
+  <view class="insurance-container">
+    <!-- 顶部横幅 -->
+    <view class="banner-section">
+      <view class="banner-content">
+        <image class="banner-bg" src="/static/images/agriculture/rice-field2.svg" mode="aspectFill"></image>
+        <view class="banner-overlay">
+          <view class="banner-text">
+            <text class="main-title">农业保险服务</text>
+            <text class="sub-title">为您的农田和收成多一份保障</text>
+          </view>
+        </view>
+      </view>
+    </view>
+
+    <!-- 什么是农业保险 -->
+    <view class="info-card">
+      <view class="card-header">
+        <text class="card-title">什么是农业保险?</text>
+      </view>
+      <view class="card-content">
+        <text class="description-text">
+          农业保险是由保险公司对种植业、养殖业因自然灾害、病虫害等造成的损失进行保障的专项服务。它能有效分散农业风险、保障农户收益,为农业生产提供坚实的风险保障屏障,让农民朋友能够安心从事农业生产活动。
+        </text>
+      </view>
+    </view>
+
+    <!-- 可投保项目 -->
+    <view class="info-card">
+      <view class="card-header">
+        <text class="card-title">可投保项目</text>
+      </view>
+      <view class="card-content">
+        <view class="insurance-types">
+          <view class="type-item">
+            <view class="type-header">
+              <text class="type-title">作物种植险</text>
+            </view>
+            <text class="type-desc">水稻、小麦、玉米等主要农作物种植保障</text>
+          </view>
+          
+          <view class="type-item">
+            <view class="type-header">
+              <text class="type-title">农机具保险</text>
+            </view>
+            <text class="type-desc">拖拉机、植保无人机等农机设备保障</text>
+          </view>
+          
+          <view class="type-item">
+            <view class="type-header">
+              <text class="type-title">农田财产保险</text>
+            </view>
+            <text class="type-desc">农田设施、仓储设备等财产保障</text>
+          </view>
+          
+          <view class="type-item">
+            <view class="type-header">
+              <text class="type-title">农业自然灾害险</text>
+            </view>
+            <text class="type-desc">洪涝、干旱、冰雹等自然灾害保障</text>
+          </view>
+        </view>
+      </view>
+    </view>
+
+    <!-- 参保流程 -->
+    <view class="info-card">
+      <view class="card-header">
+        <text class="card-title">参保流程</text>
+      </view>
+      <view class="card-content">
+        <view class="process-steps">
+          <view class="step-item">
+            <view class="step-number">1</view>
+            <view class="step-content">
+              <text class="step-title">咨询保险方案</text>
+              <text class="step-desc">了解各类保险产品和保障范围</text>
+            </view>
+          </view>
+          
+          <view class="step-item">
+            <view class="step-number">2</view>
+            <view class="step-content">
+              <text class="step-title">提交申请材料</text>
+              <text class="step-desc">准备身份证明、土地证明等相关资料</text>
+            </view>
+          </view>
+          
+          <view class="step-item">
+            <view class="step-number">3</view>
+            <view class="step-content">
+              <text class="step-title">线下签约与缴费</text>
+              <text class="step-desc">前往服务点签署保险合同并缴纳保费</text>
+            </view>
+          </view>
+          
+          <view class="step-item">
+            <view class="step-number">4</view>
+            <view class="step-content">
+              <text class="step-title">获得保障凭证</text>
+              <text class="step-desc">领取保险单据,享受保险保障服务</text>
+            </view>
+          </view>
+        </view>
+      </view>
+    </view>
+
+    <!-- 服务优势 -->
+    <view class="info-card">
+      <view class="card-header">
+        <text class="card-title">服务优势</text>
+      </view>
+      <view class="card-content">
+        <view class="advantage-list">
+          <view class="advantage-item">
+            <text class="advantage-text">政府补贴保费,农户负担低</text>
+          </view>
+          <view class="advantage-item">
+            <text class="advantage-text">保障范围广,理赔流程明确</text>
+          </view>
+          <view class="advantage-item">
+            <text class="advantage-text">减少自然灾害带来的收入风险</text>
+          </view>
+          <view class="advantage-item">
+            <text class="advantage-text">专业服务团队,全程跟踪保障</text>
+          </view>
+        </view>
+      </view>
+    </view>
+
+    <!-- 联系方式 -->
+    <view class="info-card">
+      <view class="card-header">
+        <text class="card-title">联系方式</text>
+      </view>
+      <view class="card-content">
+        <view class="contact-list">
+          <view class="contact-item">
+            <view class="contact-label">联系单位:</view>
+            <text class="contact-value">农业保险服务点</text>
+          </view>
+          <view class="contact-item">
+            <view class="contact-label">联系人:</view>
+            <text class="contact-value">张老师</text>
+          </view>
+          <view class="contact-item">
+            <view class="contact-label">联系电话:</view>
+            <text class="contact-phone" @click="makePhoneCall">400-456-7890</text>
+          </view>
+          <view class="contact-item">
+            <view class="contact-label">服务时间:</view>
+            <text class="contact-value">工作日 9:00-17:30</text>
+          </view>
+        </view>
+      </view>
+    </view>
+
+    <!-- 底部温馨提示 -->
+    <view class="notice-card">
+      <view class="notice-content">
+        <text class="notice-text">
+          农业保险服务为线下办理业务,平台仅提供信息展示与咨询对接服务,如有需求,请拨打电话或前往就近服务站。
+        </text>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  methods: {
+    // 拨打电话
+    makePhoneCall() {
+      uni.makePhoneCall({
+        phoneNumber: '400-456-7890',
+        fail: (err) => {
+          console.log('拨打电话失败:', err);
+          uni.showToast({
+            title: '拨打电话失败',
+            icon: 'none'
+          });
+        }
+      });
+    }
+  }
+}
+</script>
+
+<style lang="scss">
+.insurance-container {
+  min-height: 100vh;
+  background-color: #f5f5f5;
+  padding-bottom: 40rpx;
+}
+
+// 顶部横幅
+.banner-section {
+  position: relative;
+  height: 400rpx;
+  overflow: hidden;
+}
+
+.banner-content {
+  position: relative;
+  width: 100%;
+  height: 100%;
+}
+
+.banner-bg {
+  width: 100%;
+  height: 100%;
+  position: absolute;
+  top: 0;
+  left: 0;
+}
+
+.banner-overlay {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background: linear-gradient(135deg, rgba(76, 175, 80, 0.85) 0%, rgba(46, 125, 50, 0.9) 100%);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.banner-text {
+  text-align: center;
+  color: #fff;
+  padding: 0 40rpx;
+}
+
+.main-title {
+  font-size: 52rpx;
+  font-weight: 700;
+  margin-bottom: 20rpx;
+  display: block;
+  letter-spacing: 2rpx;
+  text-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.2);
+}
+
+.sub-title {
+  font-size: 30rpx;
+  opacity: 0.95;
+  line-height: 1.5;
+  display: block;
+  font-weight: 400;
+  text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.1);
+}
+
+// 信息卡片
+.info-card {
+  margin: 20rpx;
+  background-color: #fff;
+  border-radius: 20rpx;
+  box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.06);
+  overflow: hidden;
+  border: 1rpx solid #f5f5f5;
+}
+
+.card-header {
+  display: flex;
+  align-items: center;
+  padding: 32rpx;
+  background: linear-gradient(135deg, #f8fffe 0%, #f0fdf4 100%);
+  border-bottom: 1rpx solid #e8f5e8;
+}
+
+.card-title {
+  font-size: 34rpx;
+  font-weight: 600;
+  color: #1a1a1a;
+}
+
+.card-content {
+  padding: 30rpx;
+}
+
+// 描述文字
+.description-text {
+  font-size: 30rpx;
+  color: #4a5568;
+  line-height: 1.7;
+  font-weight: 400;
+}
+
+// 可投保项目
+.insurance-types {
+  display: flex;
+  flex-direction: column;
+  gap: 20rpx;
+}
+
+.type-item {
+  padding: 24rpx;
+  background: linear-gradient(135deg, #f7fafc 0%, #edf2f7 100%);
+  border-radius: 16rpx;
+  border: 1rpx solid #e2e8f0;
+  border-left: 4rpx solid #4CAF50;
+}
+
+.type-header {
+  margin-bottom: 12rpx;
+}
+
+.type-title {
+  font-size: 32rpx;
+  font-weight: 600;
+  color: #2d3748;
+}
+
+.type-desc {
+  font-size: 28rpx;
+  color: #718096;
+  line-height: 1.5;
+}
+
+// 参保流程
+.process-steps {
+  display: flex;
+  flex-direction: column;
+  gap: 28rpx;
+}
+
+.step-item {
+  display: flex;
+  align-items: flex-start;
+  gap: 24rpx;
+  padding: 24rpx;
+  background: linear-gradient(135deg, #f7fafc 0%, #edf2f7 100%);
+  border-radius: 16rpx;
+  border: 1rpx solid #e2e8f0;
+  transition: all 0.3s ease;
+  
+  &:hover {
+    transform: translateY(-2rpx);
+    box-shadow: 0 8rpx 20rpx rgba(0, 0, 0, 0.08);
+  }
+}
+
+.step-number {
+  width: 64rpx;
+  height: 64rpx;
+  background: linear-gradient(135deg, #4CAF50 0%, #66BB6A 100%);
+  color: #fff;
+  border-radius: 32rpx;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  font-size: 32rpx;
+  font-weight: 600;
+  box-shadow: 0 4rpx 12rpx rgba(76, 175, 80, 0.3);
+  flex-shrink: 0;
+}
+
+.step-content {
+  flex: 1;
+  padding-top: 4rpx;
+}
+
+.step-title {
+  font-size: 32rpx;
+  font-weight: 600;
+  color: #2d3748;
+  margin-bottom: 12rpx;
+  display: block;
+}
+
+.step-desc {
+  font-size: 28rpx;
+  color: #718096;
+  line-height: 1.5;
+  display: block;
+}
+
+// 服务优势
+.advantage-list {
+  display: flex;
+  flex-direction: column;
+  gap: 20rpx;
+}
+
+.advantage-item {
+  padding: 24rpx;
+  background: linear-gradient(135deg, #f8fff8 0%, #f0fdf4 100%);
+  border-radius: 16rpx;
+  border: 1rpx solid #e8f5e8;
+  transition: all 0.3s ease;
+  border-left: 4rpx solid #4CAF50;
+  
+  &:hover {
+    transform: translateY(-2rpx);
+    box-shadow: 0 8rpx 16rpx rgba(76, 175, 80, 0.1);
+  }
+}
+
+.advantage-text {
+  font-size: 30rpx;
+  color: #2c3e50;
+  font-weight: 500;
+  line-height: 1.4;
+}
+
+// 联系方式
+.contact-list {
+  display: flex;
+  flex-direction: column;
+  gap: 24rpx;
+}
+
+.contact-item {
+  display: flex;
+  align-items: center;
+  padding: 20rpx 24rpx;
+  background: linear-gradient(135deg, #f7fafc 0%, #edf2f7 100%);
+  border-radius: 12rpx;
+  border: 1rpx solid #e2e8f0;
+}
+
+.contact-label {
+  font-size: 30rpx;
+  color: #718096;
+  width: 150rpx;
+  flex-shrink: 0;
+  font-weight: 500;
+}
+
+.contact-value {
+  font-size: 30rpx;
+  color: #2d3748;
+  font-weight: 600;
+}
+
+.contact-phone {
+  font-size: 30rpx;
+  color: #4CAF50;
+  font-weight: 600;
+  padding: 8rpx 16rpx;
+  background-color: #f0fdf4;
+  border-radius: 8rpx;
+  border: 1rpx solid #d1fae5;
+  transition: all 0.3s ease;
+  
+  &:active {
+    transform: scale(0.98);
+    background-color: #dcfce7;
+  }
+}
+
+// 底部提示
+.notice-card {
+  margin: 20rpx;
+  background: linear-gradient(135deg, #fff8e1 0%, #fffde7 100%);
+  border: 1rpx solid #f9e79f;
+  border-radius: 16rpx;
+  padding: 28rpx;
+  box-shadow: 0 4rpx 12rpx rgba(255, 193, 7, 0.1);
+}
+
+.notice-content {
+  text-align: center;
+}
+
+.notice-text {
+  font-size: 28rpx;
+  color: #8d4e00;
+  line-height: 1.6;
+  flex: 1;
+  font-weight: 500;
+}
+</style> 

+ 485 - 0
pages/service/mall-detail.vue

@@ -0,0 +1,485 @@
+<template>
+  <view class="detail-container">
+    <!-- 商品轮播图 -->
+    <view class="swiper-container">
+      <swiper class="goods-swiper" :indicator-dots="true" :autoplay="true" :circular="true">
+        <swiper-item v-for="(image, index) in goodsImages" :key="index">
+          <image class="swiper-image" :src="image" mode="aspectFill"></image>
+        </swiper-item>
+      </swiper>
+    </view>
+
+    <!-- 商品基本信息 -->
+    <view class="goods-basic-info">
+      <view class="goods-title">{{ goodsDetail.title }}</view>
+      <view class="goods-subtitle">{{ goodsDetail.description }}</view>
+      <view class="price-container">
+        <text class="current-price">¥{{ goodsDetail.price }}</text>
+        <text class="price-unit">/{{ goodsDetail.unit }}</text>
+        <text class="original-price" v-if="goodsDetail.originalPrice">¥{{ goodsDetail.originalPrice }}</text>
+      </view>
+      <view class="specs-info">
+        <text class="specs-label">规格:</text>
+        <text class="specs-value">{{ goodsDetail.specifications }}</text>
+      </view>
+    </view>
+
+    <!-- 商品详情介绍 -->
+    <view class="goods-detail-info">
+      <view class="detail-title">商品详情</view>
+      
+      <!-- 产品特点 -->
+      <view class="detail-section">
+        <view class="section-title">产品特点</view>
+        <view class="feature-list">
+          <view 
+            class="feature-item" 
+            v-for="(feature, index) in goodsDetail.features" 
+            :key="index"
+          >
+            <view class="feature-icon">✓</view>
+            <text class="feature-text">{{ feature }}</text>
+          </view>
+        </view>
+      </view>
+
+      <!-- 使用说明 -->
+      <view class="detail-section">
+        <view class="section-title">使用说明</view>
+        <view class="usage-content">
+          <text>{{ goodsDetail.usage }}</text>
+        </view>
+      </view>
+
+      <!-- 产品图片展示 -->
+      <view class="detail-section">
+        <view class="section-title">产品展示</view>
+        <view class="detail-images">
+          <image 
+            class="detail-image" 
+            v-for="(image, index) in goodsDetail.detailImages" 
+            :key="index"
+            :src="image" 
+            mode="widthFix"
+            @click="previewImage(image, goodsDetail.detailImages)"
+          ></image>
+        </view>
+      </view>
+    </view>
+
+    <!-- 底部操作栏 -->
+    <view class="bottom-actions">
+      <view class="action-btn consult-btn" @click="handleConsult">
+        立即咨询
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      goodsId: '',
+      goodsDetail: {
+        title: '高产玉米种子',
+        description: '优质杂交种,抗病性强,适应性广',
+        price: '68',
+        originalPrice: '88',
+        unit: '袋',
+        specifications: '500g/袋,发芽率≥95%',
+        features: [
+          '高产稳产,比普通品种增产15-20%',
+          '抗病性强,抗大小斑病、丝黑穗病',
+          '适应性广,适合多种土壤和气候条件',
+          '株型紧凑,抗倒伏能力强',
+          '籽粒饱满,商品性好'
+        ],
+        usage: '播种前先进行种子处理,选择肥沃、排水良好的土壤,按照每亩3-4千粒的密度播种。播种深度2-3厘米,播种后及时覆土镇压。生长期注意水肥管理,适时中耕除草。',
+        detailImages: [
+          '/static/images/products/corn-seeds-new.jpg',
+          '/static/images/products/seeds-packets.jpg',
+          '/static/images/products/agriculture-tools.jpg'
+        ]
+      },
+      goodsImages: [
+        '/static/images/products/corn-seeds-new.jpg',
+        '/static/images/products/fertilizer.jpg',
+        '/static/images/products/organic-fertilizer-new.jpg',
+        '/static/images/products/greenhouse-film.jpg'
+      ]
+    }
+  },
+  
+  onLoad(options) {
+    if (options.id) {
+      this.goodsId = options.id;
+      this.loadGoodsDetail();
+    }
+    if (options.title) {
+      uni.setNavigationBarTitle({
+        title: decodeURIComponent(options.title)
+      });
+    }
+  },
+  
+  methods: {
+    // 加载商品详情
+    loadGoodsDetail() {
+      // 这里可以根据goodsId从后端获取商品详情
+      // 目前使用模拟数据
+      const goodsData = {
+        1: {
+          title: '高产玉米种子',
+          description: '优质杂交种,抗病性强,适应性广',
+          price: '68',
+          originalPrice: '88',
+          unit: '袋',
+          specifications: '500g/袋,发芽率≥95%',
+          features: [
+            '高产稳产,比普通品种增产15-20%',
+            '抗病性强,抗大小斑病、丝黑穗病',
+            '适应性广,适合多种土壤和气候条件',
+            '株型紧凑,抗倒伏能力强',
+            '籽粒饱满,商品性好'
+          ],
+          usage: '播种前先进行种子处理,选择肥沃、排水良好的土壤,按照每亩3-4千粒的密度播种。播种深度2-3厘米,播种后及时覆土镇压。生长期注意水肥管理,适时中耕除草。',
+          detailImages: [
+            '/static/images/products/corn-seeds-new.jpg',
+            '/static/images/products/seeds-packets.jpg',
+            '/static/images/products/agriculture-tools.jpg'
+          ]
+        },
+        2: {
+          title: '复合肥料NPK',
+          description: '15-15-15配比,全营养均衡',
+          price: '120',
+          originalPrice: '150',
+          unit: '袋',
+          specifications: '40kg/袋,NPK含量≥45%',
+          features: [
+            '营养全面,氮磷钾配比科学',
+            '速效持效相结合,肥效持久',
+            '提高作物产量和品质',
+            '改善土壤结构,增强保肥能力',
+            '适用于多种作物和土壤类型'
+          ],
+          usage: '基肥:每亩施用20-30kg,在耕地时均匀撒施并翻入土中。追肥:根据作物生长情况,在关键生长期追施10-15kg。注意避免与种子直接接触,施肥后及时浇水。',
+          detailImages: [
+            '/static/images/products/fertilizer.jpg',
+            '/static/images/products/organic-fertilizer-new.jpg',
+            '/static/images/products/soil-test.jpg'
+          ]
+        },
+        3: {
+          title: '植物保护剂',
+          description: '广谱除草,效果持久',
+          price: '45',
+          originalPrice: '58',
+          unit: '瓶',
+          specifications: '500ml/瓶,有效成分≥98%',
+          features: [
+            '广谱高效,对多种杂草有效',
+            '低毒环保,对作物安全',
+            '持效期长,减少施药次数',
+            '易于使用,省时省力',
+            '成本经济,性价比高'
+          ],
+          usage: '在杂草3-5叶期施药效果最佳。每亩用药量15-20ml,兑水30-45kg均匀喷雾。避免在风力较大时施药,施药后6小时内遇雨需重新施药。',
+          detailImages: [
+            '/static/images/products/plant-protection.jpg',
+            '/static/images/products/agriculture-tools.jpg',
+            '/static/images/products/pesticide.jpg'
+          ]
+        },
+        4: {
+          title: '优质水稻种子',
+          description: '高产稳产,米质优良',
+          price: '85',
+          originalPrice: '105',
+          unit: '袋',
+          specifications: '25kg/袋,发芽率≥95%',
+          features: [
+            '优质品种,口感佳产量高',
+            '抗病性强,适应性广',
+            '生育期适中,便于管理',
+            '籽粒饱满,商品性好',
+            '耐储存,发芽率稳定'
+          ],
+          usage: '播种前进行晒种、选种处理。育秧密度适宜,秧龄25-30天移栽。合理密植,一般每亩1.8-2.2万穴。科学施肥,注意水分管理。',
+          detailImages: [
+            '/static/images/products/seeds-packets.jpg',
+            '/static/images/products/rice-seeds.jpg',
+            '/static/images/products/corn-seeds-new.jpg'
+          ]
+        }
+      };
+      
+      if (goodsData[this.goodsId]) {
+        this.goodsDetail = goodsData[this.goodsId];
+        // 根据商品类型设置轮播图
+        this.setGoodsImages(this.goodsId);
+      }
+    },
+    
+    // 设置商品轮播图
+    setGoodsImages(goodsId) {
+      const imageMap = {
+        '1': [ // 玉米种子
+          '/static/images/products/corn-seeds-new.jpg',
+          '/static/images/products/seeds-packets.jpg',
+          '/static/images/products/agriculture-tools.jpg',
+          '/static/images/products/wheat-seeds.jpg'
+        ],
+        '2': [ // 复合肥料
+          '/static/images/products/fertilizer.jpg',
+          '/static/images/products/organic-fertilizer-new.jpg',
+          '/static/images/products/soil-test.jpg',
+          '/static/images/products/greenhouse-film.jpg'
+        ],
+        '3': [ // 植物保护剂
+          '/static/images/products/plant-protection.jpg',
+          '/static/images/products/agriculture-tools.jpg',
+          '/static/images/products/pesticide.jpg',
+          '/static/images/products/insecticide.jpg'
+        ],
+        '4': [ // 水稻种子
+          '/static/images/products/seeds-packets.jpg',
+          '/static/images/products/rice-seeds.jpg',
+          '/static/images/products/corn-seeds-new.jpg',
+          '/static/images/products/wheat-seeds.jpg'
+        ]
+      };
+      
+      if (imageMap[goodsId]) {
+        this.goodsImages = imageMap[goodsId];
+      }
+    },
+    
+    // 预览图片
+    previewImage(current, urls) {
+      uni.previewImage({
+        current: current,
+        urls: urls
+      });
+    },
+    
+    // 立即咨询
+    handleConsult() {
+      uni.showModal({
+        title: '咨询服务',
+        content: '您可以通过以下方式联系我们:\n1. 拨打客服热线:400-xxx-xxxx\n2. 在线客服(工作时间:9:00-18:00)',
+        confirmText: '拨打电话',
+        cancelText: '取消',
+        success: (res) => {
+          if (res.confirm) {
+            uni.makePhoneCall({
+              phoneNumber: '400-xxx-xxxx'
+            });
+          }
+        }
+      });
+    }
+  }
+}
+</script>
+
+<style lang="scss">
+.detail-container {
+  min-height: 100vh;
+  background-color: #f5f5f5;
+  padding-bottom: 120rpx; // 为底部操作栏留出空间
+}
+
+.swiper-container {
+  width: 100%;
+  height: 600rpx;
+  background-color: #fff;
+}
+
+.goods-swiper {
+  width: 100%;
+  height: 100%;
+}
+
+.swiper-image {
+  width: 100%;
+  height: 100%;
+}
+
+.goods-basic-info {
+  background-color: #fff;
+  padding: 30rpx;
+  margin-bottom: 20rpx;
+}
+
+.goods-title {
+  font-size: 36rpx;
+  font-weight: bold;
+  color: #333;
+  line-height: 1.4;
+  margin-bottom: 16rpx;
+}
+
+.goods-subtitle {
+  font-size: 28rpx;
+  color: #666;
+  line-height: 1.5;
+  margin-bottom: 24rpx;
+}
+
+.price-container {
+  display: flex;
+  align-items: baseline;
+  margin-bottom: 24rpx;
+}
+
+.current-price {
+  font-size: 40rpx;
+  font-weight: bold;
+  color: #4CAF50;
+}
+
+.price-unit {
+  font-size: 28rpx;
+  color: #999;
+  margin-left: 8rpx;
+  margin-right: 16rpx;
+}
+
+.original-price {
+  font-size: 28rpx;
+  color: #999;
+  text-decoration: line-through;
+}
+
+.specs-info {
+  display: flex;
+  align-items: center;
+}
+
+.specs-label {
+  font-size: 28rpx;
+  color: #666;
+}
+
+.specs-value {
+  font-size: 28rpx;
+  color: #333;
+}
+
+.goods-detail-info {
+  background-color: #fff;
+  padding: 30rpx;
+}
+
+.detail-title {
+  font-size: 32rpx;
+  font-weight: bold;
+  color: #333;
+  margin-bottom: 30rpx;
+  text-align: center;
+}
+
+.detail-section {
+  margin-bottom: 40rpx;
+  
+  &:last-child {
+    margin-bottom: 0;
+  }
+}
+
+.section-title {
+  font-size: 30rpx;
+  font-weight: bold;
+  color: #333;
+  margin-bottom: 20rpx;
+  padding-left: 20rpx;
+  position: relative;
+  
+  &::before {
+    content: '';
+    position: absolute;
+    left: 0;
+    top: 50%;
+    transform: translateY(-50%);
+    width: 8rpx;
+    height: 32rpx;
+    background-color: #4CAF50;
+    border-radius: 4rpx;
+  }
+}
+
+.feature-list {
+  .feature-item {
+    display: flex;
+    align-items: center;
+    margin-bottom: 16rpx;
+    
+    .feature-icon {
+      width: 32rpx;
+      height: 32rpx;
+      background-color: #4CAF50;
+      color: #fff;
+      border-radius: 50%;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      font-size: 20rpx;
+      font-weight: bold;
+      margin-right: 16rpx;
+      flex-shrink: 0;
+    }
+    
+    .feature-text {
+      font-size: 28rpx;
+      color: #666;
+      line-height: 1.5;
+    }
+  }
+}
+
+.usage-content {
+  font-size: 28rpx;
+  color: #666;
+  line-height: 1.6;
+  padding: 20rpx;
+  background-color: #f8f8f8;
+  border-radius: 12rpx;
+}
+
+.detail-images {
+  display: flex;
+  flex-direction: column;
+  gap: 20rpx;
+}
+
+.detail-image {
+  width: 100%;
+  border-radius: 12rpx;
+}
+
+.bottom-actions {
+  position: fixed;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  background-color: #fff;
+  padding: 20rpx 30rpx;
+  border-top: 1rpx solid #f0f0f0;
+  z-index: 1000;
+}
+
+.action-btn {
+  text-align: center;
+  padding: 24rpx 0;
+  border-radius: 12rpx;
+  font-size: 32rpx;
+  font-weight: bold;
+}
+
+.consult-btn {
+  background-color: #4CAF50;
+  color: #fff;
+}
+</style> 

+ 419 - 0
pages/service/mall.vue

@@ -0,0 +1,419 @@
+<template>
+  <view class="mall-container">
+    <!-- 顶部搜索框 -->
+    <view class="search-header">
+      <view class="search-box">
+        <view class="search-input">
+          <image class="search-icon" src="/static/icons/search.png" mode="aspectFit"></image>
+          <input 
+            class="input" 
+            placeholder="搜索农资商品(如:化肥、除草剂)" 
+            placeholder-style="color: #999;"
+            v-model="searchKeyword"
+            @confirm="handleSearch"
+          />
+        </view>
+      </view>
+    </view>
+
+    <!-- 分类导航 -->
+    <view class="category-nav">
+      <scroll-view 
+        class="nav-scroll" 
+        scroll-x="true" 
+        :show-scrollbar="false"
+        :enhanced="true"
+        :bounces="false"
+        :scroll-with-animation="true"
+        :scroll-left="scrollLeft"
+      >
+        <view class="nav-list">
+          <view 
+            class="nav-item"
+            :class="{ active: activeCategory === item.id }"
+            v-for="item in categoryList" 
+            :key="item.id"
+            @click="switchCategory(item.id)"
+          >
+            {{ item.name }}
+          </view>
+        </view>
+      </scroll-view>
+    </view>
+
+    <!-- 商品展示区 -->
+    <view class="goods-container">
+      <view class="goods-grid">
+        <view 
+          class="goods-card"
+          v-for="item in filteredGoods" 
+          :key="item.id"
+          @click="navigateToDetail(item)"
+        >
+          <view class="goods-image">
+            <image :src="item.image" mode="aspectFill"></image>
+          </view>
+          <view class="goods-info">
+            <text class="goods-title">{{ item.title }}</text>
+            <text class="goods-desc">{{ item.description }}</text>
+            <view class="goods-price">
+              <text class="price">¥{{ item.price }}</text>
+              <text class="unit">/{{ item.unit }}</text>
+            </view>
+            <view class="action-btn">了解更多</view>
+          </view>
+        </view>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      searchKeyword: '',
+      activeCategory: 'recommend',
+      scrollLeft: 0,
+      
+      // 分类列表
+      categoryList: [
+        { id: 'recommend', name: '推荐' },
+        { id: 'seeds', name: '种子' },
+        { id: 'fertilizer', name: '肥料' },
+        { id: 'pesticide', name: '农药' },
+        { id: 'film', name: '农膜' },
+        { id: 'parts', name: '农机配件' }
+      ],
+      
+      // 商品列表
+      goodsList: [
+        {
+          id: 1,
+          title: '高产玉米种子',
+          description: '优质杂交种,抗病性强,适应性广',
+          price: '68',
+          unit: '袋',
+          image: '/static/images/products/corn-seeds-new.jpg',
+          category: 'seeds'
+        },
+        {
+          id: 2,
+          title: '复合肥料NPK',
+          description: '15-15-15配比,全营养均衡',
+          price: '120',
+          unit: '袋',
+          image: '/static/images/products/fertilizer.jpg',
+          category: 'fertilizer'
+        },
+        {
+          id: 3,
+          title: '植物保护剂',
+          description: '广谱除草,效果持久',
+          price: '45',
+          unit: '瓶',
+          image: '/static/images/products/plant-protection.jpg',
+          category: 'pesticide'
+        },
+        {
+          id: 4,
+          title: '优质水稻种子',
+          description: '高产稳产,米质优良',
+          price: '85',
+          unit: '袋',
+          image: '/static/images/products/seeds-packets.jpg',
+          category: 'seeds'
+        },
+        {
+          id: 5,
+          title: '有机肥料',
+          description: '纯天然有机,改良土壤',
+          price: '95',
+          unit: '袋',
+          image: '/static/images/products/organic-fertilizer-new.jpg',
+          category: 'fertilizer'
+        },
+        {
+          id: 6,
+          title: '农用工具套装',
+          description: '多功能农具,提高作业效率',
+          price: '285',
+          unit: '套',
+          image: '/static/images/products/agriculture-tools.jpg',
+          category: 'pesticide'
+        },
+        {
+          id: 7,
+          title: '温室农膜',
+          description: '保温保湿,延长生长期',
+          price: '125',
+          unit: '卷',
+          image: '/static/images/products/greenhouse-film.jpg',
+          category: 'film'
+        },
+        {
+          id: 8,
+          title: '农业机械配件',
+          description: '耐用配件,维护设备正常运行',
+          price: '350',
+          unit: '套',
+          image: '/static/images/products/farming-equipment.jpg',
+          category: 'parts'
+        }
+      ]
+    }
+  },
+  
+  computed: {
+    filteredGoods() {
+      let goods = this.goodsList;
+      
+      // 按分类筛选
+      if (this.activeCategory !== 'recommend') {
+        goods = goods.filter(item => item.category === this.activeCategory);
+      }
+      
+      // 按搜索关键词筛选
+      if (this.searchKeyword.trim()) {
+        const keyword = this.searchKeyword.trim().toLowerCase();
+        goods = goods.filter(item => 
+          item.title.toLowerCase().includes(keyword) || 
+          item.description.toLowerCase().includes(keyword)
+        );
+      }
+      
+      return goods;
+    }
+  },
+  
+  methods: {
+    // 切换分类
+    switchCategory(categoryId) {
+      this.activeCategory = categoryId;
+      // 滚动到当前分类位置
+      this.$nextTick(() => {
+        this.scrollToActiveCategory(categoryId);
+      });
+    },
+    
+    // 滚动到激活的分类  
+    scrollToActiveCategory(categoryId) {
+      const index = this.categoryList.findIndex(item => item.id === categoryId);
+      if (index > -1) {
+        // 计算滚动位置,让当前分类居中显示
+        const itemWidth = 120; // 每个分类项大约120rpx宽度
+        const containerWidth = 750; // 屏幕宽度
+        const scrollLeft = Math.max(0, index * itemWidth - containerWidth / 2 + itemWidth / 2);
+        
+        // 设置scroll-view的scrollLeft
+        this.scrollLeft = scrollLeft;
+      }
+    },
+    
+    // 搜索处理
+    handleSearch() {
+      if (!this.searchKeyword.trim()) {
+        uni.showToast({
+          title: '请输入搜索关键词',
+          icon: 'none'
+        });
+        return;
+      }
+      // 搜索逻辑已在computed中处理
+    },
+    
+    // 导航到商品详情
+    navigateToDetail(goods) {
+      uni.navigateTo({
+        url: `/pages/service/mall-detail?id=${goods.id}&title=${encodeURIComponent(goods.title)}`
+      });
+    }
+  },
+  
+  onNavigationBarTitleText() {
+    return '农资商城';
+  }
+}
+</script>
+
+<style lang="scss">
+.mall-container {
+  min-height: 100vh;
+  background-color: #f5f5f5;
+}
+
+.search-header {
+  background-color: #fff;
+  padding: 20rpx;
+  border-bottom: 1rpx solid #f0f0f0;
+}
+
+.search-box {
+  position: relative;
+}
+
+.search-input {
+  display: flex;
+  align-items: center;
+  background-color: #f8f8f8;
+  border-radius: 32rpx;
+  padding: 16rpx 24rpx;
+  
+  .search-icon {
+    width: 32rpx;
+    height: 32rpx;
+    margin-right: 16rpx;
+  }
+  
+  .input {
+    flex: 1;
+    font-size: 28rpx;
+    line-height: 1.5;
+  }
+}
+
+.category-nav {
+  background-color: #fff;
+  border-bottom: 1rpx solid #f0f0f0;
+  position: sticky;
+  top: 0;
+  z-index: 100;
+}
+
+.nav-scroll {
+  white-space: nowrap;
+  height: 88rpx;
+  width: 100%;
+  overflow: hidden;
+  -webkit-overflow-scrolling: touch; /* iOS滑动优化 */
+  scroll-behavior: smooth; /* 平滑滚动 */
+}
+
+.nav-list {
+  display: inline-flex;
+  padding: 0 20rpx;
+  height: 100%;
+  align-items: center;
+  min-width: 100%;
+}
+
+.nav-item {
+  flex-shrink: 0;
+  padding: 24rpx 32rpx;
+  margin-right: 8rpx;
+  font-size: 28rpx;
+  color: #666;
+  font-weight: 500;
+  position: relative;
+  white-space: nowrap;
+  transition: all 0.2s ease;
+  border-radius: 8rpx;
+  
+  &:active {
+    background-color: #f0f0f0;
+    transform: scale(0.95);
+  }
+  
+  &.active {
+    color: #4CAF50;
+    font-weight: bold;
+    background-color: #f8fdf8;
+  }
+  
+  &.active::after {
+    content: '';
+    position: absolute;
+    bottom: 8rpx;
+    left: 50%;
+    transform: translateX(-50%);
+    width: 40rpx;
+    height: 4rpx;
+    background-color: #4CAF50;
+    border-radius: 2rpx;
+  }
+}
+
+.goods-container {
+  padding: 20rpx;
+}
+
+.goods-grid {
+  display: grid;
+  grid-template-columns: 1fr 1fr;
+  gap: 20rpx;
+}
+
+.goods-card {
+  background-color: #fff;
+  border-radius: 16rpx;
+  overflow: hidden;
+  box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
+  transition: transform 0.2s ease;
+  
+  &:active {
+    transform: scale(0.98);
+  }
+}
+
+.goods-image {
+  width: 100%;
+  height: 240rpx;
+  
+  image {
+    width: 100%;
+    height: 100%;
+  }
+}
+
+.goods-info {
+  padding: 24rpx;
+}
+
+.goods-title {
+  font-size: 28rpx;
+  font-weight: bold;
+  color: #333;
+  line-height: 1.4;
+  display: block;
+  margin-bottom: 8rpx;
+}
+
+.goods-desc {
+  font-size: 24rpx;
+  color: #666;
+  line-height: 1.4;
+  display: block;
+  margin-bottom: 16rpx;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+
+.goods-price {
+  display: flex;
+  align-items: baseline;
+  margin-bottom: 20rpx;
+  
+  .price {
+    font-size: 32rpx;
+    font-weight: bold;
+    color: #4CAF50;
+  }
+  
+  .unit {
+    font-size: 24rpx;
+    color: #999;
+    margin-left: 4rpx;
+  }
+}
+
+.action-btn {
+  background-color: #4CAF50;
+  color: #fff;
+  text-align: center;
+  padding: 16rpx 0;
+  border-radius: 8rpx;
+  font-size: 28rpx;
+  font-weight: 500;
+}
+</style> 

+ 647 - 0
pages/service/my-publish.vue

@@ -0,0 +1,647 @@
+<template>
+  <view class="my-publish-container">
+    <!-- 顶部Tab标签页 -->
+    <view class="tab-header">
+      <view class="tab-list">
+        <view 
+          class="tab-item"
+          :class="{ active: activeTab === 'published' }"
+          @click="switchTab('published')"
+        >
+          <text class="tab-text">销售信息</text>
+        </view>
+        <view 
+          class="tab-item"
+          :class="{ active: activeTab === 'purchase' }"
+          @click="switchTab('purchase')"
+        >
+          <text class="tab-text">收购信息</text>
+        </view>
+      </view>
+      <view class="tab-indicator" :style="{ left: activeTab === 'published' ? '0' : '50%' }"></view>
+    </view>
+
+    <!-- 我的发布页面 -->
+    <view v-if="activeTab === 'published'" class="tab-content">
+      <!-- 搜索筛选 -->
+      <view class="search-section">
+        <view class="search-box">
+          <image class="search-icon" src="/static/icons/search.png" mode="aspectFit"></image>
+          <input 
+            class="search-input" 
+            placeholder="搜索我的农产品" 
+            placeholder-style="color: #999;"
+            v-model="searchKeyword"
+            @confirm="handleSearch"
+          />
+        </view>
+      </view>
+      
+      <!-- 我的发布列表 -->
+      <view class="products-container">
+        <view class="products-list">
+          <view 
+            class="published-card"
+            v-for="item in filteredPublishedProducts" 
+            :key="item.id"
+            @click="navigateToDetail(item)"
+          >
+            <view class="card-content">
+              <view class="product-image">
+                <image :src="item.image" mode="aspectFill"></image>
+              </view>
+              <view class="product-info">
+                <view class="product-header">
+                  <view class="product-name">{{ item.name }}</view>
+                  <view class="price-info">¥{{ item.price }} 元/{{ item.unit }}</view>
+                </view>
+                <view class="product-desc">{{ item.description }}</view>
+                <view class="product-footer">
+                  <view class="publish-time">{{ item.publishTime }}</view>
+                  <view class="status-tag" :class="item.status">
+                    {{ getStatusText(item.status) }}
+                  </view>
+                </view>
+              </view>
+            </view>
+          </view>
+        </view>
+      </view>
+    </view>
+
+    <!-- 收购信息页面 -->
+    <view v-if="activeTab === 'purchase'" class="tab-content">
+      <!-- 搜索筛选 -->
+      <view class="search-section">
+        <view class="search-box">
+          <image class="search-icon" src="/static/icons/search.png" mode="aspectFit"></image>
+          <input 
+            class="search-input" 
+            placeholder="搜索收购信息" 
+            placeholder-style="color: #999;"
+            v-model="purchaseSearchKeyword"
+            @confirm="handlePurchaseSearch"
+          />
+        </view>
+      </view>
+      
+      <!-- 收购信息列表 -->
+      <view class="products-container">
+        <view class="products-list">
+          <view 
+            class="published-card"
+            v-for="item in filteredPurchaseList" 
+            :key="item.id"
+            @click="navigateToPurchaseDetail(item)"
+          >
+            <view class="card-content">
+              <view class="product-image">
+                <image :src="getPurchaseImage(item)" mode="aspectFill"></image>
+              </view>
+              <view class="product-info">
+                <view class="product-header">
+                  <view class="product-name">{{ item.title }}</view>
+                  <view class="price-info">¥{{ item.budgetPrice }} 元/{{ item.unit }}</view>
+                </view>
+                <view class="product-desc">需求数量:{{ item.quantity }}</view>
+                <view class="product-footer">
+                  <view class="publish-time">{{ item.publishTime }}</view>
+                  <view class="status-tag" :class="item.status">
+                    {{ getStatusText(item.status) }}
+                  </view>
+                </view>
+              </view>
+            </view>
+          </view>
+        </view>
+      </view>
+    </view>
+
+    <!-- 底部固定按钮 -->
+    <view class="bottom-action-bar">
+      <view class="action-btn" @click="showPublishModal = true">
+        <text class="btn-text">发布</text>
+      </view>
+    </view>
+
+    <!-- 发布选择弹窗 -->
+    <view class="publish-modal" v-if="showPublishModal" @click="showPublishModal = false">
+      <view class="publish-content" @click.stop>
+        <view class="publish-header">
+          <text class="publish-title">选择发布类型</text>
+          <text class="publish-close" @click="showPublishModal = false">✕</text>
+        </view>
+        <view class="publish-options">
+          <view class="option-item" @click="navigateToPublish">
+            <view class="option-text">
+              <text class="option-title">发布农产品</text>
+              <text class="option-desc">出售我的农产品</text>
+            </view>
+          </view>
+          <view class="option-item" @click="navigateToPurchasePublish">
+            <view class="option-text">
+              <text class="option-title">发布收购信息</text>
+              <text class="option-desc">收购农产品需求</text>
+            </view>
+          </view>
+        </view>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      activeTab: 'published',
+      searchKeyword: '',
+      purchaseSearchKeyword: '',
+      showPublishModal: false,
+      
+      // 我的发布列表
+      publishedProductsList: [
+        {
+          id: 1,
+          name: '有机苹果',
+          description: '新鲜采摘,香甜可口',
+          price: '8.5',
+          unit: '斤',
+          image: '/static/images/products/corn-seeds-new.jpg',
+          publishTime: '今天',
+          status: 'approved'
+        },
+        {
+          id: 2,
+          name: '优质大米',
+          description: '当季新米,粒粒饱满',
+          price: '6.8',
+          unit: '斤',
+          image: '/static/images/products/rice-seeds.jpg',
+          publishTime: '昨天',
+          status: 'pending'
+        },
+        {
+          id: 3,
+          name: '新鲜蔬菜包',
+          description: '时令蔬菜,营养丰富',
+          price: '25',
+          unit: '份',
+          image: '/static/images/products/organic-fertilizer-new.jpg',
+          publishTime: '2天前',
+          status: 'approved'
+        },
+        {
+          id: 4,
+          name: '土鸡蛋',
+          description: '散养土鸡,营养价值高',
+          price: '2.5',
+          unit: '个',
+          image: '/static/images/products/seeds-packets.jpg',
+          publishTime: '3天前',
+          status: 'rejected'
+        }
+      ],
+      
+      // 收购信息列表
+      purchaseList: [
+        {
+          id: 1,
+          title: '高价收购优质土豆',
+          category: '蔬菜',
+          quantity: '1000斤',
+          budgetPrice: '3.5',
+          unit: '斤',
+          contact: '张**',
+          location: '本地',
+          publishTime: '今天',
+          status: 'approved'
+        },
+        {
+          id: 2,
+          title: '大量收购新鲜玉米',
+          category: '粮食',
+          quantity: '5000斤',
+          budgetPrice: '2.8',
+          unit: '斤',
+          contact: '李**',
+          location: '周边',
+          publishTime: '昨天',
+          status: 'pending'
+        },
+        {
+          id: 3,
+          title: '收购有机蔬菜',
+          category: '蔬菜',
+          quantity: '500斤',
+          budgetPrice: '8.0',
+          unit: '斤',
+          contact: '王**',
+          location: '本地',
+          publishTime: '2天前',
+          status: 'rejected'
+        }
+      ]
+    }
+  },
+  
+  computed: {
+    filteredPublishedProducts() {
+      let products = this.publishedProductsList;
+      
+      if (this.searchKeyword.trim()) {
+        const keyword = this.searchKeyword.trim().toLowerCase();
+        products = products.filter(item => 
+          item.name.toLowerCase().includes(keyword) || 
+          item.description.toLowerCase().includes(keyword)
+        );
+      }
+      
+      return products;
+    },
+    
+    filteredPurchaseList() {
+      let list = this.purchaseList;
+      
+      if (this.purchaseSearchKeyword.trim()) {
+        const keyword = this.purchaseSearchKeyword.trim().toLowerCase();
+        list = list.filter(item => 
+          item.title.toLowerCase().includes(keyword) || 
+          item.category.toLowerCase().includes(keyword)
+        );
+      }
+      
+      return list;
+    }
+  },
+  
+  methods: {
+    switchTab(tab) {
+      this.activeTab = tab;
+    },
+    
+    getStatusText(status) {
+      const statusMap = {
+        'pending': '审核中',
+        'approved': '已上架',
+        'rejected': '已下架'
+      };
+      return statusMap[status] || '未知';
+    },
+    
+    handleSearch() {
+      // 搜索逻辑已在computed中处理
+    },
+    
+    handlePurchaseSearch() {
+      // 搜索逻辑已在computed中处理
+    },
+    
+    navigateToDetail(product) {
+      uni.navigateTo({
+        url: `/pages/service/sales-detail?id=${product.id}&type=sale&name=${encodeURIComponent(product.name)}&source=myPublish&status=${product.status}`
+      });
+    },
+    
+    navigateToPurchaseDetail(item) {
+      uni.navigateTo({
+        url: `/pages/service/sales-detail?id=${item.id}&type=purchase&title=${encodeURIComponent(item.title)}&source=myPublish&status=${item.status}`
+      });
+    },
+    
+    navigateToPublish() {
+      this.showPublishModal = false;
+      uni.navigateTo({
+        url: '/pages/service/sales-publish'
+      });
+    },
+    
+    navigateToPurchasePublish() {
+      this.showPublishModal = false;
+      uni.navigateTo({
+        url: '/pages/service/purchase-publish'
+      });
+    },
+    
+    // 获取收购信息对应的图片
+    getPurchaseImage(item) {
+      // 根据分类返回对应的默认图片
+      const categoryImages = {
+        '蔬菜': '/static/images/products/organic-fertilizer-new.jpg',
+        '粮食': '/static/images/products/corn-seeds-new.jpg',
+        '水果': '/static/images/products/rice-seeds.jpg',
+        '其他': '/static/images/products/agriculture-tools.jpg'
+      };
+      return categoryImages[item.category] || categoryImages['其他'];
+    }
+  }
+}
+</script>
+
+<style lang="scss">
+.my-publish-container {
+  min-height: 100vh;
+  background-color: #f5f5f5;
+  padding-bottom: calc(128rpx + env(safe-area-inset-bottom));
+}
+
+.tab-header {
+  background-color: #fff;
+  position: relative;
+  border-bottom: 1rpx solid #f0f0f0;
+}
+
+.tab-list {
+  display: flex;
+  align-items: center;
+}
+
+.tab-item {
+  flex: 1;
+  text-align: center;
+  padding: 32rpx 0;
+  position: relative;
+  
+  .tab-text {
+    font-size: 30rpx;
+    color: #666;
+    font-weight: 500;
+    transition: color 0.3s ease;
+  }
+  
+  &.active .tab-text {
+    color: #4CAF50;
+    font-weight: bold;
+  }
+}
+
+.tab-indicator {
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  width: 50%;
+  height: 4rpx;
+  background-color: #4CAF50;
+  transition: left 0.3s ease;
+}
+
+.tab-content {
+  flex: 1;
+}
+
+.search-section {
+  background-color: #fff;
+  padding: 20rpx;
+  border-bottom: 1rpx solid #f0f0f0;
+}
+
+.search-box {
+  flex: 1;
+  display: flex;
+  align-items: center;
+  background-color: #f8f8f8;
+  border-radius: 32rpx;
+  padding: 16rpx 24rpx;
+}
+
+.search-icon {
+  width: 32rpx;
+  height: 32rpx;
+  margin-right: 16rpx;
+}
+
+.search-input {
+  flex: 1;
+  font-size: 28rpx;
+  line-height: 1.5;
+}
+
+.products-container, .purchase-container {
+  padding: 20rpx;
+}
+
+.products-list, .purchase-list {
+  display: flex;
+  flex-direction: column;
+  gap: 16rpx;
+}
+
+.published-card {
+  background-color: #fff;
+  border-radius: 12rpx;
+  overflow: hidden;
+  box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
+  transition: transform 0.2s ease;
+  
+  &:active {
+    transform: scale(0.98);
+  }
+}
+
+.card-content {
+  display: flex;
+  padding: 20rpx;
+  gap: 20rpx;
+}
+
+.product-image {
+  width: 160rpx;
+  height: 160rpx;
+  border-radius: 8rpx;
+  overflow: hidden;
+  flex-shrink: 0;
+  
+  image {
+    width: 100%;
+    height: 100%;
+  }
+}
+
+.product-info {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+}
+
+.product-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: flex-start;
+  margin-bottom: 12rpx;
+}
+
+.product-name {
+  font-size: 30rpx;
+  font-weight: bold;
+  color: #4CAF50;
+  flex: 1;
+  margin-right: 16rpx;
+}
+
+.price-info {
+  font-size: 26rpx;
+  color: #333;
+  font-weight: bold;
+  white-space: nowrap;
+}
+
+.product-desc {
+  font-size: 26rpx;
+  color: #666;
+  margin-bottom: 16rpx;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+
+.product-footer {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.publish-time {
+  font-size: 24rpx;
+  color: #999;
+}
+
+.status-tag {
+  padding: 8rpx 16rpx;
+  border-radius: 16rpx;
+  font-size: 22rpx;
+  
+  &.pending {
+    background-color: #fff7e6;
+    color: #fa8c16;
+  }
+  
+  &.approved {
+    background-color: #f6ffed;
+    color: #52c41a;
+  }
+  
+  &.rejected {
+    background-color: #fff2f0;
+    color: #ff4d4f;
+  }
+}
+
+// 收购信息现在使用统一的 .published-card 样式
+
+// 底部固定按钮
+.bottom-action-bar {
+  position: fixed;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  width: 100%;
+  background-color: #fff;
+  border-top: 1rpx solid #f0f0f0;
+  padding: 20rpx 30rpx;
+  padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
+  z-index: 1000;
+  box-shadow: 0 -2rpx 8rpx rgba(0, 0, 0, 0.05);
+  box-sizing: border-box;
+}
+
+.action-btn {
+  width: 100%;
+  height: 88rpx;
+  background-color: #4CAF50;
+  border-radius: 12rpx;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  transition: background-color 0.2s ease;
+  box-sizing: border-box;
+  
+  &:active {
+    background-color: #45a049;
+  }
+  
+  .btn-text {
+    font-size: 32rpx;
+    color: #fff;
+    font-weight: bold;
+  }
+}
+
+.publish-modal {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background-color: rgba(0, 0, 0, 0.5);
+  z-index: 2000;
+  display: flex;
+  align-items: flex-end;
+}
+
+.publish-content {
+  width: 100%;
+  background-color: #fff;
+  border-radius: 24rpx 24rpx 0 0;
+  padding: 0;
+}
+
+.publish-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 30rpx;
+  border-bottom: 1rpx solid #f0f0f0;
+  
+  .publish-title {
+    font-size: 32rpx;
+    font-weight: bold;
+    color: #333;
+  }
+  
+  .publish-close {
+    font-size: 36rpx;
+    color: #999;
+  }
+}
+
+.publish-options {
+  padding: 20rpx;
+}
+
+.option-item {
+  display: flex;
+  align-items: center;
+  padding: 24rpx 20rpx;
+  border-radius: 12rpx;
+  margin-bottom: 16rpx;
+  background-color: #f8f8f8;
+  transition: background-color 0.2s ease;
+  
+  &:last-child {
+    margin-bottom: 0;
+  }
+  
+  &:active {
+    background-color: #e8f5e8;
+  }
+}
+
+.option-text {
+  flex: 1;
+  
+  .option-title {
+    font-size: 30rpx;
+    font-weight: bold;
+    color: #333;
+    display: block;
+    margin-bottom: 8rpx;
+  }
+  
+  .option-desc {
+    font-size: 26rpx;
+    color: #666;
+    display: block;
+  }
+}
+</style> 

+ 710 - 0
pages/service/purchase-publish.vue

@@ -0,0 +1,710 @@
+<template>
+  <view class="purchase-publish-container">
+    <!-- 表单内容 -->
+    <view class="form-container">
+      <!-- 收购标题 -->
+      <view class="form-item">
+        <view class="item-label">
+          <text class="label-text">收购标题</text>
+          <text class="required">*</text>
+        </view>
+        <view class="item-content">
+          <input
+            class="form-input"
+            v-model="formData.title"
+            placeholder="请输入收购标题"
+            placeholder-style="color: #999;"
+            maxlength="30"
+            @input="onTitleInput"
+          />
+          <view class="char-count">{{ titleLength }}/30</view>
+        </view>
+      </view>
+
+      <!-- 收购品类 -->
+      <view class="form-item">
+        <view class="item-label">
+          <text class="label-text">收购品类</text>
+          <text class="required">*</text>
+        </view>
+        <view class="item-content">
+          <view class="category-selector" @click="showCategoryPicker = true">
+            <text class="selector-text" :class="{ placeholder: !formData.category }">
+              {{ formData.category || '请选择收购品类' }}
+            </text>
+            <text class="arrow-icon">></text>
+          </view>
+        </view>
+      </view>
+
+      <!-- 收购数量 -->
+      <view class="form-item">
+        <view class="item-label">
+          <text class="label-text">收购数量</text>
+          <text class="required">*</text>
+        </view>
+        <view class="item-content">
+          <view class="input-with-unit">
+            <input
+              class="form-input"
+              v-model="formData.quantity"
+              placeholder="请输入收购数量"
+              placeholder-style="color: #999;"
+              type="number"
+            />
+            <text class="unit-text">斤</text>
+          </view>
+        </view>
+      </view>
+
+      <!-- 单价预算 -->
+      <view class="form-item">
+        <view class="item-label">
+          <text class="label-text">单价预算</text>
+          <text class="required">*</text>
+        </view>
+        <view class="item-content">
+          <view class="input-with-unit">
+            <text class="currency-symbol">¥</text>
+            <input
+              class="form-input"
+              v-model="formData.budgetPrice"
+              placeholder="请输入单价预算"
+              placeholder-style="color: #999;"
+              type="digit"
+            />
+            <text class="unit-text">元/斤</text>
+          </view>
+        </view>
+      </view>
+
+      <!-- 补充说明 -->
+      <view class="form-item">
+        <view class="item-label">
+          <text class="label-text">补充说明</text>
+        </view>
+        <view class="item-content">
+          <textarea
+            class="form-textarea"
+            v-model="formData.description"
+            placeholder="请描述交货要求、时间等补充信息"
+            placeholder-style="color: #999;"
+            maxlength="200"
+            auto-height
+            @input="onDescInput"
+          />
+          <view class="char-count">{{ descLength }}/200</view>
+        </view>
+      </view>
+
+      <!-- 上传参考图片 -->
+      <view class="form-item">
+        <view class="item-label">
+          <text class="label-text">参考图片</text>
+          <text class="optional">(最多2张)</text>
+        </view>
+        <view class="item-content">
+          <view class="image-upload-area">
+            <view 
+              class="image-item"
+              v-for="(image, index) in formData.images"
+              :key="index"
+            >
+              <image class="uploaded-image" :src="image" mode="aspectFill"></image>
+              <view class="image-delete" @click="removeImage(index)">×</view>
+            </view>
+            <view 
+              class="image-upload-btn"
+              v-if="formData.images.length < 2"
+              @click="chooseImage"
+            >
+              <text class="upload-icon">+</text>
+              <text class="upload-text">上传图片</text>
+            </view>
+          </view>
+        </view>
+      </view>
+
+      <!-- 联系人信息 -->
+      <view class="form-item">
+        <view class="item-label">
+          <text class="label-text">联系人信息</text>
+        </view>
+        <view class="item-content">
+          <view class="contact-input-row">
+            <text class="contact-label">联系人:</text>
+            <input
+              class="contact-input"
+              v-model="formData.contactName"
+              placeholder="请输入联系人姓名"
+              placeholder-style="color: #999;"
+              maxlength="10"
+            />
+          </view>
+          <view class="contact-input-row">
+            <text class="contact-label">电话:</text>
+            <input
+              class="contact-input"
+              v-model="formData.contactPhone"
+              placeholder="请输入联系电话"
+              placeholder-style="color: #999;"
+              type="number"
+              maxlength="11"
+            />
+          </view>
+        </view>
+      </view>
+    </view>
+
+    <!-- 底部提交按钮 -->
+    <view class="bottom-action-bar">
+      <view class="submit-btn" @click="submitForm">
+        <text class="btn-text">{{ isEditMode ? '保存修改' : '提交发布' }}</text>
+      </view>
+    </view>
+
+    <!-- 品类选择弹窗 -->
+    <view class="picker-modal" v-if="showCategoryPicker" @click="showCategoryPicker = false">
+      <view class="picker-content" @click.stop>
+        <view class="picker-header">
+          <text class="picker-title">选择收购品类</text>
+          <text class="picker-close" @click="showCategoryPicker = false">×</text>
+        </view>
+        <view class="picker-options">
+          <view 
+            class="picker-option"
+            v-for="category in categoryOptions"
+            :key="category"
+            @click="selectCategory(category)"
+          >
+            <text class="option-text">{{ category }}</text>
+          </view>
+        </view>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      isEditMode: false, // 是否为编辑模式
+      editItemId: '', // 编辑的收购信息ID
+      formData: {
+        title: '',
+        category: '',
+        quantity: '',
+        budgetPrice: '',
+        description: '',
+        images: [],
+        contactName: '',
+        contactPhone: ''
+      },
+      categoryOptions: ['蔬菜', '水果', '粮食', '其他'],
+      showCategoryPicker: false,
+      titleLength: 0,
+      descLength: 0
+    }
+  },
+  
+  onLoad(options) {
+    // 检查是否为编辑模式
+    if (options.action === 'edit' && options.id) {
+      this.isEditMode = true;
+      this.editItemId = options.id;
+      
+      // 设置页面标题
+      uni.setNavigationBarTitle({
+        title: '编辑收购信息'
+      });
+      
+      // 加载收购信息数据
+      this.loadPurchaseData();
+    } else {
+      // 新建模式
+      this.isEditMode = false;
+      uni.setNavigationBarTitle({
+        title: '发布收购信息'
+      });
+    }
+  },
+  
+  methods: {
+    // 加载收购信息数据(编辑模式)
+    loadPurchaseData() {
+      // 模拟从API加载数据,实际应用中需要根据ID调用相应的API
+      uni.showLoading({ title: '加载中...' });
+      
+      setTimeout(() => {
+        // 收购信息的模拟数据
+        const mockData = {
+          title: '高价收购优质土豆',
+          category: '蔬菜',
+          quantity: '1000',
+          budgetPrice: '3.5',
+          description: '大量收购优质土豆,要求新鲜无病害,无青皮,规格统一。支持长期合作,价格优惠,现金结算。有货源的农户欢迎联系,我们提供上门收购服务。',
+          images: [
+            '/static/images/products/agriculture-tools.jpg'
+          ],
+          contactName: '李先生',
+          contactPhone: '13856785678'
+        };
+        
+        // 填充表单数据
+        this.formData = { ...mockData };
+        
+        // 更新字符计数
+        this.titleLength = this.formData.title.length;
+        this.descLength = this.formData.description.length;
+        
+        uni.hideLoading();
+      }, 1000);
+    },
+    
+    // 标题输入处理
+    onTitleInput(e) {
+      this.titleLength = e.detail.value.length;
+    },
+    
+    // 描述输入处理
+    onDescInput(e) {
+      this.descLength = e.detail.value.length;
+    },
+    
+    // 选择品类
+    selectCategory(category) {
+      this.formData.category = category;
+      this.showCategoryPicker = false;
+    },
+    
+    // 选择图片
+    chooseImage() {
+      const remainingCount = 2 - this.formData.images.length;
+      uni.chooseImage({
+        count: remainingCount,
+        sizeType: ['compressed'],
+        sourceType: ['album', 'camera'],
+        success: (res) => {
+          this.formData.images = this.formData.images.concat(res.tempFilePaths);
+        },
+        fail: (err) => {
+          console.error('选择图片失败:', err);
+        }
+      });
+    },
+    
+    // 删除图片
+    removeImage(index) {
+      this.formData.images.splice(index, 1);
+    },
+    
+    // 表单验证
+    validateForm() {
+      if (!this.formData.title.trim()) {
+        uni.showToast({
+          title: '请输入收购标题',
+          icon: 'none'
+        });
+        return false;
+      }
+      
+      if (!this.formData.category) {
+        uni.showToast({
+          title: '请选择收购品类',
+          icon: 'none'
+        });
+        return false;
+      }
+      
+      if (!this.formData.quantity || this.formData.quantity <= 0) {
+        uni.showToast({
+          title: '请输入有效的收购数量',
+          icon: 'none'
+        });
+        return false;
+      }
+      
+      if (!this.formData.budgetPrice || this.formData.budgetPrice <= 0) {
+        uni.showToast({
+          title: '请输入有效的单价预算',
+          icon: 'none'
+        });
+        return false;
+      }
+      
+      if (!this.formData.contactName.trim()) {
+        uni.showToast({
+          title: '请输入联系人姓名',
+          icon: 'none'
+        });
+        return false;
+      }
+      
+      if (!this.formData.contactPhone.trim()) {
+        uni.showToast({
+          title: '请输入联系电话',
+          icon: 'none'
+        });
+        return false;
+      }
+      
+      // 简单的手机号格式验证
+      const phoneRegex = /^1[3-9]\d{9}$/;
+      if (!phoneRegex.test(this.formData.contactPhone)) {
+        uni.showToast({
+          title: '请输入正确的手机号码',
+          icon: 'none'
+        });
+        return false;
+      }
+      
+      return true;
+    },
+    
+    // 提交表单
+    submitForm() {
+      if (!this.validateForm()) {
+        return;
+      }
+      
+      // 显示加载提示
+      const loadingTitle = this.isEditMode ? '保存中...' : '提交中...';
+      uni.showLoading({
+        title: loadingTitle
+      });
+      
+      // 模拟提交
+      setTimeout(() => {
+        uni.hideLoading();
+        
+        if (this.isEditMode) {
+          // 编辑模式 - 保存修改
+          uni.showModal({
+            title: '保存成功',
+            content: '您的修改已保存成功!',
+            showCancel: false,
+            success: () => {
+              uni.navigateBack();
+            }
+          });
+        } else {
+          // 新建模式 - 提交发布
+          uni.showToast({
+            title: '发布成功',
+            icon: 'success'
+          });
+          
+          // 返回上一页
+          setTimeout(() => {
+            uni.navigateBack();
+          }, 1500);
+        }
+      }, 2000);
+    }
+  }
+}
+</script>
+
+<style lang="scss">
+.purchase-publish-container {
+  min-height: 100vh;
+  background-color: #f5f5f5;
+  padding-bottom: calc(128rpx + env(safe-area-inset-bottom));
+}
+
+.form-container {
+  padding: 20rpx;
+}
+
+.form-item {
+  background-color: #fff;
+  border-radius: 12rpx;
+  padding: 24rpx;
+  margin-bottom: 16rpx;
+  box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
+}
+
+.item-label {
+  display: flex;
+  align-items: center;
+  margin-bottom: 16rpx;
+}
+
+.label-text {
+  font-size: 28rpx;
+  color: #333;
+  font-weight: bold;
+}
+
+.required {
+  color: #ff4d4f;
+  font-size: 28rpx;
+  margin-left: 4rpx;
+}
+
+.optional {
+  color: #999;
+  font-size: 24rpx;
+  margin-left: 8rpx;
+}
+
+.item-content {
+  position: relative;
+}
+
+.form-input {
+  width: 100%;
+  height: 44rpx;
+  font-size: 28rpx;
+  color: #333;
+  line-height: 44rpx;
+}
+
+.form-textarea {
+  width: 100%;
+  min-height: 120rpx;
+  font-size: 28rpx;
+  color: #333;
+  line-height: 1.5;
+}
+
+.char-count {
+  position: absolute;
+  right: 0;
+  bottom: -4rpx;
+  font-size: 24rpx;
+  color: #999;
+}
+
+// 品类选择器
+.category-selector {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 12rpx 0;
+  border-bottom: 1rpx solid #f0f0f0;
+}
+
+.selector-text {
+  font-size: 28rpx;
+  color: #333;
+  
+  &.placeholder {
+    color: #999;
+  }
+}
+
+.arrow-icon {
+  font-size: 24rpx;
+  color: #999;
+}
+
+// 带单位的输入框
+.input-with-unit {
+  display: flex;
+  align-items: center;
+  border-bottom: 1rpx solid #f0f0f0;
+  padding: 12rpx 0;
+}
+
+.currency-symbol {
+  font-size: 28rpx;
+  color: #333;
+  margin-right: 8rpx;
+}
+
+.unit-text {
+  font-size: 28rpx;
+  color: #666;
+  margin-left: 8rpx;
+  white-space: nowrap;
+}
+
+// 图片上传
+.image-upload-area {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 16rpx;
+}
+
+.image-item {
+  position: relative;
+  width: 160rpx;
+  height: 160rpx;
+  border-radius: 8rpx;
+  overflow: hidden;
+}
+
+.uploaded-image {
+  width: 100%;
+  height: 100%;
+}
+
+.image-delete {
+  position: absolute;
+  top: -8rpx;
+  right: -8rpx;
+  width: 32rpx;
+  height: 32rpx;
+  background-color: #ff4d4f;
+  color: #fff;
+  border-radius: 50%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  font-size: 20rpx;
+  font-weight: bold;
+}
+
+.image-upload-btn {
+  width: 160rpx;
+  height: 160rpx;
+  border: 2rpx dashed #ddd;
+  border-radius: 8rpx;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  background-color: #fafafa;
+}
+
+.upload-icon {
+  font-size: 48rpx;
+  color: #999;
+  margin-bottom: 8rpx;
+}
+
+.upload-text {
+  font-size: 24rpx;
+  color: #999;
+}
+
+// 联系人信息
+.contact-input-row {
+  display: flex;
+  align-items: center;
+  margin-bottom: 20rpx;
+  
+  &:last-child {
+    margin-bottom: 0;
+  }
+}
+
+.contact-label {
+  font-size: 28rpx;
+  color: #333;
+  width: 120rpx;
+  font-weight: bold;
+}
+
+.contact-input {
+  flex: 1;
+  height: 44rpx;
+  font-size: 28rpx;
+  color: #333;
+  line-height: 44rpx;
+  border-bottom: 1rpx solid #f0f0f0;
+  padding: 12rpx 0;
+}
+
+// 底部提交按钮
+.bottom-action-bar {
+  position: fixed;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  width: 100%;
+  background-color: #fff;
+  border-top: 1rpx solid #f0f0f0;
+  padding: 20rpx 30rpx;
+  padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
+  z-index: 1000;
+  box-shadow: 0 -2rpx 8rpx rgba(0, 0, 0, 0.05);
+  box-sizing: border-box;
+}
+
+.submit-btn {
+  width: 100%;
+  height: 88rpx;
+  background-color: #4CAF50;
+  border-radius: 12rpx;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  transition: background-color 0.2s ease;
+  box-sizing: border-box;
+  
+  &:active {
+    background-color: #45a049;
+  }
+  
+  .btn-text {
+    font-size: 32rpx;
+    color: #fff;
+    font-weight: bold;
+  }
+}
+
+// 品类选择弹窗
+.picker-modal {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background-color: rgba(0, 0, 0, 0.5);
+  z-index: 2000;
+  display: flex;
+  align-items: flex-end;
+}
+
+.picker-content {
+  width: 100%;
+  background-color: #fff;
+  border-radius: 24rpx 24rpx 0 0;
+  padding: 0;
+}
+
+.picker-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 30rpx;
+  border-bottom: 1rpx solid #f0f0f0;
+}
+
+.picker-title {
+  font-size: 32rpx;
+  font-weight: bold;
+  color: #333;
+}
+
+.picker-close {
+  font-size: 36rpx;
+  color: #999;
+}
+
+.picker-options {
+  padding: 20rpx 0;
+}
+
+.picker-option {
+  padding: 24rpx 30rpx;
+  border-bottom: 1rpx solid #f8f8f8;
+  transition: background-color 0.2s ease;
+  
+  &:last-child {
+    border-bottom: none;
+  }
+  
+  &:active {
+    background-color: #f5f5f5;
+  }
+}
+
+.option-text {
+  font-size: 30rpx;
+  color: #333;
+}
+</style> 

+ 630 - 0
pages/service/sales-detail.vue

@@ -0,0 +1,630 @@
+<template>
+  <view class="detail-container">
+    <!-- 顶部封面图轮播 -->
+    <view class="image-section">
+      <swiper 
+        class="image-swiper" 
+        :indicator-dots="false"
+        :circular="false"
+        :autoplay="false"
+        @change="onSwiperChange"
+      >
+        <swiper-item v-for="(image, index) in imageList" :key="index" @click="previewImage(index)">
+          <image :src="image" mode="aspectFill" class="cover-image" lazy-load></image>
+        </swiper-item>
+      </swiper>
+      
+      <!-- 自定义分页指示器 -->
+      <view class="custom-dots" v-if="imageList.length > 1">
+        <view 
+          class="dot"
+          :class="{ active: currentImageIndex === index }"
+          v-for="(item, index) in imageList" 
+          :key="index"
+        ></view>
+      </view>
+    </view>
+
+    <!-- 标题和类型标签 -->
+    <view class="title-section">
+      <view class="title-content">
+        <text class="product-title">{{ productInfo.title }}</text>
+        <view class="type-tag" :class="productInfo.type">
+          {{ productInfo.type === 'sale' ? '出售' : '收购' }}
+        </view>
+      </view>
+    </view>
+
+    <!-- 核心信息展示卡片 -->
+    <view class="info-card">
+      <view class="info-row">
+        <text class="info-label">分类</text>
+        <text class="info-value">{{ productInfo.category }}</text>
+      </view>
+      <view class="info-row">
+        <text class="info-label">{{ productInfo.type === 'sale' ? '单价' : '收购价' }}</text>
+        <text class="info-value price">¥{{ productInfo.price }}/{{ productInfo.unit }}</text>
+      </view>
+      <view class="info-row">
+        <text class="info-label">数量</text>
+        <text class="info-value">{{ productInfo.quantity }}{{ productInfo.unit }}</text>
+      </view>
+      <view class="info-row">
+        <text class="info-label">所在地</text>
+        <text class="info-value location">{{ productInfo.location }}</text>
+      </view>
+    </view>
+
+    <!-- 补充说明区域 -->
+    <view class="description-card">
+      <view class="card-title">
+        <text>{{ productInfo.type === 'sale' ? '产品详情' : '收购要求' }}</text>
+      </view>
+      <view class="description-content">
+        <text class="description-text">
+          {{ productInfo.description || '无补充说明' }}
+        </text>
+      </view>
+    </view>
+
+    <!-- 发布者信息卡片 -->
+    <view class="publisher-card">
+      <view class="card-title">
+        <text>发布者信息</text>
+      </view>
+      <view class="publisher-info">
+        <view class="info-row">
+          <text class="info-label">联系人</text>
+          <text class="info-value">{{ productInfo.publisher.name }}</text>
+        </view>
+        <view class="info-row">
+          <text class="info-label">联系电话</text>
+          <text class="info-value phone">{{ productInfo.publisher.phone }}</text>
+        </view>
+        <view class="info-row">
+          <text class="info-label">发布时间</text>
+          <text class="info-value">{{ productInfo.publishTime }}</text>
+        </view>
+      </view>
+    </view>
+
+    <!-- 底部操作按钮 -->
+    <view class="action-buttons" v-if="shouldShowActionButtons">
+      <!-- 当前用户发布的内容 -->
+      <template v-if="isOwnProduct">
+        <!-- 已上架状态:显示编辑和下架 -->
+        <template v-if="productStatus === 'approved'">
+          <button class="action-btn edit-btn" @click="editProduct">
+            编辑
+          </button>
+          <button class="action-btn remove-btn" @click="removeProduct">
+            下架
+          </button>
+        </template>
+        
+        <!-- 审核中状态:显示编辑和撤销 -->
+        <template v-else-if="productStatus === 'pending'">
+          <button class="action-btn edit-btn" @click="editProduct">
+            编辑
+          </button>
+          <button class="action-btn cancel-btn" @click="cancelProduct">
+            撤销
+          </button>
+        </template>
+        
+        <!-- 已下架状态:不显示任何按钮 -->
+      </template>
+      
+      <!-- 他人发布的内容 -->
+      <template v-else>
+        <button class="action-btn contact-btn" @click="contactPublisher">
+          立即联系
+        </button>
+      </template>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      currentImageIndex: 0,
+      source: '', // 页面来源,myPublish表示来自我的发布页面
+      productStatus: '', // 产品状态:pending, approved, rejected
+      productInfo: {
+        id: '',
+        type: 'sale', // sale: 出售, purchase: 收购
+        title: '',
+        category: '',
+        price: '',
+        quantity: '',
+        unit: '',
+        location: '',
+        description: '',
+        publisher: {
+          name: '',
+          phone: '',
+          userId: ''
+        },
+        publishTime: '',
+        images: []
+      },
+      imageList: [],
+      isOwnProduct: false // 是否为当前用户发布的产品
+    }
+  },
+  
+  onLoad(options) {
+    // 获取页面参数
+    if (options.id) {
+      this.source = options.source || '';
+      this.productStatus = options.status || '';
+      this.loadProductDetail(options.id, options.type);
+    }
+  },
+  
+  computed: {
+    // 判断是否显示操作按钮
+    shouldShowActionButtons() {
+      if (!this.isOwnProduct) {
+        // 他人发布的内容始终显示联系按钮
+        return true;
+      } else {
+        // 自己发布的内容,已下架状态不显示任何按钮
+        return this.productStatus !== 'rejected';
+      }
+    }
+  },
+  
+  methods: {
+    // 加载产品详情
+    loadProductDetail(id, type) {
+      // 根据类型模拟不同的数据结构
+      let mockData;
+      
+      if (type === 'purchase') {
+        // 收购信息的数据结构
+        mockData = {
+          id: id,
+          type: 'purchase',
+          title: '高价收购优质土豆',
+          category: '蔬菜',
+          price: '3.5',
+          quantity: '1000',
+          unit: '斤',
+          location: '山东·烟台',
+          description: '大量收购优质土豆,要求新鲜无病害,无青皮,规格统一。支持长期合作,价格优惠,现金结算。有货源的农户欢迎联系,我们提供上门收购服务。',
+          publisher: {
+            name: '李**',
+            phone: '138****5678',
+            userId: 'user456'
+          },
+          publishTime: '2025-01-21 10:30',
+          images: [
+            '/static/images/products/agriculture-tools.jpg',
+            '/static/images/products/organic-fertilizer-new.jpg',
+            '/static/images/products/plastic-film.jpg'
+          ]
+        };
+      } else {
+        // 出售信息的数据结构
+        mockData = {
+          id: id,
+          type: type || 'sale',
+          title: '2024年红富士苹果',
+          category: '水果',
+          price: '8.5',
+          quantity: '1000',
+          unit: '斤',
+          location: '山东·烟台',
+          description: '自家果园种植的红富士苹果,个大味甜,果形端正,色泽鲜艳。采用有机种植方式,无农药残留,口感清脆香甜。现大量上市,欢迎各地客商前来洽谈合作。支持批发零售,量大价优。',
+          publisher: {
+            name: '张**',
+            phone: '188****1234',
+            userId: 'user123'
+          },
+          publishTime: '2025-01-21 14:20',
+          images: [
+            '/static/images/products/corn-seeds-new.jpg',
+            '/static/images/products/rice-seeds.jpg',
+            '/static/images/products/seeds-packets.jpg',
+            '/static/images/products/greenhouse-film.jpg'
+          ]
+        };
+      }
+      
+      this.productInfo = mockData;
+      this.imageList = mockData.images;
+      
+      // 判断是否为当前用户发布的产品
+      // 如果来源是我的发布页面,则表示是自己的产品
+      this.isOwnProduct = this.source === 'myPublish';
+    },
+    
+    // 轮播图切换
+    onSwiperChange(e) {
+      this.currentImageIndex = e.detail.current;
+    },
+    
+    // 预览图片
+    previewImage(index) {
+      uni.previewImage({
+        current: index,
+        urls: this.imageList
+      });
+    },
+    
+    // 编辑产品
+    editProduct() {
+      if (this.productInfo.type === 'purchase') {
+        // 收购信息跳转到收购编辑页面
+        uni.navigateTo({
+          url: `/pages/service/purchase-publish?action=edit&id=${this.productInfo.id}`
+        });
+      } else {
+        // 销售信息跳转到销售编辑页面
+        uni.navigateTo({
+          url: `/pages/service/sales-publish?action=edit&id=${this.productInfo.id}&type=${this.productInfo.type}`
+        });
+      }
+    },
+    
+    // 下架产品
+    removeProduct() {
+      uni.showModal({
+        title: '确认下架',
+        content: '确定要下架这条信息吗?下架后其他用户将无法查看。',
+        confirmText: '确认下架',
+        cancelText: '取消',
+        success: (res) => {
+          if (res.confirm) {
+            // 执行下架操作
+            this.handleRemoveProduct();
+          }
+        }
+      });
+    },
+    
+    // 处理下架操作
+    handleRemoveProduct() {
+      // 模拟下架API调用
+      uni.showLoading({ title: '下架中...' });
+      
+      setTimeout(() => {
+        uni.hideLoading();
+        uni.showToast({
+          title: '下架成功',
+          icon: 'success'
+        });
+        
+        // 返回上一页
+        setTimeout(() => {
+          uni.navigateBack();
+        }, 1500);
+      }, 1000);
+    },
+    
+    // 联系发布者
+    contactPublisher() {
+      // 获取真实电话号码并拨打
+      const realPhone = this.getRealPhoneNumber();
+      
+      uni.showModal({
+        title: '联系发布者',
+        content: `确定要拨打 ${realPhone} 吗?`,
+        confirmText: '拨打',
+        cancelText: '取消',
+        success: (res) => {
+          if (res.confirm) {
+            uni.makePhoneCall({
+              phoneNumber: realPhone,
+              fail: () => {
+                uni.showToast({
+                  title: '拨号失败',
+                  icon: 'none'
+                });
+              }
+            });
+          }
+        }
+      });
+    },
+    
+    // 撤销产品(审核中状态)
+    cancelProduct() {
+      uni.showModal({
+        title: '确认撤销',
+        content: '确定要撤销这条发布信息吗?撤销后需要重新提交审核。',
+        confirmText: '确认撤销',
+        cancelText: '取消',
+        success: (res) => {
+          if (res.confirm) {
+            // 执行撤销操作
+            this.handleCancelProduct();
+          }
+        }
+      });
+    },
+    
+    // 处理撤销操作
+    handleCancelProduct() {
+      // 模拟撤销API调用
+      uni.showLoading({ title: '撤销中...' });
+      
+      setTimeout(() => {
+        uni.hideLoading();
+        uni.showToast({
+          title: '撤销成功',
+          icon: 'success'
+        });
+        
+        // 返回上一页
+        setTimeout(() => {
+          uni.navigateBack();
+        }, 1500);
+      }, 1000);
+    },
+    
+    // 获取真实电话号码(实际应用中从API获取)
+    getRealPhoneNumber() {
+      // 模拟从API获取真实电话号码
+      return '18812341234';
+    }
+  }
+}
+</script>
+
+<style lang="scss">
+.detail-container {
+  min-height: 100vh;
+  background-color: #f5f5f5;
+  padding-bottom: 120rpx;
+}
+
+// 顶部封面图轮播
+.image-section {
+  position: relative;
+  margin: 20rpx;
+  border-radius: 16rpx;
+  overflow: hidden;
+  background-color: #fff;
+  box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
+}
+
+.image-swiper {
+  width: 100%;
+  height: 500rpx;
+}
+
+swiper-item {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 100%;
+  height: 100%;
+}
+
+.cover-image {
+  width: 100%;
+  height: 100%;
+}
+
+.custom-dots {
+  position: absolute;
+  bottom: 20rpx;
+  left: 50%;
+  transform: translateX(-50%);
+  display: flex;
+  gap: 12rpx;
+}
+
+.dot {
+  width: 12rpx;
+  height: 12rpx;
+  border-radius: 6rpx;
+  background-color: rgba(255, 255, 255, 0.5);
+  transition: all 0.3s ease;
+  
+  &.active {
+    background-color: #fff;
+    width: 24rpx;
+  }
+}
+
+// 标题和类型标签
+.title-section {
+  margin: 0 20rpx 20rpx;
+  background-color: #fff;
+  border-radius: 16rpx;
+  padding: 30rpx;
+  box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
+}
+
+.title-content {
+  display: flex;
+  justify-content: space-between;
+  align-items: flex-start;
+  gap: 20rpx;
+}
+
+.product-title {
+  flex: 1;
+  font-size: 32rpx;
+  font-weight: bold;
+  color: #333;
+  line-height: 1.4;
+}
+
+.type-tag {
+  padding: 8rpx 16rpx;
+  border-radius: 20rpx;
+  font-size: 24rpx;
+  font-weight: bold;
+  flex-shrink: 0;
+  
+  &.sale {
+    background-color: #e8f5e8;
+    color: #4CAF50;
+  }
+  
+  &.purchase {
+    background-color: #e6f7ff;
+    color: #1890ff;
+  }
+}
+
+// 信息卡片通用样式
+.info-card, .description-card, .publisher-card {
+  margin: 0 20rpx 20rpx;
+  background-color: #fff;
+  border-radius: 16rpx;
+  padding: 30rpx;
+  box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
+}
+
+.card-title {
+  font-size: 28rpx;
+  font-weight: bold;
+  color: #333;
+  margin-bottom: 24rpx;
+  padding-bottom: 16rpx;
+  border-bottom: 2rpx solid #f5f5f5;
+}
+
+// 核心信息展示
+.info-row {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 16rpx 0;
+  border-bottom: 1rpx solid #f8f8f8;
+  
+  &:last-child {
+    border-bottom: none;
+  }
+}
+
+.info-label {
+  font-size: 28rpx;
+  color: #666;
+  flex-shrink: 0;
+  width: 120rpx;
+}
+
+.info-value {
+  font-size: 28rpx;
+  color: #333;
+  font-weight: 500;
+  text-align: right;
+  flex: 1;
+  
+  &.price {
+    color: #ff6b35;
+    font-weight: bold;
+    font-size: 30rpx;
+  }
+  
+  &.location {
+    color: #4CAF50;
+  }
+  
+  &.phone {
+    color: #1890ff;
+  }
+}
+
+// 补充说明区域
+.description-content {
+  padding: 20rpx;
+  background-color: #f8f9fa;
+  border-radius: 12rpx;
+  border-left: 4rpx solid #4CAF50;
+}
+
+.description-text {
+  font-size: 26rpx;
+  color: #666;
+  line-height: 1.6;
+}
+
+// 发布者信息
+.publisher-info {
+  .info-row {
+    padding: 20rpx 0;
+  }
+}
+
+// 底部操作按钮
+.action-buttons {
+  position: fixed;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  padding: 20rpx 30rpx;
+  padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
+  background-color: #fff;
+  border-top: 1rpx solid #f0f0f0;
+  display: flex;
+  gap: 20rpx;
+  z-index: 100;
+}
+
+.action-btn {
+  flex: 1;
+  height: 80rpx;
+  border-radius: 40rpx;
+  font-size: 28rpx;
+  font-weight: bold;
+  border: none;
+  transition: all 0.3s ease;
+  
+  &.edit-btn {
+    background-color: #fff;
+    color: #4CAF50;
+    border: 2rpx solid #4CAF50;
+    
+    &:active {
+      background-color: #f0fdf4;
+    }
+  }
+  
+  &.remove-btn {
+    background-color: #fff;
+    color: #ff4757;
+    border: 2rpx solid #ff4757;
+    
+    &:active {
+      background-color: #fff5f5;
+    }
+  }
+  
+  &.cancel-btn {
+    background-color: #fff;
+    color: #fa8c16;
+    border: 2rpx solid #fa8c16;
+    
+    &:active {
+      background-color: #fff7e6;
+    }
+  }
+  
+  &.contact-btn {
+    background-color: #4CAF50;
+    color: #fff;
+    
+    &:active {
+      background-color: #45a049;
+    }
+  }
+}
+
+// 防止按钮点击状态样式被覆盖
+button[disabled] {
+  opacity: 0.6;
+}
+
+button::after {
+  border: none;
+}
+</style> 

+ 751 - 0
pages/service/sales-publish.vue

@@ -0,0 +1,751 @@
+<template>
+  <view class="sales-publish-container">
+    <!-- 表单内容 -->
+    <view class="form-container">
+      <!-- 产品名称 -->
+      <view class="form-item">
+        <view class="item-label">
+          <text class="label-text">产品名称</text>
+          <text class="required">*</text>
+        </view>
+        <view class="item-content">
+          <input
+            class="form-input"
+            v-model="formData.productName"
+            placeholder="请输入产品名称"
+            placeholder-style="color: #999;"
+            maxlength="20"
+            @input="onNameInput"
+          />
+          <view class="char-count">{{ nameLength }}/20</view>
+        </view>
+      </view>
+
+      <!-- 产品分类 -->
+      <view class="form-item">
+        <view class="item-label">
+          <text class="label-text">产品分类</text>
+          <text class="required">*</text>
+        </view>
+        <view class="item-content">
+          <view class="category-selector" @click="showCategoryPicker = true">
+            <text class="selector-text" :class="{ placeholder: !formData.category }">
+              {{ formData.category || '请选择产品分类' }}
+            </text>
+            <text class="arrow-icon">></text>
+          </view>
+        </view>
+      </view>
+
+      <!-- 销售价格 -->
+      <view class="form-item">
+        <view class="item-label">
+          <text class="label-text">销售价格</text>
+          <text class="required">*</text>
+        </view>
+        <view class="item-content">
+          <view class="input-with-unit">
+            <text class="currency-symbol">¥</text>
+            <input
+              class="form-input"
+              v-model="formData.price"
+              placeholder="请输入销售价格"
+              placeholder-style="color: #999;"
+              type="digit"
+            />
+            <text class="unit-text">元/斤</text>
+          </view>
+        </view>
+      </view>
+
+      <!-- 产品简介 -->
+      <view class="form-item">
+        <view class="item-label">
+          <text class="label-text">产品简介</text>
+        </view>
+        <view class="item-content">
+          <textarea
+            class="form-textarea"
+            v-model="formData.description"
+            placeholder="请简单介绍您的农产品特色、种植方式等"
+            placeholder-style="color: #999;"
+            maxlength="80"
+            auto-height
+            @input="onDescInput"
+          />
+          <view class="char-count">{{ descLength }}/80</view>
+        </view>
+      </view>
+
+      <!-- 产品图片 -->
+      <view class="form-item">
+        <view class="item-label">
+          <text class="label-text">产品图片</text>
+          <text class="required">*</text>
+          <text class="optional">(最多3张)</text>
+        </view>
+        <view class="item-content">
+          <view class="image-upload-area">
+            <view 
+              class="image-item"
+              v-for="(image, index) in formData.images"
+              :key="index"
+            >
+              <image class="uploaded-image" :src="image" mode="aspectFill"></image>
+              <view class="image-delete" @click="removeImage(index)">×</view>
+            </view>
+            <view 
+              class="image-upload-btn"
+              v-if="formData.images.length < 3"
+              @click="chooseImage"
+            >
+              <text class="upload-icon">+</text>
+              <text class="upload-text">上传图片</text>
+            </view>
+          </view>
+        </view>
+      </view>
+
+      <!-- 产地信息 -->
+      <view class="form-item">
+        <view class="item-label">
+          <text class="label-text">产地信息</text>
+        </view>
+        <view class="contact-info">
+          <view class="contact-row">
+            <text class="contact-label">产地:</text>
+            <text class="contact-value">{{ locationInfo.address }}</text>
+          </view>
+          <view class="contact-row">
+            <text class="contact-label">地块:</text>
+            <text class="contact-value">{{ locationInfo.field }}</text>
+          </view>
+        </view>
+      </view>
+
+      <!-- 联系人信息 -->
+      <view class="form-item">
+        <view class="item-label">
+          <text class="label-text">联系人信息</text>
+        </view>
+        <view class="item-content">
+          <view class="contact-input-row">
+            <text class="contact-label">联系人:</text>
+            <input
+              class="contact-input"
+              v-model="formData.contactName"
+              placeholder="请输入联系人姓名"
+              placeholder-style="color: #999;"
+              maxlength="10"
+            />
+          </view>
+          <view class="contact-input-row">
+            <text class="contact-label">电话:</text>
+            <input
+              class="contact-input"
+              v-model="formData.contactPhone"
+              placeholder="请输入联系电话"
+              placeholder-style="color: #999;"
+              type="number"
+              maxlength="11"
+            />
+          </view>
+        </view>
+      </view>
+    </view>
+
+    <!-- 底部提交按钮 -->
+    <view class="bottom-action-bar">
+      <view class="submit-btn" @click="submitForm">
+        <text class="btn-text">{{ isEditMode ? '保存修改' : '提交审核' }}</text>
+      </view>
+    </view>
+
+    <!-- 分类选择弹窗 -->
+    <view class="picker-modal" v-if="showCategoryPicker" @click="showCategoryPicker = false">
+      <view class="picker-content" @click.stop>
+        <view class="picker-header">
+          <text class="picker-title">选择产品分类</text>
+          <text class="picker-close" @click="showCategoryPicker = false">×</text>
+        </view>
+        <view class="picker-options">
+          <view 
+            class="picker-option"
+            v-for="category in categoryOptions"
+            :key="category"
+            @click="selectCategory(category)"
+          >
+            <text class="option-text">{{ category }}</text>
+          </view>
+        </view>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      isEditMode: false, // 是否为编辑模式
+      editProductId: '', // 编辑的产品ID
+      productType: 'sale', // 产品类型:sale(销售)或 purchase(收购)
+      formData: {
+        productName: '',
+        category: '',
+        price: '',
+        description: '',
+        images: [],
+        contactName: '',
+        contactPhone: ''
+      },
+      locationInfo: {
+        address: '张家村',
+        field: '水稻田A区'
+      },
+      categoryOptions: ['蔬菜', '水果', '粮食', '畜产品', '水产品', '中药材'],
+      showCategoryPicker: false,
+      nameLength: 0,
+      descLength: 0
+    }
+  },
+  
+  onLoad(options) {
+    // 检查是否为编辑模式
+    if (options.action === 'edit' && options.id) {
+      this.isEditMode = true;
+      this.editProductId = options.id;
+      this.productType = options.type || 'sale';
+      
+      // 设置页面标题
+      uni.setNavigationBarTitle({
+        title: this.productType === 'sale' ? '编辑销售信息' : '编辑收购信息'
+      });
+      
+      // 加载产品数据
+      this.loadProductData();
+    } else {
+      // 新建模式
+      this.isEditMode = false;
+      uni.setNavigationBarTitle({
+        title: '发布农产品'
+      });
+    }
+  },
+  
+  methods: {
+    // 加载产品数据(编辑模式)
+    loadProductData() {
+      // 模拟从API加载数据,实际应用中需要根据ID和类型调用相应的API
+      uni.showLoading({ title: '加载中...' });
+      
+      setTimeout(() => {
+        let mockData;
+        
+        if (this.productType === 'sale') {
+          // 销售信息的模拟数据
+          mockData = {
+            productName: '2024年红富士苹果',
+            category: '水果',
+            price: '8.5',
+            description: '自家果园种植的红富士苹果,个大味甜,果形端正,色泽鲜艳。采用有机种植方式,无农药残留,口感清脆香甜。',
+            images: [
+              '/static/images/products/corn-seeds-new.jpg',
+              '/static/images/products/rice-seeds.jpg'
+            ],
+            contactName: '张先生',
+            contactPhone: '18812341234'
+          };
+        } else {
+          // 收购信息的模拟数据
+          mockData = {
+            productName: '高价收购优质土豆',
+            category: '蔬菜',
+            price: '3.5',
+            description: '大量收购优质土豆,要求新鲜无病害,无青皮,规格统一。支持长期合作,价格优惠,现金结算。',
+            images: [
+              '/static/images/products/agriculture-tools.jpg'
+            ],
+            contactName: '李先生',
+            contactPhone: '13856785678'
+          };
+        }
+        
+        // 填充表单数据
+        this.formData = { ...mockData };
+        
+        // 更新字符计数
+        this.nameLength = this.formData.productName.length;
+        this.descLength = this.formData.description.length;
+        
+        uni.hideLoading();
+      }, 1000);
+    },
+    
+    // 产品名称输入处理
+    onNameInput(e) {
+      this.nameLength = e.detail.value.length;
+    },
+    
+    // 描述输入处理
+    onDescInput(e) {
+      this.descLength = e.detail.value.length;
+    },
+    
+    // 选择分类
+    selectCategory(category) {
+      this.formData.category = category;
+      this.showCategoryPicker = false;
+    },
+    
+    // 选择图片
+    chooseImage() {
+      const remainingCount = 3 - this.formData.images.length;
+      uni.chooseImage({
+        count: remainingCount,
+        sizeType: ['compressed'],
+        sourceType: ['album', 'camera'],
+        success: (res) => {
+          this.formData.images = this.formData.images.concat(res.tempFilePaths);
+        },
+        fail: (err) => {
+          console.error('选择图片失败:', err);
+        }
+      });
+    },
+    
+    // 删除图片
+    removeImage(index) {
+      this.formData.images.splice(index, 1);
+    },
+    
+    // 表单验证
+    validateForm() {
+      if (!this.formData.productName.trim()) {
+        uni.showToast({
+          title: '请输入产品名称',
+          icon: 'none'
+        });
+        return false;
+      }
+      
+      if (!this.formData.category) {
+        uni.showToast({
+          title: '请选择产品分类',
+          icon: 'none'
+        });
+        return false;
+      }
+      
+      if (!this.formData.price || this.formData.price <= 0) {
+        uni.showToast({
+          title: '请输入有效的销售价格',
+          icon: 'none'
+        });
+        return false;
+      }
+      
+      if (this.formData.images.length === 0) {
+        uni.showToast({
+          title: '请至少上传一张产品图片',
+          icon: 'none'
+        });
+        return false;
+      }
+      
+      if (!this.formData.contactName.trim()) {
+        uni.showToast({
+          title: '请输入联系人姓名',
+          icon: 'none'
+        });
+        return false;
+      }
+      
+      if (!this.formData.contactPhone.trim()) {
+        uni.showToast({
+          title: '请输入联系电话',
+          icon: 'none'
+        });
+        return false;
+      }
+      
+      // 简单的手机号格式验证
+      const phoneRegex = /^1[3-9]\d{9}$/;
+      if (!phoneRegex.test(this.formData.contactPhone)) {
+        uni.showToast({
+          title: '请输入正确的手机号码',
+          icon: 'none'
+        });
+        return false;
+      }
+      
+      return true;
+    },
+    
+    // 提交表单
+    submitForm() {
+      if (!this.validateForm()) {
+        return;
+      }
+      
+      // 显示加载提示
+      const loadingTitle = this.isEditMode ? '保存中...' : '提交中...';
+      uni.showLoading({
+        title: loadingTitle
+      });
+      
+      // 模拟提交
+      setTimeout(() => {
+        uni.hideLoading();
+        
+        if (this.isEditMode) {
+          // 编辑模式 - 保存修改
+          uni.showModal({
+            title: '保存成功',
+            content: '您的修改已保存成功!',
+            showCancel: false,
+            success: () => {
+              uni.navigateBack();
+            }
+          });
+        } else {
+          // 新建模式 - 提交审核
+          uni.showModal({
+            title: '提交成功',
+            content: '您的农产品信息已提交审核,审核通过后将在销售页面展示。',
+            showCancel: false,
+            success: () => {
+              uni.navigateBack();
+            }
+          });
+        }
+      }, 2000);
+    }
+  }
+}
+</script>
+
+<style lang="scss">
+.sales-publish-container {
+  min-height: 100vh;
+  background-color: #f5f5f5;
+  padding-bottom: calc(128rpx + env(safe-area-inset-bottom));
+}
+
+.form-container {
+  padding: 20rpx;
+}
+
+.form-item {
+  background-color: #fff;
+  border-radius: 12rpx;
+  padding: 24rpx;
+  margin-bottom: 16rpx;
+  box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
+}
+
+.item-label {
+  display: flex;
+  align-items: center;
+  margin-bottom: 16rpx;
+}
+
+.label-text {
+  font-size: 28rpx;
+  color: #333;
+  font-weight: bold;
+}
+
+.required {
+  color: #ff4d4f;
+  font-size: 28rpx;
+  margin-left: 4rpx;
+}
+
+.optional {
+  color: #999;
+  font-size: 24rpx;
+  margin-left: 8rpx;
+}
+
+.item-content {
+  position: relative;
+}
+
+.form-input {
+  width: 100%;
+  height: 44rpx;
+  font-size: 28rpx;
+  color: #333;
+  line-height: 44rpx;
+}
+
+.form-textarea {
+  width: 100%;
+  min-height: 120rpx;
+  font-size: 28rpx;
+  color: #333;
+  line-height: 1.5;
+}
+
+.char-count {
+  position: absolute;
+  right: 0;
+  bottom: -4rpx;
+  font-size: 24rpx;
+  color: #999;
+}
+
+// 分类选择器
+.category-selector {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 12rpx 0;
+  border-bottom: 1rpx solid #f0f0f0;
+}
+
+.selector-text {
+  font-size: 28rpx;
+  color: #333;
+  
+  &.placeholder {
+    color: #999;
+  }
+}
+
+.arrow-icon {
+  font-size: 24rpx;
+  color: #999;
+}
+
+// 带单位的输入框
+.input-with-unit {
+  display: flex;
+  align-items: center;
+  border-bottom: 1rpx solid #f0f0f0;
+  padding: 12rpx 0;
+}
+
+.currency-symbol {
+  font-size: 28rpx;
+  color: #333;
+  margin-right: 8rpx;
+}
+
+.unit-text {
+  font-size: 28rpx;
+  color: #666;
+  margin-left: 8rpx;
+  white-space: nowrap;
+}
+
+// 图片上传
+.image-upload-area {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 16rpx;
+}
+
+.image-item {
+  position: relative;
+  width: 160rpx;
+  height: 160rpx;
+  border-radius: 8rpx;
+  overflow: hidden;
+}
+
+.uploaded-image {
+  width: 100%;
+  height: 100%;
+}
+
+.image-delete {
+  position: absolute;
+  top: -8rpx;
+  right: -8rpx;
+  width: 32rpx;
+  height: 32rpx;
+  background-color: #ff4d4f;
+  color: #fff;
+  border-radius: 50%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  font-size: 20rpx;
+  font-weight: bold;
+}
+
+.image-upload-btn {
+  width: 160rpx;
+  height: 160rpx;
+  border: 2rpx dashed #ddd;
+  border-radius: 8rpx;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  background-color: #fafafa;
+}
+
+.upload-icon {
+  font-size: 48rpx;
+  color: #999;
+  margin-bottom: 8rpx;
+}
+
+.upload-text {
+  font-size: 24rpx;
+  color: #999;
+}
+
+// 产地信息
+.contact-info {
+  background-color: #f8f9fa;
+  border-radius: 8rpx;
+  padding: 20rpx;
+}
+
+.contact-row {
+  display: flex;
+  align-items: center;
+  margin-bottom: 12rpx;
+  
+  &:last-child {
+    margin-bottom: 0;
+  }
+}
+
+.contact-value {
+  font-size: 26rpx;
+  color: #333;
+}
+
+// 联系人信息输入
+.contact-input-row {
+  display: flex;
+  align-items: center;
+  margin-bottom: 20rpx;
+  
+  &:last-child {
+    margin-bottom: 0;
+  }
+}
+
+.contact-label {
+  font-size: 28rpx;
+  color: #333;
+  width: 120rpx;
+  font-weight: bold;
+}
+
+.contact-input {
+  flex: 1;
+  height: 44rpx;
+  font-size: 28rpx;
+  color: #333;
+  line-height: 44rpx;
+  border-bottom: 1rpx solid #f0f0f0;
+  padding: 12rpx 0;
+}
+
+// 底部提交按钮
+.bottom-action-bar {
+  position: fixed;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  width: 100%;
+  background-color: #fff;
+  border-top: 1rpx solid #f0f0f0;
+  padding: 20rpx 30rpx;
+  padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
+  z-index: 1000;
+  box-shadow: 0 -2rpx 8rpx rgba(0, 0, 0, 0.05);
+  box-sizing: border-box;
+}
+
+.submit-btn {
+  width: 100%;
+  height: 88rpx;
+  background-color: #4CAF50;
+  border-radius: 12rpx;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  transition: background-color 0.2s ease;
+  box-sizing: border-box;
+  
+  &:active {
+    background-color: #45a049;
+  }
+  
+  .btn-text {
+    font-size: 32rpx;
+    color: #fff;
+    font-weight: bold;
+  }
+}
+
+// 分类选择弹窗
+.picker-modal {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background-color: rgba(0, 0, 0, 0.5);
+  z-index: 2000;
+  display: flex;
+  align-items: flex-end;
+}
+
+.picker-content {
+  width: 100%;
+  background-color: #fff;
+  border-radius: 24rpx 24rpx 0 0;
+  padding: 0;
+}
+
+.picker-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 30rpx;
+  border-bottom: 1rpx solid #f0f0f0;
+}
+
+.picker-title {
+  font-size: 32rpx;
+  font-weight: bold;
+  color: #333;
+}
+
+.picker-close {
+  font-size: 36rpx;
+  color: #999;
+}
+
+.picker-options {
+  padding: 20rpx 0;
+}
+
+.picker-option {
+  padding: 24rpx 30rpx;
+  border-bottom: 1rpx solid #f8f8f8;
+  transition: background-color 0.2s ease;
+  
+  &:last-child {
+    border-bottom: none;
+  }
+  
+  &:active {
+    background-color: #f5f5f5;
+  }
+}
+
+.option-text {
+  font-size: 30rpx;
+  color: #333;
+}
+</style> 

+ 540 - 0
pages/service/sales.vue

@@ -0,0 +1,540 @@
+<template>
+  <view class="sales-container">
+    <!-- 顶部Tab标签页 -->
+    <view class="tab-header">
+      <view class="tab-list">
+        <view 
+          class="tab-item"
+          :class="{ active: activeTab === 'all' }"
+          @click="switchTab('all')"
+        >
+          <text class="tab-text">全部</text>
+        </view>
+        <view 
+          class="tab-item"
+          :class="{ active: activeTab === 'sale' }"
+          @click="switchTab('sale')"
+        >
+          <text class="tab-text">出售信息</text>
+        </view>
+        <view 
+          class="tab-item"
+          :class="{ active: activeTab === 'purchase' }"
+          @click="switchTab('purchase')"
+        >
+          <text class="tab-text">收购信息</text>
+        </view>
+      </view>
+      <view class="tab-indicator" :style="{ left: getIndicatorPosition() }"></view>
+    </view>
+
+    <!-- 搜索筛选 -->
+    <view class="search-section">
+      <view class="search-box">
+        <image class="search-icon" src="/static/icons/search.png" mode="aspectFit"></image>
+        <input 
+          class="search-input" 
+          placeholder="搜索农产品信息" 
+          placeholder-style="color: #999;"
+          v-model="searchKeyword"
+          @confirm="handleSearch"
+        />
+      </view>
+    </view>
+
+    <!-- 全部农产品信息列表 -->
+    <view class="content-container">
+      <view class="info-list">
+        <view 
+          class="info-card"
+          v-for="item in filteredAllInfo" 
+          :key="`${item.type}_${item.id}`"
+          @click="navigateToDetail(item)"
+        >
+          <view class="card-content">
+            <!-- 封面图片 -->
+            <view class="info-image">
+              <image :src="item.image" mode="aspectFill"></image>
+            </view>
+            
+            <!-- 信息内容 -->
+            <view class="info-content">
+              <!-- 类型标签和标题 -->
+              <view class="info-header">
+                <view class="type-tag" :class="item.type">
+                  {{ item.type === 'sale' ? '出售' : '收购' }}
+                </view>
+                <view class="info-title">{{ item.title }}</view>
+              </view>
+              
+              <!-- 简要说明 -->
+              <view class="info-desc">{{ item.description }}</view>
+              
+              <!-- 底部信息 -->
+              <view class="info-footer">
+                <view class="publish-info">
+                  <text class="publisher">{{ item.publisher }}</text>
+                  <text class="publish-time">{{ item.publishTime }}</text>
+                </view>
+              </view>
+            </view>
+          </view>
+        </view>
+      </view>
+    </view>
+
+    <!-- 浮动发布按钮 -->
+    <view class="floating-btn" @click="navigateToMyPublish">
+      <view class="btn-icon">+</view>
+      <text class="btn-text">我的发布</text>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      activeTab: 'all', // 当前活跃的标签页
+      searchKeyword: '',
+      
+      // 全部农产品信息列表(出售+收购)
+      allInfoList: [
+        // 出售信息
+        {
+          id: 1,
+          type: 'sale',
+          title: '优质红薯 ¥2.5/斤',
+          description: '自家种植,香甜可口,现挖现卖',
+          image: '/static/images/products/corn-seeds-new.jpg',
+          publisher: '李**',
+          publishTime: '今天',
+          price: '2.5',
+          unit: '斤'
+        },
+        {
+          id: 2,
+          type: 'sale', 
+          title: '有机苹果 ¥8.5/斤',
+          description: '新鲜采摘,无农药残留,口感清脆',
+          image: '/static/images/products/rice-seeds.jpg',
+          publisher: '张**',
+          publishTime: '2小时前',
+          price: '8.5',
+          unit: '斤'
+        },
+        {
+          id: 3,
+          type: 'sale',
+          title: '土鸡蛋 ¥2.0/个',
+          description: '散养土鸡,营养丰富,蛋黄金黄',
+          image: '/static/images/products/seeds-packets.jpg',
+          publisher: '王**',
+          publishTime: '昨天',
+          price: '2.0',
+          unit: '个'
+        },
+        {
+          id: 4,
+          type: 'sale',
+          title: '新鲜玉米 ¥3.0/斤',
+          description: '当季玉米,粒粒饱满,甜度高',
+          image: '/static/images/products/greenhouse-film.jpg',
+          publisher: '陈**',
+          publishTime: '2天前',
+          price: '3.0',
+          unit: '斤'
+        },
+        // 收购信息
+        {
+          id: 5,
+          type: 'purchase',
+          title: '高价收购优质土豆 ¥3.5/斤',
+          description: '大量收购,要求新鲜无病害,长期合作',
+          image: '/static/images/products/agriculture-tools.jpg',
+          publisher: '刘**',
+          publishTime: '今天',
+          quantity: '1000斤',
+          budgetPrice: '3.5',
+          unit: '斤'
+        },
+        {
+          id: 6,
+          type: 'purchase',
+          title: '收购新鲜玉米 ¥2.8/斤',
+          description: '需求量大,价格优惠,现金结算',
+          image: '/static/images/products/organic-fertilizer-new.jpg',
+          publisher: '周**',
+          publishTime: '5小时前',
+          quantity: '5000斤',
+          budgetPrice: '2.8',
+          unit: '斤'
+        },
+        {
+          id: 7,
+          type: 'purchase',
+          title: '收购有机蔬菜 ¥8.0/斤',
+          description: '要求有机认证,品质优良,长期收购',
+          image: '/static/images/products/plastic-film.jpg',
+          publisher: '赵**',
+          publishTime: '昨天',
+          quantity: '500斤',
+          budgetPrice: '8.0',
+          unit: '斤'
+        },
+        {
+          id: 8,
+          type: 'sale',
+          title: '优质大米 ¥6.8/斤',
+          description: '当季新米,粒粒饱满,口感香甜',
+          image: '/static/images/products/fertilizer.jpg',
+          publisher: '孙**',
+          publishTime: '3天前',
+          price: '6.8',
+          unit: '斤'
+        }
+      ]
+    }
+  },
+  
+  computed: {
+    filteredAllInfo() {
+      let list = this.allInfoList;
+      
+      // 按类型筛选
+      if (this.activeTab === 'sale') {
+        list = list.filter(item => item.type === 'sale');
+      } else if (this.activeTab === 'purchase') {
+        list = list.filter(item => item.type === 'purchase');
+      }
+      
+      // 按搜索关键词筛选
+      if (this.searchKeyword.trim()) {
+        const keyword = this.searchKeyword.trim().toLowerCase();
+        list = list.filter(item => 
+          item.title.toLowerCase().includes(keyword) || 
+          item.description.toLowerCase().includes(keyword) ||
+          item.publisher.toLowerCase().includes(keyword)
+        );
+      }
+      
+      return list;
+    }
+  },
+  
+  methods: {
+    // 切换Tab标签页
+    switchTab(tab) {
+      this.activeTab = tab;
+    },
+    
+    // 获取指示器位置
+    getIndicatorPosition() {
+      const positions = {
+        'all': '0%',
+        'sale': '33.33%', 
+        'purchase': '66.66%'
+      };
+      return positions[this.activeTab] || '0%';
+    },
+    
+    // 搜索处理
+    handleSearch() {
+      // 搜索逻辑已在computed中处理
+    },
+    
+    // 导航到详情页
+    navigateToDetail(item) {
+      uni.navigateTo({
+        url: `/pages/service/sales-detail?id=${item.id}&type=${item.type}&title=${encodeURIComponent(item.title)}`
+      });
+    },
+    
+    // 导航到我的发布页面
+    navigateToMyPublish() {
+      uni.navigateTo({
+        url: '/pages/service/my-publish'
+      });
+    }
+  }
+}
+</script>
+
+<style lang="scss">
+.sales-container {
+  min-height: 100vh;
+  background-color: #f5f5f5;
+  padding-bottom: 120rpx;
+}
+
+.tab-header {
+  background-color: #fff;
+  position: relative;
+  border-bottom: 1rpx solid #f0f0f0;
+}
+
+.tab-list {
+  display: flex;
+  align-items: center;
+}
+
+.tab-item {
+  flex: 1;
+  text-align: center;
+  padding: 32rpx 0;
+  position: relative;
+  
+  .tab-text {
+    font-size: 30rpx;
+    color: #666;
+    font-weight: 500;
+    transition: color 0.3s ease;
+  }
+  
+  &.active .tab-text {
+    color: #4CAF50;
+    font-weight: bold;
+  }
+}
+
+.tab-indicator {
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  width: 33.33%;
+  height: 4rpx;
+  background-color: #4CAF50;
+  transition: left 0.3s ease;
+}
+
+
+
+.search-section {
+  background-color: #fff;
+  padding: 20rpx;
+  border-bottom: 1rpx solid #f0f0f0;
+}
+
+.search-box {
+  flex: 1;
+  display: flex;
+  align-items: center;
+  background-color: #f8f8f8;
+  border-radius: 32rpx;
+  padding: 16rpx 24rpx;
+}
+
+.search-icon {
+  width: 32rpx;
+  height: 32rpx;
+  margin-right: 16rpx;
+}
+
+.search-input {
+  flex: 1;
+  font-size: 28rpx;
+  line-height: 1.5;
+}
+
+.filter-btn {
+  display: flex;
+  align-items: center;
+  padding: 16rpx 24rpx;
+  background-color: #f8f8f8;
+  border-radius: 24rpx;
+  font-size: 28rpx;
+  color: #666;
+  
+  .filter-icon {
+    margin-left: 8rpx;
+    font-size: 20rpx;
+  }
+}
+
+.category-tags {
+  background-color: #fff;
+  border-bottom: 1rpx solid #f0f0f0;
+}
+
+.tags-scroll {
+  white-space: nowrap;
+}
+
+.tags-list {
+  display: inline-flex;
+  padding: 0 20rpx;
+}
+
+.tag-item {
+  flex-shrink: 0;
+  padding: 20rpx 32rpx;
+  margin-right: 8rpx;
+  font-size: 28rpx;
+  color: #666;
+  border-radius: 32rpx;
+  transition: all 0.2s ease;
+  
+  &.active {
+    color: #4CAF50;
+    background-color: #f0fdf4;
+    font-weight: bold;
+  }
+}
+
+// 内容容器
+.content-container {
+  padding: 20rpx;
+}
+
+.info-list {
+  display: flex;
+  flex-direction: column;
+  gap: 16rpx;
+}
+
+// 统一信息卡片样式
+.info-card {
+  background-color: #fff;
+  border-radius: 12rpx;
+  overflow: hidden;
+  box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
+  transition: transform 0.2s ease;
+  
+  &:active {
+    transform: scale(0.98);
+  }
+}
+
+.card-content {
+  display: flex;
+  padding: 20rpx;
+  gap: 20rpx;
+}
+
+// 封面图片
+.info-image {
+  width: 160rpx;
+  height: 160rpx;
+  border-radius: 8rpx;
+  overflow: hidden;
+  flex-shrink: 0;
+  
+  image {
+    width: 100%;
+    height: 100%;
+  }
+}
+
+// 信息内容
+.info-content {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+}
+
+// 信息头部
+.info-header {
+  display: flex;
+  align-items: flex-start;
+  margin-bottom: 12rpx;
+  gap: 12rpx;
+}
+
+.type-tag {
+  padding: 6rpx 12rpx;
+  border-radius: 12rpx;
+  font-size: 20rpx;
+  font-weight: bold;
+  flex-shrink: 0;
+  
+  &.sale {
+    background-color: #e8f5e8;
+    color: #4CAF50;
+  }
+  
+  &.purchase {
+    background-color: #e6f7ff;
+    color: #1890ff;
+  }
+}
+
+.info-title {
+  font-size: 28rpx;
+  font-weight: bold;
+  color: #333;
+  flex: 1;
+  line-height: 1.4;
+}
+
+// 简要说明
+.info-desc {
+  font-size: 26rpx;
+  color: #666;
+  margin-bottom: 16rpx;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  line-height: 1.4;
+}
+
+// 底部信息
+.info-footer {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.publish-info {
+  display: flex;
+  align-items: center;
+  gap: 16rpx;
+}
+
+.publisher {
+  font-size: 24rpx;
+  color: #4CAF50;
+  font-weight: bold;
+}
+
+.publish-time {
+  font-size: 24rpx;
+  color: #999;
+}
+
+// 浮动发布按钮
+.floating-btn {
+  position: fixed;
+  bottom: 120rpx;
+  right: 30rpx;
+  width: 140rpx;
+  height: 140rpx;
+  background-color: #4CAF50;
+  border-radius: 70rpx;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  box-shadow: 0 8rpx 24rpx rgba(76, 175, 80, 0.3);
+  z-index: 1000;
+  transition: transform 0.2s ease;
+  
+  &:active {
+    transform: scale(0.95);
+  }
+  
+  .btn-icon {
+    font-size: 56rpx;
+    color: #fff;
+    font-weight: 300;
+    line-height: 1;
+    margin-bottom: 2rpx;
+  }
+  
+  .btn-text {
+    font-size: 22rpx;
+    color: #fff;
+    font-weight: bold;
+  }
+}
+</style> 

+ 44 - 47
pages/settings/index.vue

@@ -48,10 +48,6 @@
           <text>关于我们</text>
           <text class="arrow">></text>
         </view>
-        <view class="settings-item" @click="handleContact">
-          <text>联系客服</text>
-          <text class="arrow">></text>
-        </view>
         <view class="settings-item" @click="navigateToPrivacy">
           <text>隐私政策</text>
           <text class="arrow">></text>
@@ -71,29 +67,27 @@ export default {
         crop: true,
         weather: true
       },
+      
       // 缓存大小
       cacheSize: '0.00MB',
+      
       // 版本号
       version: '1.0.0'
-    }
+    };
   },
-
-  onShow() {
-    this.getCacheSize()
-    this.loadNotificationSettings()
-  },
-
+  
   methods: {
     // 获取缓存大小
     getCacheSize() {
+      // 实际项目中需要调用相关API获取缓存大小
       uni.getStorageInfo({
         success: (res) => {
-          const size = (res.currentSize / 1024).toFixed(2)
-          this.cacheSize = size + 'MB'
+          const size = (res.currentSize / 1024).toFixed(2);
+          this.cacheSize = size + 'MB';
         }
-      })
+      });
     },
-
+    
     // 清除缓存
     handleClearCache() {
       uni.showModal({
@@ -106,70 +100,73 @@ export default {
                 uni.showToast({
                   title: '清除成功',
                   icon: 'success'
-                })
-                this.getCacheSize()
+                });
+                this.getCacheSize();
               }
-            })
+            });
           }
         }
-      })
+      });
     },
-
+    
     // 检查更新
     checkUpdate() {
-      uni.showLoading({ title: '检查更新中...' })
+      // 实际项目中需要调用后端API检查更新
+      uni.showLoading({ title: '检查更新中...' });
       setTimeout(() => {
-        uni.hideLoading()
+        uni.hideLoading();
         uni.showToast({
           title: '已是最新版本',
           icon: 'none'
-        })
-      }, 1500)
+        });
+      }, 1500);
     },
-
+    
     // 通知设置处理函数
     handleSystemNotification(e) {
-      this.notifications.system = e.detail.value
-      this.saveNotificationSettings()
+      this.notifications.system = e.detail.value;
+      this.saveNotificationSettings();
     },
+    
     handleCropNotification(e) {
-      this.notifications.crop = e.detail.value
-      this.saveNotificationSettings()
+      this.notifications.crop = e.detail.value;
+      this.saveNotificationSettings();
     },
+    
     handleWeatherNotification(e) {
-      this.notifications.weather = e.detail.value
-      this.saveNotificationSettings()
+      this.notifications.weather = e.detail.value;
+      this.saveNotificationSettings();
     },
-
+    
     // 保存通知设置
     saveNotificationSettings() {
-      uni.setStorageSync('notifications', this.notifications)
+      uni.setStorageSync('notifications', this.notifications);
     },
-
+    
     // 加载通知设置
     loadNotificationSettings() {
-      const savedSettings = uni.getStorageSync('notifications')
+      const savedSettings = uni.getStorageSync('notifications');
       if (savedSettings) {
-        this.notifications = savedSettings
+        this.notifications = savedSettings;
       }
     },
-
+    
     // 页面跳转
     navigateToAboutUs() {
-      uni.navigateTo({ url: '/pages/about/index' })
+      uni.navigateTo({ url: '/pages/about/index' });
     },
+    
     navigateToPrivacy() {
-      uni.navigateTo({ url: '/pages/privacy/index' })
-    },
-
-    // 拨打客服电话
-    handleContact() {
-      uni.makePhoneCall({
-        phoneNumber: '400-xxx-xxxx' // 替换为实际的客服电话
-      })
+      uni.navigateTo({ url: '/pages/privacy/index' });
     }
+  },
+  
+  // 页面显示时加载数据
+  onShow() {
+    this.getCacheSize();
+    this.loadNotificationSettings();
   }
-}
+};
 </script>
 
 <style lang="scss">

+ 72 - 65
pages/user/index.vue

@@ -37,45 +37,42 @@
 		</view>
 
 		<!-- 农业服务 -->
-		<view class="info-card">
-			<view class="card-title">
-				<text>农业服务</text>
-			</view>
-			<view class="service-grid">
-				<view class="service-item" v-for="(item, index) in serviceList" :key="index"
-					@click="navigateToService(item)">
-					<view class="service-icon">
-						<text>{{ item.iconText }}</text>
-					</view>
-					<text class="service-name">{{ item.name }}</text>
-				</view>
-			</view>
-		</view>
+    <view class="info-card">
+      <view class="card-title">
+        <text>农业服务</text>
+      </view>
+      <view class="service-grid">
+        <view 
+          class="service-item" 
+          v-for="(item, index) in serviceList" 
+          :key="index"
+          @click="navigateToService(item)"
+        >
+          <view class="service-icon">
+            <image v-if="item.iconSvg" class="icon-svg" :src="item.iconSvg"></image>
+            <text v-else>{{ item.iconText }}</text>
+          </view>
+          <text class="service-name">{{ item.name }}</text>
+        </view>
+      </view>
+    </view>
+
 
 		<!-- 常用功能 -->
 		<view class="info-card">
 			<view class="function-list">
 				<view class="function-item" @click="handleContact">
-					<view class="left">
-						<text class="function-icon">客</text>
-						<text>联系客服</text>
-					</view>
-					<text class="arrow">></text>
-				</view>
-				<view class="function-item" @click="navigateToAbout">
-					<view class="left">
-						<text class="function-icon">关</text>
-						<text>关于我们</text>
-					</view>
-					<text class="arrow">></text>
-				</view>
-				<view class="function-item" @click="navigateToSettings">
-					<view class="left">
-						<text class="function-icon">设</text>
-						<text>系统设置</text>
-					</view>
-					<text class="arrow">></text>
-				</view>
+          <view class="left">
+            <text>联系客服</text>
+          </view>
+          <text class="arrow">></text>
+        </view>
+        <view class="function-item" @click="navigateToSettings">
+          <view class="left">
+            <text>系统设置</text>
+          </view>
+          <text class="arrow">></text>
+        </view>
 				<view v-if="isLogin" class="function-item" @click="handleLogout">
 					<view class="left">
 						<text class="function-icon">退</text>
@@ -104,32 +101,38 @@
 					active: 0,
 					idle: 0
 				},
-				serviceList: [{
-						name: '农资商城',
-						iconText: '商',
-						path: '/pages/service/mall'
-					},
-					{
-						name: '农产品销售',
-						iconText: '售',
-						path: '/pages/service/sales'
-					},
-					{
-						name: '在线专家问诊',
-						iconText: '诊',
-						path: '/pages/service/expert'
-					},
-					{
-						name: '绿色认证申请',
-						iconText: '证',
-						path: '/pages/service/certification'
-					},
-					{
-						name: '保险接入',
-						iconText: '保',
-						path: '/pages/service/insurance'
-					}
-				],
+				serviceList: [
+        { 
+          name: '农资商城',
+          iconText: '商',
+          iconSvg: '/static/icons/mall.png',
+          path: '/pages/service/mall'
+        },
+        { 
+          name: '农品交易',
+          iconText: '售',
+          iconSvg: '/static/icons/sales.png',
+          path: '/pages/service/sales'
+        },
+        { 
+          name: '专家咨询',
+          iconText: '诊',
+          iconSvg: '/static/icons/expert.png',
+          path: '/pages/service/expert'
+        },
+        { 
+          name: '绿色认证',
+          iconText: '证',
+          iconSvg: '/static/icons/certification.png',
+          path: '/pages/service/certification'
+        },
+        { 
+          name: '保险接入',
+          iconText: '保',
+          iconSvg: '/static/icons/insurance.png',
+          path: '/pages/service/insurance'
+        }
+      ],
 				userInfo: {
 					nickName: '',
 					id: '',
@@ -189,11 +192,9 @@
 					url: '/pages/plots/list'
 				})
 			},
-			navigateToService(item) {
-				uni.navigateTo({
-					url: item.path
-				})
-			},
+    navigateToService(item) {
+      uni.navigateTo({ url: item.path })
+    },
 			handleContact() {
 				uni.makePhoneCall({
 					phoneNumber: '400-xxx-xxxx' // 替换为实际的客服电话
@@ -372,6 +373,12 @@
 		font-weight: bold;
 	}
 
+	.icon-svg {
+		width: 48rpx;
+		height: 48rpx;
+		display: block;
+	}
+
 	.service-name {
 		font-size: 28rpx;
 		color: #666;

BIN
static/icons/add_task.png


+ 5 - 0
static/icons/arrow_down.svg

@@ -0,0 +1,5 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+  <!-- 默认状态向下箭头 -->
+  <path d="M12 4L12 20" stroke="#999999" stroke-width="2" stroke-linecap="round"/>
+  <path d="M6 14L12 20L18 14" stroke="#999999" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+</svg> 

+ 5 - 0
static/icons/arrow_left.svg

@@ -0,0 +1,5 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+  <!-- 默认状态向左箭头 -->
+  <path d="M4 12L20 12" stroke="#999999" stroke-width="2" stroke-linecap="round"/>
+  <path d="M10 6L4 12L10 18" stroke="#999999" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+</svg> 

+ 5 - 0
static/icons/arrow_right.svg

@@ -0,0 +1,5 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+  <!-- 默认状态向右箭头 -->
+  <path d="M4 12L20 12" stroke="#999999" stroke-width="2" stroke-linecap="round"/>
+  <path d="M14 6L20 12L14 18" stroke="#999999" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+</svg> 

+ 5 - 0
static/icons/arrow_up.svg

@@ -0,0 +1,5 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+  <!-- 默认状态向上箭头 -->
+  <path d="M12 4L12 20" stroke="#999999" stroke-width="2" stroke-linecap="round"/>
+  <path d="M6 10L12 4L18 10" stroke="#999999" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+</svg> 

+ 5 - 0
static/icons/arrow_up_active.svg

@@ -0,0 +1,5 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+  <!-- 激活状态向上箭头 -->
+  <path d="M12 4L12 20" stroke="#4CAF50" stroke-width="3" stroke-linecap="round"/>
+  <path d="M6 10L12 4L18 10" stroke="#4CAF50" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
+</svg> 

+ 4 - 0
static/icons/auto_mode.svg

@@ -0,0 +1,4 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+  <!-- AUTO文字,居中显示 -->
+  <text x="12" y="14" text-anchor="middle" fill="#2196F3" font-size="8" font-weight="700" font-family="Arial, sans-serif">AUTO</text>
+</svg> 

BIN
static/icons/certification.png


+ 7 - 0
static/icons/emergency_stop.svg

@@ -0,0 +1,7 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+  <!-- 警告三角形 -->
+  <path d="M12 3L20 19H4L12 3Z" stroke="#F56C6C" stroke-width="2" stroke-linejoin="round" fill="none"/>
+  <!-- 感叹号 -->
+  <path d="M12 9L12 14" stroke="#F56C6C" stroke-width="2" stroke-linecap="round"/>
+  <circle cx="12" cy="16" r="1" fill="#F56C6C"/>
+</svg> 

+ 4 - 0
static/icons/engine_start.svg

@@ -0,0 +1,4 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+  <!-- 放大的播放三角形,1.2倍大小 -->
+  <path d="M7 5V19L19 12L7 5Z" fill="white" stroke="white" stroke-width="0.5" stroke-linejoin="round"/>
+</svg> 

+ 4 - 0
static/icons/engine_stop.svg

@@ -0,0 +1,4 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+  <!-- 停止方块,白色填充 -->
+  <rect x="6" y="6" width="12" height="12" rx="2" fill="white" stroke="white" stroke-width="0.5"/>
+</svg> 

BIN
static/icons/expert.png


+ 6 - 0
static/icons/home.svg

@@ -0,0 +1,6 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+  <!-- 简单房子轮廓 -->
+  <path d="M4 19V12L12 4L20 12V19H4Z" stroke="#4CAF50" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
+  <!-- 门 -->
+  <path d="M10 19V14H14V19" stroke="#4CAF50" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
+</svg> 

BIN
static/icons/insurance.png


BIN
static/icons/mall.png


BIN
static/icons/professor.png


BIN
static/icons/sales.png


BIN
static/icons/upload_add.png


+ 42 - 0
static/images/products/README.md

@@ -0,0 +1,42 @@
+# 农资商城产品图片素材
+
+## 图片来源
+所有图片素材均来自 Unsplash 免费图片库,遵循 Unsplash License 协议,可用于商业用途。
+
+## 图片列表
+
+### 种子类
+- `corn-seeds-new.jpg` - 高产玉米种子
+- `seeds-packets.jpg` - 优质水稻种子包装
+- `wheat-seeds.jpg` - 小麦种子
+
+### 肥料类
+- `fertilizer.jpg` - 复合肥料NPK
+- `organic-fertilizer-new.jpg` - 有机肥料
+- `soil-test.jpg` - 土壤检测相关
+
+### 植保用品类
+- `plant-protection.jpg` - 植物保护剂
+- `agriculture-tools.jpg` - 农用工具套装
+
+### 农膜类
+- `greenhouse-film.jpg` - 温室农膜
+- `plastic-film.jpg` - 地膜覆盖膜
+
+### 农机配件类
+- `farming-equipment.jpg` - 农业机械配件
+- `machinery-parts.jpg` - 收割机配件
+
+## 更新记录
+- 2024.06.18: 更换更符合农资商城的产品图片
+- 优化了图片内容,更贴近真实农资产品
+- 调整了商品名称和价格,更符合市场实际
+
+## 规格说明
+- 尺寸:400x300px
+- 格式:JPG
+- 优化:适配移动端显示
+
+## 版权声明
+图片来源于 Unsplash (https://unsplash.com)
+符合免费商用授权协议 

BIN
static/images/products/agriculture-tools.jpg


BIN
static/images/products/corn-seeds-new.jpg


BIN
static/images/products/farming-equipment.jpg


BIN
static/images/products/fertilizer.jpg


BIN
static/images/products/greenhouse-film.jpg


BIN
static/images/products/insecticide.jpg


BIN
static/images/products/machinery-parts.jpg


BIN
static/images/products/organic-fertilizer-new.jpg


BIN
static/images/products/pesticide.jpg


BIN
static/images/products/plant-protection.jpg


BIN
static/images/products/plastic-film.jpg


BIN
static/images/products/rice-seeds.jpg


BIN
static/images/products/seeds-packets.jpg


BIN
static/images/products/soil-test.jpg


BIN
static/images/products/wheat-seeds.jpg