feat: add resident miniapp MVP

This commit is contained in:
王鹏
2026-07-07 16:38:13 +08:00
parent bb325151d6
commit 576c54ec9d
52 changed files with 17865 additions and 66 deletions

View File

@@ -1 +1,69 @@
Page({})
const { getGroupBuyDetail, createGroupBuyOrder } = require('../../api/groupBuyApi')
const { listAddresses } = require('../../api/addressApi')
Page({
data: {
groupBuy: null,
addresses: [],
addressIndex: 0,
submitting: false,
form: {
quantity: 1,
deliveryMethod: 'SELF_PICKUP',
remark: ''
}
},
onLoad(options) {
this.groupBuyId = Number(options.id)
Promise.all([getGroupBuyDetail(this.groupBuyId), listAddresses().catch(() => [])])
.then(([groupBuy, addresses]) => {
this.setData({
groupBuy,
addresses: addresses || []
})
})
.catch((error) => wx.showToast({ title: error.message, icon: 'none' }))
},
onQuantityChange(event) {
this.setData({ 'form.quantity': Number(event.detail.value || 1) })
},
onMethodChange(event) {
this.setData({ 'form.deliveryMethod': event.detail.value })
},
onAddressChange(event) {
this.setData({ addressIndex: Number(event.detail.value) })
},
onRemarkInput(event) {
this.setData({ 'form.remark': event.detail.value })
},
submit() {
if (!this.data.groupBuy || this.data.submitting) {
return
}
const address = this.data.addresses[this.data.addressIndex]
if (this.data.form.deliveryMethod !== 'SELF_PICKUP' && !address) {
wx.showToast({ title: '请先添加地址', icon: 'none' })
return
}
this.setData({ submitting: true })
createGroupBuyOrder({
groupBuyId: this.data.groupBuy.id,
addressId: address ? address.id : null,
quantity: this.data.form.quantity,
deliveryMethod: this.data.form.deliveryMethod,
remark: this.data.form.remark
})
.then(() => {
wx.showToast({ title: '已提交' })
wx.navigateTo({ url: '/pages/orders/index' })
})
.catch((error) => wx.showToast({ title: error.message, icon: 'none' }))
.finally(() => this.setData({ submitting: false }))
}
})

View File

@@ -1 +1,25 @@
<view class="page">团购详情</view>
<view class="page" wx:if="{{groupBuy}}">
<view class="card">
<view class="section-title">{{groupBuy.title}}</view>
<view class="price">¥{{groupBuy.priceCent / 100}}</view>
<view class="muted">{{groupBuy.description || '社区团购'}}</view>
<view class="muted">自提点:{{groupBuy.pickupAddress}}</view>
</view>
<view class="card">
<view class="muted">数量</view>
<input class="input" type="number" value="{{form.quantity}}" bindinput="onQuantityChange" />
<view class="muted">提货方式</view>
<radio-group bindchange="onMethodChange">
<label class="radio"><radio value="SELF_PICKUP" checked="{{form.deliveryMethod === 'SELF_PICKUP'}}" />自提</label>
<label class="radio"><radio value="IMMEDIATE" checked="{{form.deliveryMethod === 'IMMEDIATE'}}" />配送</label>
</radio-group>
<view wx:if="{{form.deliveryMethod !== 'SELF_PICKUP'}}">
<view class="muted">收货地址</view>
<picker mode="selector" range="{{addresses}}" range-key="detail" value="{{addressIndex}}" bindchange="onAddressChange">
<view class="picker">{{addresses[addressIndex] ? addresses[addressIndex].building + ' ' + addresses[addressIndex].room + ' ' + addresses[addressIndex].detail : '请选择地址'}}</view>
</picker>
</view>
<textarea class="textarea" placeholder="备注" bindinput="onRemarkInput" />
<button class="primary" loading="{{submitting}}" bindtap="submit">提交团购订单</button>
</view>
</view>

View File

@@ -1,3 +1,5 @@
.page {
min-height: 100vh;
.radio {
display: block;
height: 60rpx;
line-height: 60rpx;
}

View File

@@ -1 +1,28 @@
Page({})
const { listGroupBuys } = require('../../api/groupBuyApi')
Page({
data: {
loading: false,
groupBuys: []
},
onLoad() {
this.load()
},
onShow() {
this.load()
},
load() {
this.setData({ loading: true })
listGroupBuys()
.then((groupBuys) => this.setData({ groupBuys: groupBuys || [] }))
.catch((error) => wx.showToast({ title: error.message, icon: 'none' }))
.finally(() => this.setData({ loading: false }))
},
goDetail(event) {
wx.navigateTo({ url: '/pages/group-buy/detail?id=' + event.currentTarget.dataset.id })
}
})

View File

@@ -1 +1,14 @@
<view class="page">今日团购</view>
<view class="page">
<view class="section-title">今日团购</view>
<view wx:for="{{groupBuys}}" wx:key="id" class="card" bindtap="goDetail" data-id="{{item.id}}">
<view class="row between">
<view>
<view>{{item.title}}</view>
<view class="muted">截单 {{item.endTime}}</view>
</view>
<view class="price">¥{{item.priceCent / 100}}</view>
</view>
<view class="muted">库存 {{item.stock}} / 已售 {{item.soldCount}}</view>
</view>
<view wx:if="{{!groupBuys.length && !loading}}" class="card muted">暂无团购</view>
</view>

View File

@@ -1,3 +1,4 @@
.page {
min-height: 100vh;
.price {
min-width: 120rpx;
text-align: right;
}