【桂工微拍小程式】商品詳情頁設計與功能實現

来源:https://www.cnblogs.com/lishilin-glut/archive/2022/07/21/16501576.html
-Advertisement-
Play Games

1、商品輪播圖 1-1、整體流程 1、swiper組件用來放置swiper-item組件 2、swiper-item組件用來放置圖片 3、image組件顯示輪播圖圖片 4、wx:for列表迴圈,設置每一個圖片 5、雲資料庫請求數據完成動態響應 1-2、根據微信開發官方文檔來設計商品輪播圖 1、從官方 ...


1、商品輪播圖 

1-1、整體流程

1、swiper組件用來放置swiper-item組件

2、swiper-item組件用來放置圖片

3、image組件顯示輪播圖圖片

4、wx:for列表迴圈,設置每一個圖片

5、雲資料庫請求數據完成動態響應

1-2、根據微信開發官方文檔來設計商品輪播圖

1、從官方文檔的組件了找到試圖容器裡面的swiper組件

 

1-3、頁面設計代碼

1、goods.wxml

<!--商品詳情頁-->
<view class="container">
  <view class="main">
    <!--頂部輪播圖-->
    <swiper autoplay="true" indicator-dots="true">
      <block wx:for="{{goodsInfo.images}}" wx:key="index">
        <swiper-item>
          <image src="{{item}}"></image>
        </swiper-item>
      </block>      
    </swiper>
  </view>

</view>

2、goods.wxss

.container{
  bottom: 0;
  top:0;
  left: 0;
  right: 0;
  position: fixed;
  width: 100%;  
  height: 100%;  
  background-color: rgb(226, 233, 236);  
}
.main{
  width: 100%;
  height: 93%;
  top: 0;
  position: absolute;
  flex: 1;
  border: aqua solid 1px;
}
swiper {
  height: 420rpx;
}
swiper-item{
  width: 100%;
  height: 100%;
}
swiper-item image{
  width: 100%;
  height: 100%;
}

 

 1-4、從雲資料庫獲取商品數據包括輪播圖圖片

1、goods.js

  onLoad(options) {
    console.log('商品id:',options.goodsid)
    let goodsId = options.goodsid
    wx.cloud.database().collection('goods').doc(goodsId).get({
      success: (res) => {
        this.setData({
          goodsInfo: res.data
        })
        console.log('商品詳細:',this.data.goodsInfo)
      }
    })
  }

1-5、商品輪播圖效果

 改進:因為圖片有不同的寬高比,還有豎屏圖片,所以需要對圖片的寬高做一個適應,這裡我選擇固定高度,讓寬度自適應,方法如下

在官方文檔中可以看到,image標簽有一個mode屬性

 

 mode裡面的heightFix屬性剛好滿足了我們的需求

 2、商品價格、標題、競拍倒計時、發佈者頭像和昵稱等

2-1、簡陋效果

 

 價格標題和發佈者都是獲取資料庫的信息,每個商品綁定了一個發佈者id,通過這個id去資料庫找到對應的用戶頭像和昵稱

js代碼如下:

 onLoad(options) {
    let goodsId = options.goodsid
    //查詢商品,商品id 時上一個頁面傳遞過來的
    wx.cloud.database().collection('goods').doc(goodsId).get({
      success: (res) => {
        this.setData({
          goodsInfo: res.data
        })
        //查詢商品發佈者
        wx.cloud.database().collection('userInfo').doc(res.data.publisher_id).get({
          success: (res) => {
            this.setData({
              publisher: res.data
            })
            console.log(res)
          }
        })
      }
    })    
    
  },

wxml代碼

<!--商品詳情頁-->
<view class="container">
  <scroll-view class="main">
    <!--頂部輪播圖-->
    <swiper autoplay="true" indicator-dots="true">
      <block wx:for="{{goodsInfo.images}}" wx:key="index">
        <swiper-item>
          <image src="{{item}}" mode="heightFix"></image>
        </swiper-item>
      </block>      
    </swiper>
    <!--商品標題價格欄-->
    <view class="goodsPrice">
      <view style="margin-left: 30rpx;">
        <image src="/image/goodsPrice.png" style="width: 30rpx;height: 30rpx;"></image>
        <text style="color: rgb(179, 6, 41);font-size: 50rpx;">{{goodsInfo.current_price}} </text>
        <image src="{{publisher.avatarUrl}}" style="width: 50rpx;height: 50rpx;border-radius: 50%;margin-left: 40%;"></image>
        <text style="font-size: 40rpx;overflow: hidden;">   {{publisher.nickName}}</text>
      </view>

      <view >
        <text style="font-size: 30rpx;margin-left: 30rpx;">起拍價 {{goodsInfo.start_price}}</text>
      </view>

      <view>
        <text style="margin-left: 30rpx;"> {{goodsInfo.name}} </text>   
      </view>
    </view>
    <!--商品發佈者和競拍記錄-->
    <scroll-view class="goodsPublisher">
      <view style="text-align: center;">
        <text style="font-size: 40rpx;color: chocolate;">出價記錄</text>
      </view>
    </scroll-view>
    <!--商品詳情描述-->
    <view class="describe">
      <rich-text>{{goodsInfo.describe}}</rich-text>
    </view>
  </scroll-view>
</view>

 2-2、倒計時

1、效果圖

 

 2、js代碼

var goods_id Page({   data: {     goodsInfo: null,     publisher: null,     auctionUser: null,     clock:'',     myTime: null   },
  onLoad(options) {     let goodsId = options.goodsid     //將id存起來給onshow用     goods_id = goodsId     //獲取商品信息     this.getGoodsInfo(goodsId)     //倒計時     this.countdown(goodsId)   },   onShow(){     this.getGoodsInfo(goods_id)   },   onUnload(){     //清楚計時器     clearInterval(this.myTime)   },   onHide(){     //清楚計時器     clearInterval(this.myTime)   },
  //查詢所有商品   getGoodsInfo(goodsId){       wx.cloud.database().collection('goods').doc(goodsId).get({         success: (res) => {           this.setData({             goodsInfo: res.data           })           //根據發佈者id去用戶表中查詢商品發佈者信息           wx.cloud.database().collection('userInfo').doc(res.data.publisher_id).get({             success: (res) => {               this.setData({                 publisher: res.data               })             }           })         }       })   },   //獲取競拍結束時間,並計算倒計時   countdown(goodsId){     wx.cloud.database().collection('goods').doc(goodsId).get({       success: res=>{         //取出競拍結束時間,精確到秒         let auctionEndtime = res.data.end_time         console.log(res)         //獲取當前系統時間,只精確到秒         var nowTime = new Date().getTime() / 1000         //剩餘時間總的秒數         var totalSecond = Math.floor(auctionEndtime - nowTime)         console.log('剩餘秒數',totalSecond)         //計算倒計時         this.doCountdown(totalSecond)       }     })   },
  //計算商品倒計時   doCountdown(totalSecond){     let _this = this     //每隔一秒執行一次代碼     this.myTime =  setInterval(function () {         //如果競拍已經結束         if(totalSecond < 0){           _this.setData({             clock: ''           })           clearInterval(_this.myTime)           return          }else{           //執行計算           var time = _this.formatTime(totalSecond)           _this.setData({             clock: time           })         }         totalSecond --;     },1000)   },
  //倒計時時間格式化   formatTime(totalSecond){     //剩餘天數     var day = Math.floor(totalSecond / 3600 / 24)     //n天後剩餘小時數     var hour = Math.floor(totalSecond /3600 % 24)     //n天n小時後剩餘分鐘數     var min = Math.floor(totalSecond / 60 % 60)     //n天n小時n分鐘後剩餘秒數     var sec = Math.floor(totalSecond % 60)     return day + "天" + hour + "小時" + min + "分" + sec + "秒"   } })

 

4、完整功能和頁面(最終版)

 

 1、goods.wxml代碼

<!--商品詳情頁-->
<view class="container">
  <scroll-view class="main" scroll-y="true">
    <!--頂部輪播圖-->
    <swiper autoplay="true" indicator-dots="true">
      <block wx:for="{{goodsInfo.images}}" wx:key="index">
        <swiper-item>
          <image src="{{item}}" mode="heightFix"></image>
        </swiper-item>
      </block>
    </swiper>
    <!--商品標題價格欄-->
    <view class="goodsPrice">
      <view style="margin-left: 30rpx;display: flex;align-items: center;">
        <image src="/image/goodsPrice.png" style="width: 30rpx;height: 30rpx;"></image>
        <text style="color: rgb(179, 6, 41);font-size: 50rpx;">{{goodsInfo.current_price}} </text>
        <!--倒計時-->
        <text wx:if="{{clock == '已經截止'}}" style="margin-left: 60%;color: crimson;">{{clock}}</text>
        <text wx:else="" style="margin-left: 12%;font-size: 45rpx;color: crimson;">{{clock}}</text>
      </view>

      <view style="display: flex;overflow: hidden;white-space: nowrap;text-overflow: ellipsis; align-items: center;">
        <text style="font-size: 30rpx;margin-left: 30rpx;">起拍價 {{goodsInfo.start_price}}</text>
        <image src="{{publisher.avatarUrl}}" style="width: 50rpx;height: 50rpx;border-radius: 50%;margin-left: 35%;"></image>
        <text style="font-size: 30rpx;margin-left: 10epx;" decode="true">&nbsp; {{publisher.nickName}} </text>
      </view>

      <view>
        <text style="margin-left: 30rpx;"> {{goodsInfo.name}} </text>
      </view>
    </view>
    <!--商品發佈者和競拍記錄-->
    <scroll-view class="goodsAuctionRecord">
      <view style="text-align: center;">
        <text style="font-size: 40rpx;color: chocolate;">出價記錄</text>
      </view>
      <!--出價的用戶-->
      <block wx:for="{{auctionRecord}}" wx:key="index">
        <view>
          <text style="font-size: 24rpx;">{{item.auctionTimeFormat}}</text>
          <image src="{{item.userInfo.avatarUrl}}" style="width: 40rpx;height: 40rpx;border-radius: 50%;margin-left: 5%;"></image>
          <text decode="true"> {{item.userInfo.nickName}}&nbsp;出價了</text>
          <text style="color: crimson; font-size: 40rpx;">{{item.putPrice}} 元</text>
        </view>
      </block>

    </scroll-view>
    <!--商品詳情描述-->
    <view class="describe">
      <rich-text>{{goodsInfo.describe}}</rich-text>
    </view>
  </scroll-view>
  <!--底部-->
  <view class="bottomContainer">
    <view>
      <image src="/image/jianhao.png" class="changePriceIcon" bindtap="downPrice"></image>
      <text class="addPrice">{{changePrice}}元</text>
      <image src="/image/add.png" class="changePriceIcon" style="width: 67rpx;height: 67rpx;margin-left: 36%;" bindtap="addPrice"></image>
      <text style="height: 100rpx;float: right;background-color: tomato;padding: 20rpx 40rpx;color: white;" bindtap="putPrice">出個價</text>
    </view>
  </view>
</view>

2、goods.wxss代碼

.container {
  bottom: 0;
  top: 0;
  left: 0;
  right: 0;
  position: fixed;
  width: 100%;
  height: 100%;
  background-color: rgba(232, 234, 235, 0.89);
}

.main {
  width: 100%;
  height: 93%;
  top: 0;
  position: absolute;
  flex: 1;
  background-color: rgb(221, 221, 204);
}

swiper {
  height: 430rpx;
  background-color: white;
}

swiper-item {
  text-align: center;
  width: 100%;
  height: 100%;
}

swiper-item image {
  border-radius: 15rpx;
  height: 100%;
}

.goodsPrice {
  margin-top: 15rpx;
  width: 96%;
  margin-left: 2%;
  border-radius: 25rpx;
  border: aliceblue solid 1px;
  background-color: aliceblue;
  box-shadow: 4px 4px 15px rgb(180, 223, 202);
}

.goodsAuctionRecord {
  margin-top: 15rpx;
  width: 96%;
  height: auto;
  margin-left: 2%;
  border-radius: 25rpx;
  border: rgb(235, 238, 241) solid 1px;
  background-color: aliceblue;
  box-shadow: 4px 4px 15px rgb(180, 223, 202);
}

.describe {
  margin-top: 15rpx;
  width: 96%;
  margin-left: 2%;
  border-radius: 25rpx;
  border: rgb(235, 238, 241) solid 1px;
  background-color: aliceblue;
  box-shadow: 4px 4px 15px rgb(180, 223, 202);
}

.bottomContainer {
  position: absolute;
  top: 93%;
  width: 100%;
  height: 5%;
  white-space: nowrap;
  word-break:keep-all;
}

.addPrice {
  position: fixed;
  background-color: rgb(8, 8, 8);
  color: white;
  border-radius: 30px;
  margin-left: 4%;
  margin-top: 17rpx;
  padding: 10rpx 10% 10rpx 10%;
}
.changePriceIcon{
  width: 60rpx;
  height: 60rpx;
  margin-left: 4%;
  padding-top: 12rpx;
}

3、goods.js代碼

var goods_id
var myTime //計數器
Page({

  data: {
    goodsInfo: null,
    publisher: null,
    auctionRecord: null,
    clock: '',
    changePrice: null //出價
  },

  onLoad(options) {
    let goodsId = options.goodsid
    //將id存起來給onshow用
    goods_id = goodsId
    //獲取商品信息
    this.getGoodsInfo(goodsId)
    //倒計時
    this.countdown(goodsId)
  },
  onShow() {
    this.getGoodsInfo(goods_id)
    this.getAuctionRecord()
  },
  onUnload() {
    //清楚計時器
    clearInterval(myTime)
  },
  onHide() {
    //清楚計時器
    clearInterval(myTime)
  },

  //查詢所有商品
  getGoodsInfo(goodsId) {
    wx.cloud.database().collection('goods').doc(goodsId).get({
      success: (res) => {
        this.setData({
          goodsInfo: res.data,
          changePrice: res.data.current_price + 1
        })
        //根據發佈者id去用戶表中查詢商品發佈者信息
        wx.cloud.database().collection('userInfo').doc(res.data.publisher_id).get({
          success: (res) => {
            this.setData({
              publisher: res.data
            })
          }
        })
      }
    })
  },
  //底部加減價格
  addPrice() {
    var price = this.data.changePrice
    price++
    this.setData({
      changePrice: price
    })
  },
  downPrice() {
    var price = this.data.changePrice
    if (price > this.data.goodsInfo.current_price + 1) {
      price--
      this.setData({
        changePrice: price
      })
    } else {
      wx.showToast({
        title: '出價應當高於當前價!',
        icon: 'none'
      })
    }
  },

  //競拍者出價
  putPrice() {
    //獲取出價
    let price = this.data.changePrice
    //獲取出價用戶
    let userInfo = wx.getStorageSync('userInfo')
    //獲取出價時間
    let nowTime = new Date().getTime()
    //轉化為時間格式
    var util = require("../../util/time_transform.js")
    let timeFormat = util.js_date_time(nowTime)
    //彈窗確認
    wx.showModal({
      title: '確認出價',
      content: '價高者得,競拍結束價高者可在競拍記錄中查看賣家聯繫信息,感謝您的參與!',
      success: (res) => {
        if (res.confirm) {
          wx.showLoading({
            title: '正在出價...',
          })
          //保存競拍記錄到資料庫
          wx.cloud.database().collection('goodsAuctionRecord').add({
              data: {
                goodsID: goods_id,
                userInfo: userInfo,
                putPrice: price,
                auctionTime: nowTime,
                auctionTimeFormat: timeFormat
              },
              success: res => {}
            }),
            //更新當前價
            wx.cloud.database().collection('goods').doc(goods_id).update({
              data: {
                current_price: price
              }
            })
          let _this = this
          setTimeout(function () {
            wx.hideLoading({
              success: (res) => {
                //刷新頁面數據
                _this.onShow()
              }
            })
          }, 1000)
        } else {
          console.log('取消')
        }
      }
    })
  },

  //獲取商品用戶競拍記錄
  getAuctionRecord() {
    wx.cloud.database().collection('goodsAuctionRecord').where({
      goodsID: goods_id
    }).get({
      success: (res) => {
        this.setData({
          auctionRecord: res.data
        })
      }
    })
  },

  //獲取競拍結束時間,並計算倒計時
  countdown(goodsId) {
    wx.cloud.database().collection('goods').doc(goodsId).get({
      success: res => {
        //取出競拍結束時間,精確到秒
        let auctionEndtime = res.data.end_time
        console.log(res)
        //獲取當前系統時間,只精確到秒
        var nowTime = new Date().getTime() / 1000
        //剩餘時間總的秒數
        var totalSecond = Math.floor(auctionEndtime - nowTime)
        console.log('剩餘秒數', totalSecond)
        //計算倒計時
        this.doCountdown(totalSecond)
      }
    })
  },

  //計算商品倒計時
  doCountdown(totalSecond) {
    let _this = this
    //每隔一秒執行一次代碼
    myTime = setInterval(function () {
      //如果競拍已經結束
      if (totalSecond < 0) {
        _this.setData({
          clock: '已經截止'
        })
        clearInterval(myTime)
        return
      } else {
        //執行計算
        var time = _this.formatTime(totalSecond)
        _this.setData({
          clock: '剩餘' + time
        })
      }
      totalSecond--;
    }, 1000)
  },

  //倒計時時間格式化
  formatTime(totalSecond) {
    //剩餘天數
    var day = Math.floor(totalSecond / 3600 / 24)
    //n天後剩餘小時數
    var hour = Math.floor(totalSecond / 3600 % 24)
    //n天n小時後剩餘分鐘數
    var min = Math.floor(totalSecond / 60 % 60)
    //n天n小時n分鐘後剩餘秒數
    var sec = Math.floor(totalSecond % 60)
    return day + "天" + hour + "小時" + min + "分" + sec + "秒"
  }
})

4、時間轉化js代碼

 

 在util 下麵新建一個time_transform.js文件

//時間戳轉換成日期時間,傳入時間精確到毫秒
function js_date_time(unixtime) {
  var date = new Date(unixtime) 
  var y = date.getFullYear();
  var m = date.getMonth() + 1;
  m = m < 10 ? ('0' + m) : m;
  var d = date.getDate();
  d = d < 10 ? ('0' + d) : d;
  var h = date.getHours();
  h = h < 10 ? ('0' + h) : h;
  var minute = date.getMinutes();
  var second = date.getSeconds();
  minute = minute < 10 ? ('0' + minute) : minute;
  second = second < 10 ? ('0' + second) : second;
  return y + '-' + m + '-' + d + ' ' + h + ':' + minute + ':' + second;//年月日時分秒
  // return y + '-' + m + '-' + d + ' ' + h + ':' + minute;
  // return y + '-' + m + '-' + d;
}
module.exports = {
  js_date_time: js_date_time
}

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 06 | 全局鎖和表鎖 :給表加個欄位怎麼有這麼多阻礙? Connection連接與Session會話 通俗來講,會話(Session)是通信雙⽅從開始通信到通信結束期間的⼀個上下文(Context)。這個上下文是⼀段位於伺服器端的記憶體:記錄了本次連接的客戶端機器、通過哪個應用程式、哪個用戶登錄等信 ...
  • 09 | 普通索引和唯一索引,應該怎麼選擇? 每個人都有一個唯一的身份證號,而且業務代碼已經保證了不會寫入兩個重覆的身份證號。如果市民系統需要按照身份證號查姓名,就會執行類似這樣的 SQL 語句: select name from CUser where id_card = 'xxxxxxxyyyy ...
  • 分享嘉賓:張鴻志博士 美團 演算法專家 編輯整理:廖媛媛 美的集團 出品平臺:DataFunTalk **導讀:**美團作為中國最大的線上本地生活服務平臺,連接著數億用戶和數千萬商戶,其背後蘊含著豐富的與日常生活相關的知識。美團知識圖譜團隊從2018年開始著力於圖譜構建和利用知識圖譜賦能業務,改善用戶 ...
  • 什麼是 MyBatis? MyBatis 是一款優秀的持久層框架,它支持自定義 SQL、存儲過程以及高級映射。 MyBatis 免除了幾乎所有的 JDBC 代碼以及設置參數和獲取結果集的工作。 MyBatis 可以通過簡單的 XML 或註解來配置和映射原始類型、介面和 Java POJO(Plain ...
  • 1.自然連接 NATURAL JOIN SQL99中新增的自然連接相當於SQL92中的等值連接。它可以自動的查詢兩個表中所有的相同欄位,然後進行等值連接。 在SQL92中: SELECT 表1.欄位1,表2.欄位2 FROM 表1 JOIN 表2 ON 表1.欄位3 = 表2.同名欄位 AND 表2 ...
  • 預備知識梳理 本文中設定 block size 與 page size 大小相等。 什麼是 Block 文章的開始先解釋一下,磁碟的數據讀寫是以扇區 (sector) 為單位的,而操作系統從磁碟上讀寫數據是以塊 (block) 為單位的,一個 block 由若幹個連續的 sector 組成,使用 b ...
  • Redis是一種記憶體資料庫,數據都存儲在記憶體中,因此可以快速地直接基於記憶體中的數據結構進行高性能的操作,但是所有數據都在記憶體中,一旦伺服器宕機,記憶體中的數據就會全部丟失,數據將無法恢復,因此Redis也有自己的持久化機制,但是要註意這個持久化和普通資料庫的持久化不同,持久化文件必須全部讀取到記憶體才可 ...
  • 完整功能和頁面 1、goods.wxml代碼 <!--商品詳情頁--> <view class="container"> <scroll-view class="main" scroll-y="true"> <!--頂部輪播圖--> <swiper autoplay="true" indicator ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...