首页/默认分类/正文
微信小程序云开发电商仿橙心优选拼团功能的实现细节

 2025年08月26日  阅读 1

摘要:1.拼团商品属性设置拼团商品在普通商品属性的基础上,需要增加拼团标志属性。我们可以在云开发数据库中创建一个专门存储拼团商品的集合,其中包含以下关键字段:现在微信小程序开发十分火热,实现微信有庞大的使用人群,而且微信小程序不需要客户端实现下载,只需...

1. 拼团商品属性设置

拼团商品在普通商品属性的基础上,需要增加拼团标志属性。我们可以在云开发数据库中创建一个专门存储拼团商品的集合,其中包含以下关键字段:

    现在微信小程序开发十分火热,实现微信有庞大的使用人群,而且微信小程序不需要客户端实现下载,只需要微信搜索就可以使用,在各种各样的小程序中电商小程序显得尤为突出,而且项目实现起来十分困难。今天小胡同学我自己设计了一个电商拼团的小功能(基于云开发),大家可以学习学习。我这个是仿橙心优选的电商项目

is_group: true/false(标识是否为拼团商品)

group_price: 拼团价

original_price: 原价

group_number: 成团人数要求

group_end_time: 拼团截止时间

joined_users: 已参团用户数组

2. 拼团限时时间设置

拼团活动需要设置倒计时功能,可以通过前端定时器实现。核心代码如下:

// 获取拼团结束时间

const endTime = new Date('2023-12-31 23:59:59').getTime()

setInterval(() => {

const now = new Date().getTime()

const distance = endTime - now

const hours = Math.floor((distance % (1000 60 60 24)) / (1000 60 60))

const seconds = Math.floor((distance % (1000 60)) / 1000)

// 更新页面显示

}, 1000)

3. 拼团人数设置

在管理后台可以设置成团人数,通常建议设置为2-5人。关键实现代码:

wx.cloud.callFunction({

name: 'setGroupNumber',

data: {

productId: 'xxx',

groupNumber: 3

}

})

4. 拼团流程实现

拼团流程主要通过以下步骤实现:

1) 用户点击"我要拼团"按钮

2) 前端调用云函数检查库存和参团情况

/** 
 * 需要一个目标日期,初始化时,先得出到当前时间还有剩余多少秒
 * 1.将秒数换成格式化输出为XX天XX小时XX分钟XX秒 XX
 * 2.提供一个时钟,每10ms运行一次,渲染时钟,再总ms数自减10
 * 3.剩余的秒次为零时,return,给出tips提示说,已经截止
 */
 
// 定义一个总毫秒数,以一天为例var total_micro_second = 10 * 1000;//这是10秒倒计时
 var total_micro_second = 3600 * 1000*24;//这是一天倒计时
 
/* 毫秒级秒杀倒计时 */
function countdown(that) {
   
   // 渲染倒计时时钟
   that.setData({
   
     clock:dateformat(total_micro_second)//格式化时间
   });
 
   if (total_micro_second <= 0) {
   
     that.setData({
   
       clock:"拼团结束"
     });
     // timeout则跳出递归
     return ;
   }  
   //settimeout实现倒计时效果
   setTimeout(function(){
   
    // 放在最后--
    total_micro_second -= 10;
    countdown(that);
  }
  ,10)//注意毫秒的步长受限于系统的时间频率,于是我们精确到0.01s即10ms
}
 
// 时间格式化输出,如1天天23时时12分分12秒秒12 。每10ms都会调用一次
function dateformat(micro_second) {
   
   // 总秒数
   var second = Math.floor(micro_second / 1000);
   // 天数
   var day = Math.floor(second / 3600/24);
   // 总小时
   var hr = Math.floor(second / 3600);
   // 小时位
   var hr2 = hr%24;
   // 分钟位
   var min = Math.floor((second - hr * 3600) / 60);
   // 秒位
  var sec = (second - hr * 3600 - min * 60);// equal to => var sec = second % 60;
  // 毫秒位,保留2位
  var micro_sec = Math.floor((micro_second % 1000) / 10);
  return /*day+"天"+*/hr2 + "时" + min + "分" + sec + "秒" ;//+ micro_sec;
}
Page({
   
  data: {
   
  
    new_product: [],
    clock: '',
    openid: '',
    
  },
  
  onLoad: function(options) {
   
    countdown(this);
  },

3) 云函数更新已参团人数

4) 返回结果给前端展示

   <view class="jishi">
              <text >限时: {
   {
   clock}}</text>            
            </view>

核心云函数代码:

exports.main = async (event, context) => {

const db = cloud.database()

.newest-box .newest-list .jishi{
   
  background: red;
  border-radius: 10px;
  width: 150px;
  margin-left: 10px;
}

const _ = db.command

return await db.collection('group_products').doc(event.productId)

.update({

data: {

joined_users: _.push(event.userInfo),

current_number: _.inc(1)

}

})

const util = require('../util.js');
const db = wx.cloud.database();
Page({
   
  /**
   * 页面的初始数据
   */
  data: {
   
    name:'',
    price:'',
    ago_price:'',
    classify:'',
    detail:'',
    stock:'',
    isRecommend:'',
    fileID:'',
    recommendObject:[{
   name:'是',checked:false},
                     {
   name:'否',checked:false}],
    classifyObject:[{
   name:'蔬菜',checked:false},
                    {
   name:'肉禽蛋品',checked:false},
                    {
   name:'海鲜水产',checked:false},
                    {
   name:'粮油调味',checked:false},
                    {
   name:'熟食卤味',checked:false},
                    {
   name:'冰品面点',checked:false},
                    {
   name:'牛奶面包',checked:false},
                    {
   name:'酒水冷饮',checked:false},
                    {
   name:'休闲零食',checked:false},
                ],
    now:'',
    array:[]
  },
  getName(res){
   
    this.setData({
   
      name:res.detail.value
    })
  },
  getClassify(res){
   
    this.setData({
   
      classify:res.detail.value
    })
  },
  getPrice(res){
   
    this.setData({
   
      price:res.detail.value
    })
  },
  getago_price(res){
   
    this.setData({
   
      ago_price:res.detail.value
    })
  },
  getkucun(res){
   
    this.setData({
   
      kucun:res.detail.value
    })
  },
  getDetail(res){
   
    this.setData({
   
      detail:res.detail.value
    })
  },
  getStock(res){
   
    this.setData({
   
      stock:res.detail.value
    })
  },
  isRecommend(res){
   
    this.setData({
   
      isRecommend:res.detail.value
    })
  },
  getPicture(res){
   

微信小程序云开发拼团功能_仿橙心优选实现拼团_小程序云开发团购功能

var that = this; var num = Math.floor(Math.random()*10000); var time = Date.parse(new Date()); wx.chooseImage({ count: 1, success(res){ console.log(res); wx.showLoading({ title: '上传中', }) wx.cloud.uploadFile({ cloudPath:'shop/' + time + '-' + num, filePath:res.tempFilePaths[0], success(res){ console.log("上传成功",res); that.setData({ fileID:res.fileID }) wx.hideLoading({ success: (res) => { }, }) }, fail(res){ console.log("上传失败",res); } }) } }) }, submit(res){ var that = this; console.log(that.data.name,that.data.classify,that.data.price,that.data.detail,that.data.isRecommend,that.data.fileID); if(that.data.name == '' || that.data.classify == '' || that.data.price == '' || that.data.ago_price == ''|| that.data.kucun == '' || that.data.detail == '' ||that.data.isRecommend == '' || that.data.fileID == ''){ wx.showToast({ title: '请完整填写信息', }) }else{ if(that.data.now == '修改'){ wx.cloud.callFunction({ name:'updatepintuan', data:{ id:that.data.array._id, name:that.data.name, fenlei:that.data.classify, price:that.data.price, ago_price:that.data.ago_price, kucun:parseInt(that.data.kucun), detail:that.data.detail, isRecommend:that.data.isRecommend, fileID:that.data.fileID }, success(res){ console.log("信息修改成功"); wx.redirectTo({ url: '../admin/admin', success(res){ wx.showToast({ title: '修改成功', duration:3000 }) } }) }, fail(res){ console.log("信息修改失败",res); } }) }else{ db.collection('pintuan').add({ data:{ detail:that.data.detail, fenlei:that.data.classify, img_src:that.data.fileID, name:that.data.name, price:that.data.price, ago_price:that.data.ago_price, kucun:parseInt(that.data.kucun), pinglun:[], isRecommend:that.data.isRecommend }, success(res){ console.log("上传成功"); wx.showToast({ title: '上传成功', success(res){ wx.redirectTo({ url: '../admin/admin', }) } }) } }) } } }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { var that = this; var classifyObject = that.data.classifyObject; var recommendObject = that.data.recommendObject; console.log(options.data); if(options.data == undefined){ }else{ var array = JSON.parse(options.data); console.log(array); for(var i = 0; i < classifyObject.length; i++){ if(classifyObject[i].name == array.fenlei){ classifyObject[i].checked = true; } } for(var j = 0; j < recommendObject.length; j++){ if(recommendObject[j].name == array.isRecommend){ recommendObject[j].checked = true; } } that.setData({ classifyObject:classifyObject, recommendObject:recommendObject, classify:array.fenlei, isRecommend:array.isRecommend, now:'修改', name:array.name, price:array.price, detail:array.detail, ago_price:that.data.ago_price, kucun:that.data.kucun, fileID:array.img_src, array:array }) } }, })

}

5. 防止重复拼团

<view class="content">
  <view class="body">
  <text>拼团商品名称:text>
  <input bindinput="getName" value="{
    {name}}"/>
view>
<view class="body">
  <text>商品分类:text>
  <radio-group bindchange="getClassify">
    <radio wx:for="{
    {classifyObject}}" value="{
    {item.name}}" checked="{
    {item.checked}}">{
  {item.name}}radio>
  radio-group>
view>
<view class="body">
  <text>原价格:text>
  <input bindinput="getago_price" value="{
    {ago_price}}" type="number" />
view>
<view class="body">
  <text>拼团价格:text>
  <input bindinput="getPrice" value="{
    {price}}" type="number" />
view>
<view class="body">
  <text>拼团人数:text>
  <input bindinput="getkucun" value="{
    {kucun}}" type="number" />
view>
<view class="body">
  <text>描述:text>
  <input bindinput="getDetail" value="{
    {detail}}"/>
view>

<view class="body">
  <text>是否推荐到主页:text>
  <radio-group bindchange="isRecommend">
    <radio wx:for="{
    {recommendObject}}" value="{
    {item.name}}" checked="{
    {item.checked}}">{
  {item.name}}radio>
  radio-group>
view>
<view class="image">
  <text>图片:text>
  <button type="primary" style="width:50%" bindtap="getPicture" wx:if="{
    {fileID == ''}}">添加图片button>
  <image src="{
    {fileID}}" wx:if="{
    {fileID !== ''}}" mode="widthFix" style="width:200rpx;height:200rpx;margin:0 auto">image>
view>
<button style="margin-top:30rpx;background-color:#00f;color:#fff;width:70%;margin-bottom:30rpx" bindtap="submit">提交button>
view>

通过创建辅助数据库记录用户拼团状态:

const checkRepeat = async (userId, productId) => {

page {
   
  background-color: #f3f3f3;
}
.content {
   
  background-color: #fff;
  width: 90%;
  margin: 0 auto;
  margin-top: 20rpx;
}
.body {
   
  display: flex;
  flex-direction: row;
  margin-top: 20rpx;
  align-items: center;
}
.body > text {
   
  width: 30%;
  padding: 10rpx 20rpx;
  margin-left: 42rpx;
}
.body > input,radio-group {
   
  width: 70%;
  margin-right: 30rpx;
}
.image {
   
  display: flex;
  margin-top: 20rpx;
  flex-direction: column;
}
.image > text {
   
  margin-left: 62rpx;
  margin-bottom: 30rpx;
}

const res = await db.collection('group_records')

.where({

userId: userId,

productId: productId

})

.get()

return res.data.length > 0

}

6. 拼团成功后购买流程

拼团成功后,用户可以在"我的订单"中看到拼团商品,点击购买时会检查:

1) 是否达到成团人数

2) 是否在有效期内

 pintuan: function(e) {
   
    var that = this;
    const db = wx.cloud.database();
    const _=db.command;
     var clock = this.data.clock;
    var _id = e.currentTarget.dataset.id;//获取当前商品的_id
    var _openid=app.globalData.openid;
    console.log(_openid);
    console.log(_id);
    if (clock==0){
   
      wx.showModal({
   
        title: '',
        content: '时间已经截止',
        showCancel:false,
      })
    }
    wx.showModal({
   
      title: '',
      content: '是否确认拼团?',
      mask: true,
      success(res) {
   
        if (res.confirm) {
   
          console.log(_id);
          db.collection("pintuan").doc(_id).update({
   
            data: {
   
              kucun:_.inc(-1), //拼团名额减一
              people:_.inc(0-1),//拼团人数加一
            },
          
            success(res) {
   
              wx.showToast({
   
                title: '拼团成功!',
                mask:true,
              })
            }
           
          })
        } 
      }
    })
  },

3) 用户是否已参团

购买流程与普通订单相似,但价格使用拼团价。

7. 数据库设计补充

建议创建以下几个集合:

group_products: 拼团商品主表

  <view class="pintuan" wx:if="{
    {item.kucun>0}}">  //当kucun,拼团名额已经小于等于0时,不在显示我要拼团的前端按钮,拼团结束了
             <text bindtap="pintuan" data-id="{
    {item._id}}" >我要拼团text>
            view>

group_records: 拼团记录表

每个集合都需要建立适当的索引以提高查询效率。

8. 前端展示优化


.newest-box {
   
  padding: 0 35rpx;
  margin-top: 20rpx;
  column-count: 2;
  height: 100%;
}
.newest-list {
   
  display: inline-block;
  width: 345rpx;
  height: 100%;
  margin: 0 0 20rpx -5rpx;
  border-top-left-radius: 15rpx;
  border-top-right-radius: 15rpx;
  text-align: center; /*图片和文字居中 */
  background: rgba(245, 127, 59, 0.829);
}
.newest-box .newest-list:nth-child(2n) {
   
  margin-right: 0;
}
.newest-box .newest-list image {
   
  width: 300rpx;
  height: 200rpx;
  border-top-left-radius: 15rpx;
  border-top-right-radius: 15rpx;
  margin: 0;
}
.newest-text-child {
   
  opacity: 0.5;
  display: flex;
  margin-top: 8rpx;
  margin-left: 20rpx;
  font-size: 20rpx;
  color: rgb(10, 10, 10);
}
.ago_price {
   
  text-decoration: line-through;
  margin-top: 0px;
  opacity: 0.7;
  height: 30rpx;
  font-size: 28rpx;
}
.newest-text {
   
  margin-top: 0px;
  display: flex;
  align-items: center;
}
.cruuent_price {
   
  width: 150rpx;
  font-size: 30rpx;
}
.newest-box .newest-list .newest-text {
   
  display: flex;
  font-size: 30rpx;
  color: #e6343a;
  padding-top: 30rpx;
}
.newest-text1 {
   
  overflow: hidden;
  font-size: 32rpx;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pintuan{
   
  color: rgb(240, 240, 240);
  background: rgb(233, 196, 30);
  width: 100px;
  border-radius: 15px;
  margin-left: 20%;
}
.newest-box .newest-list .jishi{
   
  background: red;
  border-radius: 10px;
  width: 150px;
  margin-left: 10px;
}
.buy{
   
  color: rgb(240, 240, 240);
  background: rgb(250, 3, 3);
  width: 100px;
  border-radius: 15px;
  margin-left: 20%;
  margin-top: 2px;
}
.major{
    white-space: nowrap; padding:10px ;background-color:#ebf0f34d;  margin-top: 10rpx; width: 100%;border-radius: 16rpx;}
.major .box{
    text-align: center; width:180rpx; align-self: center; display: inline-block; border-radius: 16rpx;}
.major .pic{
   width:100rpx; height: 100rpx;}
.major .pic1{
   width:120rpx; height: 110rpx;}
.major .txt{
    font-size:26rpx; margin-top:2rpx;} 

建议在前端展示:

当前参团人数

剩余时间

参团用户头像列表

拼团进度条

版权声明:本文为 “博览广文网” 原创文章,转载请附上原文出处链接及本声明;

原文链接:http://wen.bjhwtx.com/post/35686.html

标签:

博览广文网

博览广文网为所有文学爱好者、新闻爱好者、关注生活多方面内容的观众朋友提供多方位的内容呈现、提升阅读空间、填充碎片时间,开阔读者的视野、增长见识、了解民生、一个让您不出户尽知天下事的网站平台!
热门标签
关于我们
广文舒阅网—让天下读者有家可归!这里汇聚了各类优质文化信息,无论是全球热点、历史故事,还是实用百科、趣味探索,您都能轻松获取。我们希望用阅读点亮您的世界,让每一次浏览都充满收获和乐趣。
导航栏A标题
广文舒阅网
扫码关注
联系方式
全国服务热线:0755-88186625
Q Q:8705332
Email:admin@lanyu.com
地址:深圳市福田区海雅缤纷国际大厦5层501
Copyright 深圳市蓝宇科技有限公司 版权所有 备案号:京ICP备20013102号-1