feat: add resident miniapp MVP
This commit is contained in:
26
miniapp/miniprogram/api/addressApi.js
Normal file
26
miniapp/miniprogram/api/addressApi.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
const { request } = require('../utils/request')
|
||||||
|
|
||||||
|
function listAddresses() {
|
||||||
|
return request({ url: '/api/mini/addresses' })
|
||||||
|
}
|
||||||
|
|
||||||
|
function createAddress(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/mini/addresses',
|
||||||
|
method: 'POST',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function setDefaultAddress(id) {
|
||||||
|
return request({
|
||||||
|
url: '/api/mini/addresses/' + id + '/default',
|
||||||
|
method: 'PUT'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
listAddresses,
|
||||||
|
createAddress,
|
||||||
|
setDefaultAddress
|
||||||
|
}
|
||||||
48
miniapp/miniprogram/api/expressApi.js
Normal file
48
miniapp/miniprogram/api/expressApi.js
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
const { request } = require('../utils/request')
|
||||||
|
|
||||||
|
function calculateExpressFeeCent(packageCount) {
|
||||||
|
if (packageCount <= 0) {
|
||||||
|
throw new Error('件数必须大于0')
|
||||||
|
}
|
||||||
|
return 300 + Math.max(0, packageCount - 1) * 100
|
||||||
|
}
|
||||||
|
|
||||||
|
function createExpressOrder(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/mini/express-orders',
|
||||||
|
method: 'POST',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function listExpressOrders() {
|
||||||
|
return request({ url: '/api/mini/express-orders' })
|
||||||
|
}
|
||||||
|
|
||||||
|
function getExpressOrderDetail(id) {
|
||||||
|
return request({ url: '/api/mini/express-orders/' + id })
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancelExpressOrder(id, reason) {
|
||||||
|
return request({
|
||||||
|
url: '/api/mini/express-orders/' + id + '/cancel',
|
||||||
|
method: 'PUT',
|
||||||
|
data: { reason }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function completeExpressOrder(id) {
|
||||||
|
return request({
|
||||||
|
url: '/api/mini/express-orders/' + id + '/complete',
|
||||||
|
method: 'PUT'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
calculateExpressFeeCent,
|
||||||
|
createExpressOrder,
|
||||||
|
listExpressOrders,
|
||||||
|
getExpressOrderDetail,
|
||||||
|
cancelExpressOrder,
|
||||||
|
completeExpressOrder
|
||||||
|
}
|
||||||
9
miniapp/miniprogram/api/expressApi.test.js
Normal file
9
miniapp/miniprogram/api/expressApi.test.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
const { calculateExpressFeeCent } = require('./expressApi')
|
||||||
|
|
||||||
|
describe('calculateExpressFeeCent', () => {
|
||||||
|
test('matches backend express fee rule', () => {
|
||||||
|
expect(calculateExpressFeeCent(1)).toBe(300)
|
||||||
|
expect(calculateExpressFeeCent(2)).toBe(400)
|
||||||
|
expect(calculateExpressFeeCent(4)).toBe(600)
|
||||||
|
})
|
||||||
|
})
|
||||||
41
miniapp/miniprogram/api/groupBuyApi.js
Normal file
41
miniapp/miniprogram/api/groupBuyApi.js
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
const { request } = require('../utils/request')
|
||||||
|
|
||||||
|
function listGroupBuys() {
|
||||||
|
return request({ url: '/api/mini/group-buys' })
|
||||||
|
}
|
||||||
|
|
||||||
|
function getGroupBuyDetail(id) {
|
||||||
|
return request({ url: '/api/mini/group-buys/' + id })
|
||||||
|
}
|
||||||
|
|
||||||
|
function createGroupBuyOrder(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/mini/group-buy-orders',
|
||||||
|
method: 'POST',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function listGroupBuyOrders() {
|
||||||
|
return request({ url: '/api/mini/group-buy-orders' })
|
||||||
|
}
|
||||||
|
|
||||||
|
function getGroupBuyOrderDetail(id) {
|
||||||
|
return request({ url: '/api/mini/group-buy-orders/' + id })
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancelGroupBuyOrder(id) {
|
||||||
|
return request({
|
||||||
|
url: '/api/mini/group-buy-orders/' + id + '/cancel',
|
||||||
|
method: 'PUT'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
listGroupBuys,
|
||||||
|
getGroupBuyDetail,
|
||||||
|
createGroupBuyOrder,
|
||||||
|
listGroupBuyOrders,
|
||||||
|
getGroupBuyOrderDetail,
|
||||||
|
cancelGroupBuyOrder
|
||||||
|
}
|
||||||
21
miniapp/miniprogram/api/homeApi.js
Normal file
21
miniapp/miniprogram/api/homeApi.js
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
const { request } = require('../utils/request')
|
||||||
|
|
||||||
|
function getHomeData() {
|
||||||
|
return Promise.all([
|
||||||
|
request({ url: '/api/mini/banners' }).catch(() => []),
|
||||||
|
request({ url: '/api/mini/notices' }).catch(() => []),
|
||||||
|
request({ url: '/api/mini/products' }).catch(() => []),
|
||||||
|
request({ url: '/api/mini/group-buys' }).catch(() => []),
|
||||||
|
request({ url: '/api/mini/second-goods' }).catch(() => [])
|
||||||
|
]).then(([banners, notices, products, groupBuys, secondGoods]) => ({
|
||||||
|
banners,
|
||||||
|
notices,
|
||||||
|
products,
|
||||||
|
groupBuys,
|
||||||
|
secondGoods
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
getHomeData
|
||||||
|
}
|
||||||
14
miniapp/miniprogram/api/noticeApi.js
Normal file
14
miniapp/miniprogram/api/noticeApi.js
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
const { request } = require('../utils/request')
|
||||||
|
|
||||||
|
function listNotices() {
|
||||||
|
return request({ url: '/api/mini/notices' })
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNoticeDetail(id) {
|
||||||
|
return request({ url: '/api/mini/notices/' + id })
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
listNotices,
|
||||||
|
getNoticeDetail
|
||||||
|
}
|
||||||
22
miniapp/miniprogram/api/orderApi.js
Normal file
22
miniapp/miniprogram/api/orderApi.js
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
const { request } = require('../utils/request')
|
||||||
|
|
||||||
|
function listGoodsOrders() {
|
||||||
|
return request({ url: '/api/mini/goods-orders' })
|
||||||
|
}
|
||||||
|
|
||||||
|
function getGoodsOrderDetail(id) {
|
||||||
|
return request({ url: '/api/mini/goods-orders/' + id })
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancelGoodsOrder(id) {
|
||||||
|
return request({
|
||||||
|
url: '/api/mini/goods-orders/' + id + '/cancel',
|
||||||
|
method: 'PUT'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
listGoodsOrders,
|
||||||
|
getGoodsOrderDetail,
|
||||||
|
cancelGoodsOrder
|
||||||
|
}
|
||||||
31
miniapp/miniprogram/api/productApi.js
Normal file
31
miniapp/miniprogram/api/productApi.js
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
const { request } = require('../utils/request')
|
||||||
|
|
||||||
|
function listCategories() {
|
||||||
|
return request({ url: '/api/mini/product-categories' })
|
||||||
|
}
|
||||||
|
|
||||||
|
function listProducts(categoryId) {
|
||||||
|
return request({
|
||||||
|
url: '/api/mini/products',
|
||||||
|
data: categoryId ? { categoryId } : {}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function getProductDetail(id) {
|
||||||
|
return request({ url: '/api/mini/products/' + id })
|
||||||
|
}
|
||||||
|
|
||||||
|
function createGoodsOrder(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/mini/goods-orders',
|
||||||
|
method: 'POST',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
listCategories,
|
||||||
|
listProducts,
|
||||||
|
getProductDetail,
|
||||||
|
createGoodsOrder
|
||||||
|
}
|
||||||
26
miniapp/miniprogram/api/secondGoodsApi.js
Normal file
26
miniapp/miniprogram/api/secondGoodsApi.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
const { request } = require('../utils/request')
|
||||||
|
|
||||||
|
function listSecondGoods(category) {
|
||||||
|
return request({
|
||||||
|
url: '/api/mini/second-goods',
|
||||||
|
data: category ? { category } : {}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSecondGoodsDetail(id) {
|
||||||
|
return request({ url: '/api/mini/second-goods/' + id })
|
||||||
|
}
|
||||||
|
|
||||||
|
function createSecondGoods(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/mini/second-goods',
|
||||||
|
method: 'POST',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
listSecondGoods,
|
||||||
|
getSecondGoodsDetail,
|
||||||
|
createSecondGoods
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
App({
|
App({
|
||||||
globalData: {
|
globalData: {
|
||||||
apiBaseUrl: 'http://localhost:8080',
|
apiBaseUrl: 'http://localhost:8080',
|
||||||
token: ''
|
token: '',
|
||||||
|
user: null
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,9 +1,114 @@
|
|||||||
page {
|
page {
|
||||||
background: #f6f7f9;
|
background: #f4f6f8;
|
||||||
color: #111827;
|
color: #17212b;
|
||||||
font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", sans-serif;
|
font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", sans-serif;
|
||||||
|
font-size: 28rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.page {
|
.page {
|
||||||
|
min-height: 100vh;
|
||||||
padding: 24rpx;
|
padding: 24rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.section {
|
||||||
|
margin-bottom: 24rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
margin: 0 0 16rpx;
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
background: #ffffff;
|
||||||
|
border: 1rpx solid #e5e9ef;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
padding: 20rpx;
|
||||||
|
margin-bottom: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.between {
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.muted {
|
||||||
|
color: #64748b;
|
||||||
|
font-size: 24rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.price {
|
||||||
|
color: #c2410c;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 4rpx 12rpx;
|
||||||
|
background: #e6f4f1;
|
||||||
|
color: #0f766e;
|
||||||
|
border-radius: 6rpx;
|
||||||
|
font-size: 22rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shortcut {
|
||||||
|
width: calc((100% - 32rpx) / 3);
|
||||||
|
height: 116rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: #ffffff;
|
||||||
|
border: 1rpx solid #e5e9ef;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input,
|
||||||
|
.textarea,
|
||||||
|
.picker {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 76rpx;
|
||||||
|
padding: 0 18rpx;
|
||||||
|
background: #ffffff;
|
||||||
|
border: 1rpx solid #d9e0e8;
|
||||||
|
border-radius: 6rpx;
|
||||||
|
margin-bottom: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.textarea {
|
||||||
|
min-height: 140rpx;
|
||||||
|
padding-top: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-row {
|
||||||
|
display: flex;
|
||||||
|
gap: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
border-radius: 6rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.primary {
|
||||||
|
background: #0f766e;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ghost {
|
||||||
|
background: #ffffff;
|
||||||
|
color: #0f766e;
|
||||||
|
border: 1rpx solid #0f766e;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1 +1,64 @@
|
|||||||
Page({})
|
const { listAddresses, createAddress, setDefaultAddress } = require('../../api/addressApi')
|
||||||
|
const { setField } = require('../../utils/request')
|
||||||
|
|
||||||
|
Page({
|
||||||
|
data: {
|
||||||
|
addresses: [],
|
||||||
|
submitting: false,
|
||||||
|
form: {
|
||||||
|
contactName: '',
|
||||||
|
phone: '',
|
||||||
|
building: '',
|
||||||
|
room: '',
|
||||||
|
detail: '',
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onLoad() {
|
||||||
|
this.load()
|
||||||
|
},
|
||||||
|
|
||||||
|
load() {
|
||||||
|
return listAddresses()
|
||||||
|
.then((addresses) => this.setData({ addresses: addresses || [] }))
|
||||||
|
.catch((error) => wx.showToast({ title: error.message, icon: 'none' }))
|
||||||
|
},
|
||||||
|
|
||||||
|
onFieldInput(event) {
|
||||||
|
setField(this, event)
|
||||||
|
},
|
||||||
|
|
||||||
|
submit() {
|
||||||
|
if (this.data.submitting) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.setData({ submitting: true })
|
||||||
|
createAddress(this.data.form)
|
||||||
|
.then(() => {
|
||||||
|
wx.showToast({ title: '已保存' })
|
||||||
|
this.setData({
|
||||||
|
form: {
|
||||||
|
contactName: '',
|
||||||
|
phone: '',
|
||||||
|
building: '',
|
||||||
|
room: '',
|
||||||
|
detail: '',
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return this.load()
|
||||||
|
})
|
||||||
|
.catch((error) => wx.showToast({ title: error.message, icon: 'none' }))
|
||||||
|
.finally(() => this.setData({ submitting: false }))
|
||||||
|
},
|
||||||
|
|
||||||
|
setDefault(event) {
|
||||||
|
setDefaultAddress(event.currentTarget.dataset.id)
|
||||||
|
.then(() => {
|
||||||
|
wx.showToast({ title: '已设默认' })
|
||||||
|
return this.load()
|
||||||
|
})
|
||||||
|
.catch((error) => wx.showToast({ title: error.message, icon: 'none' }))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|||||||
@@ -1 +1,19 @@
|
|||||||
<view class="page">地址管理</view>
|
<view class="page">
|
||||||
|
<view class="section-title">地址管理</view>
|
||||||
|
<view class="card">
|
||||||
|
<input class="input" placeholder="联系人" data-field="contactName" value="{{form.contactName}}" bindinput="onFieldInput" />
|
||||||
|
<input class="input" placeholder="手机号" data-field="phone" value="{{form.phone}}" bindinput="onFieldInput" />
|
||||||
|
<input class="input" placeholder="楼栋" data-field="building" value="{{form.building}}" bindinput="onFieldInput" />
|
||||||
|
<input class="input" placeholder="房号" data-field="room" value="{{form.room}}" bindinput="onFieldInput" />
|
||||||
|
<input class="input" placeholder="详细地址" data-field="detail" value="{{form.detail}}" bindinput="onFieldInput" />
|
||||||
|
<button class="primary" loading="{{submitting}}" bindtap="submit">保存地址</button>
|
||||||
|
</view>
|
||||||
|
<view wx:for="{{addresses}}" wx:key="id" class="card">
|
||||||
|
<view class="row between">
|
||||||
|
<view>{{item.contactName}} {{item.phone}}</view>
|
||||||
|
<view wx:if="{{item.default}}" class="tag">默认</view>
|
||||||
|
</view>
|
||||||
|
<view class="muted">{{item.building}} {{item.room}} {{item.detail}}</view>
|
||||||
|
<button wx:if="{{!item.default}}" size="mini" class="ghost" data-id="{{item.id}}" bindtap="setDefault">设为默认</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
.page {
|
.ghost {
|
||||||
min-height: 100vh;
|
margin-top: 16rpx;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1,71 @@
|
|||||||
Page({})
|
const { calculateExpressFeeCent, createExpressOrder } = require('../../api/expressApi')
|
||||||
|
const { listAddresses } = require('../../api/addressApi')
|
||||||
|
const { setField } = require('../../utils/request')
|
||||||
|
|
||||||
|
Page({
|
||||||
|
data: {
|
||||||
|
addresses: [],
|
||||||
|
addressIndex: 0,
|
||||||
|
feeCent: 300,
|
||||||
|
submitting: false,
|
||||||
|
form: {
|
||||||
|
expressCompany: '',
|
||||||
|
pickupCode: '',
|
||||||
|
pickupAddress: '',
|
||||||
|
receiverPhone: '',
|
||||||
|
addressId: null,
|
||||||
|
packageCount: 1,
|
||||||
|
remark: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onLoad() {
|
||||||
|
listAddresses()
|
||||||
|
.then((addresses) => {
|
||||||
|
this.setData({
|
||||||
|
addresses: addresses || [],
|
||||||
|
'form.addressId': addresses && addresses[0] ? addresses[0].id : null
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
},
|
||||||
|
|
||||||
|
onFieldInput(event) {
|
||||||
|
setField(this, event)
|
||||||
|
},
|
||||||
|
|
||||||
|
onAddressChange(event) {
|
||||||
|
const index = Number(event.detail.value)
|
||||||
|
const address = this.data.addresses[index]
|
||||||
|
this.setData({
|
||||||
|
addressIndex: index,
|
||||||
|
'form.addressId': address ? address.id : null
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
onPackageCountChange(event) {
|
||||||
|
const packageCount = Number(event.detail.value || 1)
|
||||||
|
this.setData({
|
||||||
|
'form.packageCount': packageCount,
|
||||||
|
feeCent: calculateExpressFeeCent(packageCount)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
submit() {
|
||||||
|
if (this.data.submitting) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!this.data.form.addressId) {
|
||||||
|
wx.showToast({ title: '请先添加地址', icon: 'none' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.setData({ submitting: true })
|
||||||
|
createExpressOrder(this.data.form)
|
||||||
|
.then(() => {
|
||||||
|
wx.showToast({ title: '已提交' })
|
||||||
|
wx.navigateTo({ url: '/pages/orders/index' })
|
||||||
|
})
|
||||||
|
.catch((error) => wx.showToast({ title: error.message, icon: 'none' }))
|
||||||
|
.finally(() => this.setData({ submitting: false }))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|||||||
@@ -1 +1,23 @@
|
|||||||
<view class="page">代取快递</view>
|
<view class="page">
|
||||||
|
<view class="section-title">代取快递</view>
|
||||||
|
<view class="card">
|
||||||
|
<input class="input" placeholder="快递公司" data-field="expressCompany" bindinput="onFieldInput" />
|
||||||
|
<input class="input" placeholder="取件码" data-field="pickupCode" bindinput="onFieldInput" />
|
||||||
|
<input class="input" placeholder="快递站地址" data-field="pickupAddress" bindinput="onFieldInput" />
|
||||||
|
<input class="input" placeholder="手机号" data-field="receiverPhone" bindinput="onFieldInput" />
|
||||||
|
<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>
|
||||||
|
<input class="input" type="number" value="{{form.packageCount}}" bindinput="onPackageCountChange" />
|
||||||
|
<view class="card">
|
||||||
|
<view class="row between">
|
||||||
|
<text>预估服务费</text>
|
||||||
|
<text class="price">¥{{feeCent / 100}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="muted">首件 3 元,续件每件 1 元</view>
|
||||||
|
</view>
|
||||||
|
<textarea class="textarea" placeholder="备注" data-field="remark" bindinput="onFieldInput" />
|
||||||
|
<button class="primary" loading="{{submitting}}" bindtap="submit">提交代取</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
.page {
|
.card .card {
|
||||||
min-height: 100vh;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 }))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
.page {
|
.radio {
|
||||||
min-height: 100vh;
|
display: block;
|
||||||
|
height: 60rpx;
|
||||||
|
line-height: 60rpx;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
.page {
|
.price {
|
||||||
min-height: 100vh;
|
min-width: 120rpx;
|
||||||
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1,49 @@
|
|||||||
Page({})
|
const { getHomeData } = require('../../api/homeApi')
|
||||||
|
const { yuan } = require('../../utils/request')
|
||||||
|
|
||||||
|
Page({
|
||||||
|
data: {
|
||||||
|
loading: false,
|
||||||
|
banners: [],
|
||||||
|
notices: [],
|
||||||
|
products: [],
|
||||||
|
groupBuys: [],
|
||||||
|
secondGoods: []
|
||||||
|
},
|
||||||
|
|
||||||
|
onLoad() {
|
||||||
|
this.load()
|
||||||
|
},
|
||||||
|
|
||||||
|
onPullDownRefresh() {
|
||||||
|
this.load().finally(() => wx.stopPullDownRefresh())
|
||||||
|
},
|
||||||
|
|
||||||
|
load() {
|
||||||
|
this.setData({ loading: true })
|
||||||
|
return getHomeData()
|
||||||
|
.then((data) => {
|
||||||
|
this.setData({
|
||||||
|
banners: data.banners || [],
|
||||||
|
notices: (data.notices || []).slice(0, 3),
|
||||||
|
products: (data.products || []).slice(0, 6),
|
||||||
|
groupBuys: (data.groupBuys || []).slice(0, 3),
|
||||||
|
secondGoods: (data.secondGoods || []).slice(0, 3)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch((error) => wx.showToast({ title: error.message, icon: 'none' }))
|
||||||
|
.finally(() => this.setData({ loading: false }))
|
||||||
|
},
|
||||||
|
|
||||||
|
go(event) {
|
||||||
|
wx.navigateTo({ url: event.currentTarget.dataset.url })
|
||||||
|
},
|
||||||
|
|
||||||
|
goTab(event) {
|
||||||
|
wx.switchTab({ url: event.currentTarget.dataset.url })
|
||||||
|
},
|
||||||
|
|
||||||
|
yuan(cent) {
|
||||||
|
return yuan(cent)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|||||||
@@ -1 +1,57 @@
|
|||||||
<view class="page">邻小帮</view>
|
<view class="page">
|
||||||
|
<view class="section">
|
||||||
|
<view class="section-title">邻小帮</view>
|
||||||
|
<view class="muted">社区服务 30 分钟到家</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="grid section">
|
||||||
|
<view class="shortcut" bindtap="go" data-url="/pages/products/index">商品预定</view>
|
||||||
|
<view class="shortcut" bindtap="go" data-url="/pages/express/create">代取快递</view>
|
||||||
|
<view class="shortcut" bindtap="goTab" data-url="/pages/group-buy/index">今日团购</view>
|
||||||
|
<view class="shortcut" bindtap="goTab" data-url="/pages/second-hand/index">二手闲置</view>
|
||||||
|
<view class="shortcut" bindtap="go" data-url="/pages/notices/index">社区公告</view>
|
||||||
|
<view class="shortcut" bindtap="go" data-url="/pages/orders/index">我的订单</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="section">
|
||||||
|
<view class="section-title">公告</view>
|
||||||
|
<view wx:for="{{notices}}" wx:key="id" class="card" bindtap="go" data-url="/pages/notices/index">
|
||||||
|
<view>{{item.title}}</view>
|
||||||
|
<view class="muted">{{item.category}}</view>
|
||||||
|
</view>
|
||||||
|
<view wx:if="{{!notices.length}}" class="card muted">暂无公告</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="section">
|
||||||
|
<view class="section-title">热门商品</view>
|
||||||
|
<view wx:for="{{products}}" wx:key="id" class="card" bindtap="go" data-url="/pages/products/detail?id={{item.id}}">
|
||||||
|
<view class="row between">
|
||||||
|
<view>{{item.name}}</view>
|
||||||
|
<view class="tag">{{item.status}}</view>
|
||||||
|
</view>
|
||||||
|
<view class="muted">{{item.description || '社区商品'}}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="section">
|
||||||
|
<view class="section-title">今日团购</view>
|
||||||
|
<view wx:for="{{groupBuys}}" wx:key="id" class="card" bindtap="go" data-url="/pages/group-buy/detail?id={{item.id}}">
|
||||||
|
<view class="row between">
|
||||||
|
<view>{{item.title}}</view>
|
||||||
|
<view class="price">¥{{item.priceCent / 100}}</view>
|
||||||
|
</view>
|
||||||
|
<view class="muted">已售 {{item.soldCount}} / 库存 {{item.stock}}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="section">
|
||||||
|
<view class="section-title">最新闲置</view>
|
||||||
|
<view wx:for="{{secondGoods}}" wx:key="id" class="card">
|
||||||
|
<view class="row between">
|
||||||
|
<view>{{item.title}}</view>
|
||||||
|
<view class="price">¥{{item.priceCent / 100}}</view>
|
||||||
|
</view>
|
||||||
|
<view class="muted">{{item.category}}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
.page {
|
.page {
|
||||||
min-height: 100vh;
|
padding-bottom: 40rpx;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1,20 @@
|
|||||||
Page({})
|
const { listNotices } = require('../../api/noticeApi')
|
||||||
|
|
||||||
|
Page({
|
||||||
|
data: {
|
||||||
|
loading: false,
|
||||||
|
notices: []
|
||||||
|
},
|
||||||
|
|
||||||
|
onLoad() {
|
||||||
|
this.load()
|
||||||
|
},
|
||||||
|
|
||||||
|
load() {
|
||||||
|
this.setData({ loading: true })
|
||||||
|
listNotices()
|
||||||
|
.then((notices) => this.setData({ notices: notices || [] }))
|
||||||
|
.catch((error) => wx.showToast({ title: error.message, icon: 'none' }))
|
||||||
|
.finally(() => this.setData({ loading: false }))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|||||||
@@ -1 +1,12 @@
|
|||||||
<view class="page">社区公告</view>
|
<view class="page">
|
||||||
|
<view class="section-title">社区公告</view>
|
||||||
|
<view wx:for="{{notices}}" wx:key="id" class="card">
|
||||||
|
<view class="row between">
|
||||||
|
<view>{{item.title}}</view>
|
||||||
|
<view wx:if="{{item.pinned}}" class="tag">置顶</view>
|
||||||
|
</view>
|
||||||
|
<view class="muted">{{item.category}} {{item.publishedAt}}</view>
|
||||||
|
<view>{{item.content}}</view>
|
||||||
|
</view>
|
||||||
|
<view wx:if="{{!notices.length && !loading}}" class="card muted">暂无公告</view>
|
||||||
|
</view>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
.page {
|
.card > view:last-child {
|
||||||
min-height: 100vh;
|
margin-top: 12rpx;
|
||||||
|
line-height: 44rpx;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1,56 @@
|
|||||||
Page({})
|
const { getGoodsOrderDetail, cancelGoodsOrder } = require('../../api/orderApi')
|
||||||
|
const { getExpressOrderDetail, cancelExpressOrder, completeExpressOrder } = require('../../api/expressApi')
|
||||||
|
const { getGroupBuyOrderDetail, cancelGroupBuyOrder } = require('../../api/groupBuyApi')
|
||||||
|
const { statusText } = require('../../utils/request')
|
||||||
|
|
||||||
|
Page({
|
||||||
|
data: {
|
||||||
|
type: '',
|
||||||
|
order: null
|
||||||
|
},
|
||||||
|
|
||||||
|
onLoad(options) {
|
||||||
|
this.type = options.type
|
||||||
|
this.id = Number(options.id)
|
||||||
|
this.setData({ type: this.type })
|
||||||
|
this.load()
|
||||||
|
},
|
||||||
|
|
||||||
|
load() {
|
||||||
|
const loaders = {
|
||||||
|
goods: getGoodsOrderDetail,
|
||||||
|
express: getExpressOrderDetail,
|
||||||
|
group: getGroupBuyOrderDetail
|
||||||
|
}
|
||||||
|
loaders[this.type](this.id)
|
||||||
|
.then((order) => this.setData({ order }))
|
||||||
|
.catch((error) => wx.showToast({ title: error.message, icon: 'none' }))
|
||||||
|
},
|
||||||
|
|
||||||
|
cancel() {
|
||||||
|
const actions = {
|
||||||
|
goods: () => cancelGoodsOrder(this.id),
|
||||||
|
express: () => cancelExpressOrder(this.id, '用户取消'),
|
||||||
|
group: () => cancelGroupBuyOrder(this.id)
|
||||||
|
}
|
||||||
|
actions[this.type]()
|
||||||
|
.then(() => {
|
||||||
|
wx.showToast({ title: '已取消' })
|
||||||
|
this.load()
|
||||||
|
})
|
||||||
|
.catch((error) => wx.showToast({ title: error.message, icon: 'none' }))
|
||||||
|
},
|
||||||
|
|
||||||
|
completeExpress() {
|
||||||
|
completeExpressOrder(this.id)
|
||||||
|
.then(() => {
|
||||||
|
wx.showToast({ title: '已完成' })
|
||||||
|
this.load()
|
||||||
|
})
|
||||||
|
.catch((error) => wx.showToast({ title: error.message, icon: 'none' }))
|
||||||
|
},
|
||||||
|
|
||||||
|
statusText(status) {
|
||||||
|
return statusText(status)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|||||||
@@ -1 +1,29 @@
|
|||||||
<view class="page">订单详情</view>
|
<view class="page" wx:if="{{order}}">
|
||||||
|
<view class="card">
|
||||||
|
<view class="section-title">{{order.orderNo}}</view>
|
||||||
|
<view class="tag">{{order.status}}</view>
|
||||||
|
<view class="muted">类型:{{type}}</view>
|
||||||
|
</view>
|
||||||
|
<view class="card">
|
||||||
|
<view wx:if="{{type === 'goods'}}">
|
||||||
|
<view>商品金额:¥{{order.totalAmountCent / 100}}</view>
|
||||||
|
<view>配送费:¥{{order.deliveryFeeCent / 100}}</view>
|
||||||
|
<view class="price">应收:¥{{order.payableAmountCent / 100}}</view>
|
||||||
|
<view class="muted">{{order.deliveryMethod}}</view>
|
||||||
|
</view>
|
||||||
|
<view wx:if="{{type === 'express'}}">
|
||||||
|
<view>{{order.expressCompany}} / {{order.pickupCode}}</view>
|
||||||
|
<view class="muted">{{order.pickupAddress}}</view>
|
||||||
|
<view class="price">服务费:¥{{order.feeCent / 100}}</view>
|
||||||
|
</view>
|
||||||
|
<view wx:if="{{type === 'group'}}">
|
||||||
|
<view>{{order.groupBuyTitle}}</view>
|
||||||
|
<view>数量:{{order.quantity}}</view>
|
||||||
|
<view class="price">金额:¥{{order.amountCent / 100}}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="button-row">
|
||||||
|
<button class="ghost" bindtap="cancel">取消订单</button>
|
||||||
|
<button wx:if="{{type === 'express'}}" class="primary" bindtap="completeExpress">确认完成</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
.page {
|
.button-row button {
|
||||||
min-height: 100vh;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1,70 @@
|
|||||||
Page({})
|
const { listGoodsOrders } = require('../../api/orderApi')
|
||||||
|
const { listExpressOrders } = require('../../api/expressApi')
|
||||||
|
const { listGroupBuyOrders } = require('../../api/groupBuyApi')
|
||||||
|
const { statusText } = require('../../utils/request')
|
||||||
|
|
||||||
|
Page({
|
||||||
|
data: {
|
||||||
|
loading: false,
|
||||||
|
orders: []
|
||||||
|
},
|
||||||
|
|
||||||
|
onLoad() {
|
||||||
|
this.load()
|
||||||
|
},
|
||||||
|
|
||||||
|
onShow() {
|
||||||
|
this.load()
|
||||||
|
},
|
||||||
|
|
||||||
|
load() {
|
||||||
|
this.setData({ loading: true })
|
||||||
|
Promise.all([
|
||||||
|
listGoodsOrders().catch(() => []),
|
||||||
|
listExpressOrders().catch(() => []),
|
||||||
|
listGroupBuyOrders().catch(() => [])
|
||||||
|
])
|
||||||
|
.then(([goodsOrders, expressOrders, groupBuyOrders]) => {
|
||||||
|
const orders = []
|
||||||
|
;(goodsOrders || []).forEach((item) => orders.push({
|
||||||
|
id: item.id,
|
||||||
|
type: 'goods',
|
||||||
|
typeText: '商品订单',
|
||||||
|
orderNo: item.orderNo,
|
||||||
|
title: item.orderNo,
|
||||||
|
amountCent: item.payableAmountCent,
|
||||||
|
status: item.status
|
||||||
|
}))
|
||||||
|
;(expressOrders || []).forEach((item) => orders.push({
|
||||||
|
id: item.id,
|
||||||
|
type: 'express',
|
||||||
|
typeText: '快递代取',
|
||||||
|
orderNo: item.orderNo,
|
||||||
|
title: item.expressCompany + ' ' + item.pickupCode,
|
||||||
|
amountCent: item.feeCent,
|
||||||
|
status: item.status
|
||||||
|
}))
|
||||||
|
;(groupBuyOrders || []).forEach((item) => orders.push({
|
||||||
|
id: item.id,
|
||||||
|
type: 'group',
|
||||||
|
typeText: '团购订单',
|
||||||
|
orderNo: item.orderNo,
|
||||||
|
title: item.groupBuyTitle,
|
||||||
|
amountCent: item.amountCent,
|
||||||
|
status: item.status
|
||||||
|
}))
|
||||||
|
this.setData({ orders })
|
||||||
|
})
|
||||||
|
.catch((error) => wx.showToast({ title: error.message, icon: 'none' }))
|
||||||
|
.finally(() => this.setData({ loading: false }))
|
||||||
|
},
|
||||||
|
|
||||||
|
goDetail(event) {
|
||||||
|
const { type, id } = event.currentTarget.dataset
|
||||||
|
wx.navigateTo({ url: '/pages/orders/detail?type=' + type + '&id=' + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
statusText(status) {
|
||||||
|
return statusText(status)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|||||||
@@ -1 +1,17 @@
|
|||||||
<view class="page">我的订单</view>
|
<view class="page">
|
||||||
|
<view class="section-title">我的订单</view>
|
||||||
|
<view wx:for="{{orders}}" wx:key="id" class="card" bindtap="goDetail" data-type="{{item.type}}" data-id="{{item.id}}">
|
||||||
|
<view class="row between">
|
||||||
|
<view>
|
||||||
|
<view>{{item.title}}</view>
|
||||||
|
<view class="muted">{{item.typeText}} {{item.orderNo}}</view>
|
||||||
|
</view>
|
||||||
|
<view class="tag">{{item.status}}</view>
|
||||||
|
</view>
|
||||||
|
<view class="row between">
|
||||||
|
<view class="muted">状态:{{item.status}}</view>
|
||||||
|
<view class="price">¥{{item.amountCent / 100}}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view wx:if="{{!orders.length && !loading}}" class="card muted">暂无订单</view>
|
||||||
|
</view>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
.page {
|
.tag {
|
||||||
min-height: 100vh;
|
min-width: 120rpx;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1,93 @@
|
|||||||
Page({})
|
const { getProductDetail, createGoodsOrder } = require('../../api/productApi')
|
||||||
|
const { listAddresses } = require('../../api/addressApi')
|
||||||
|
|
||||||
|
Page({
|
||||||
|
data: {
|
||||||
|
product: null,
|
||||||
|
addresses: [],
|
||||||
|
addressIndex: 0,
|
||||||
|
skuIndex: 0,
|
||||||
|
submitting: false,
|
||||||
|
form: {
|
||||||
|
quantity: 1,
|
||||||
|
deliveryMethod: 'IMMEDIATE',
|
||||||
|
scheduledTime: '',
|
||||||
|
remark: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onLoad(options) {
|
||||||
|
this.productId = Number(options.id)
|
||||||
|
this.load()
|
||||||
|
},
|
||||||
|
|
||||||
|
load() {
|
||||||
|
Promise.all([getProductDetail(this.productId), listAddresses().catch(() => [])])
|
||||||
|
.then(([product, addresses]) => {
|
||||||
|
this.setData({
|
||||||
|
product,
|
||||||
|
addresses: addresses || []
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch((error) => wx.showToast({ title: error.message, icon: 'none' }))
|
||||||
|
},
|
||||||
|
|
||||||
|
onSkuChange(event) {
|
||||||
|
this.setData({ skuIndex: Number(event.detail.value) })
|
||||||
|
},
|
||||||
|
|
||||||
|
onAddressChange(event) {
|
||||||
|
this.setData({ addressIndex: Number(event.detail.value) })
|
||||||
|
},
|
||||||
|
|
||||||
|
onQuantityChange(event) {
|
||||||
|
this.setData({ 'form.quantity': Number(event.detail.value || 1) })
|
||||||
|
},
|
||||||
|
|
||||||
|
onMethodChange(event) {
|
||||||
|
this.setData({ 'form.deliveryMethod': event.detail.value })
|
||||||
|
},
|
||||||
|
|
||||||
|
onScheduledTimeChange(event) {
|
||||||
|
this.setData({ 'form.scheduledTime': event.detail.value })
|
||||||
|
},
|
||||||
|
|
||||||
|
onRemarkInput(event) {
|
||||||
|
this.setData({ 'form.remark': event.detail.value })
|
||||||
|
},
|
||||||
|
|
||||||
|
submit() {
|
||||||
|
if (!this.data.product || this.data.submitting) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const sku = this.data.product.skus[this.data.skuIndex]
|
||||||
|
if (!sku) {
|
||||||
|
wx.showToast({ title: '请选择规格', icon: 'none' })
|
||||||
|
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 })
|
||||||
|
createGoodsOrder({
|
||||||
|
merchantId: this.data.product.merchantId,
|
||||||
|
addressId: address ? address.id : null,
|
||||||
|
deliveryMethod: this.data.form.deliveryMethod,
|
||||||
|
scheduledTime: this.data.form.scheduledTime || null,
|
||||||
|
remark: this.data.form.remark,
|
||||||
|
items: [{
|
||||||
|
productId: this.data.product.id,
|
||||||
|
skuId: sku.id,
|
||||||
|
quantity: this.data.form.quantity
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
wx.showToast({ title: '已提交' })
|
||||||
|
wx.navigateTo({ url: '/pages/orders/index' })
|
||||||
|
})
|
||||||
|
.catch((error) => wx.showToast({ title: error.message, icon: 'none' }))
|
||||||
|
.finally(() => this.setData({ submitting: false }))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|||||||
@@ -1 +1,34 @@
|
|||||||
<view class="page">商品详情</view>
|
<view class="page" wx:if="{{product}}">
|
||||||
|
<view class="card">
|
||||||
|
<view class="section-title">{{product.name}}</view>
|
||||||
|
<view class="muted">{{product.description || '社区商品'}}</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="card">
|
||||||
|
<view class="muted">规格</view>
|
||||||
|
<picker mode="selector" range="{{product.skus}}" range-key="skuName" value="{{skuIndex}}" bindchange="onSkuChange">
|
||||||
|
<view class="picker">{{product.skus[skuIndex].skuName}} / ¥{{product.skus[skuIndex].priceCent / 100}} / 库存 {{product.skus[skuIndex].stock}}</view>
|
||||||
|
</picker>
|
||||||
|
<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="IMMEDIATE" checked="{{form.deliveryMethod === 'IMMEDIATE'}}" />立即配送</label>
|
||||||
|
<label class="radio"><radio value="SCHEDULED" checked="{{form.deliveryMethod === 'SCHEDULED'}}" />预约配送</label>
|
||||||
|
<label class="radio"><radio value="SELF_PICKUP" checked="{{form.deliveryMethod === 'SELF_PICKUP'}}" />自提</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>
|
||||||
|
<view wx:if="{{form.deliveryMethod === 'SCHEDULED'}}">
|
||||||
|
<view class="muted">预约时间</view>
|
||||||
|
<input class="input" placeholder="2026-07-07T18:30:00" bindinput="onScheduledTimeChange" />
|
||||||
|
</view>
|
||||||
|
<view class="muted">备注</view>
|
||||||
|
<textarea class="textarea" bindinput="onRemarkInput" />
|
||||||
|
<button class="primary" loading="{{submitting}}" bindtap="submit">提交订单</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
.page {
|
.radio {
|
||||||
min-height: 100vh;
|
display: block;
|
||||||
|
height: 60rpx;
|
||||||
|
line-height: 60rpx;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1,46 @@
|
|||||||
Page({})
|
const { listCategories, listProducts } = require('../../api/productApi')
|
||||||
|
|
||||||
|
Page({
|
||||||
|
data: {
|
||||||
|
loading: false,
|
||||||
|
categories: [],
|
||||||
|
activeCategoryId: null,
|
||||||
|
products: []
|
||||||
|
},
|
||||||
|
|
||||||
|
onLoad() {
|
||||||
|
this.load()
|
||||||
|
},
|
||||||
|
|
||||||
|
load() {
|
||||||
|
this.setData({ loading: true })
|
||||||
|
Promise.all([listCategories(), listProducts()])
|
||||||
|
.then(([categories, products]) => {
|
||||||
|
this.setData({
|
||||||
|
categories: categories || [],
|
||||||
|
products: products || []
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch((error) => wx.showToast({ title: error.message, icon: 'none' }))
|
||||||
|
.finally(() => this.setData({ loading: false }))
|
||||||
|
},
|
||||||
|
|
||||||
|
chooseCategory(event) {
|
||||||
|
const categoryId = event.currentTarget.dataset.id
|
||||||
|
this.setData({ activeCategoryId: categoryId })
|
||||||
|
listProducts(categoryId)
|
||||||
|
.then((products) => this.setData({ products: products || [] }))
|
||||||
|
.catch((error) => wx.showToast({ title: error.message, icon: 'none' }))
|
||||||
|
},
|
||||||
|
|
||||||
|
clearCategory() {
|
||||||
|
this.setData({ activeCategoryId: null })
|
||||||
|
listProducts()
|
||||||
|
.then((products) => this.setData({ products: products || [] }))
|
||||||
|
.catch((error) => wx.showToast({ title: error.message, icon: 'none' }))
|
||||||
|
},
|
||||||
|
|
||||||
|
goDetail(event) {
|
||||||
|
wx.navigateTo({ url: '/pages/products/detail?id=' + event.currentTarget.dataset.id })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|||||||
@@ -1 +1,28 @@
|
|||||||
<view class="page">商品预定</view>
|
<view class="page">
|
||||||
|
<view class="section-title">商品预定</view>
|
||||||
|
<scroll-view scroll-x class="category-scroll">
|
||||||
|
<view class="category-item {{!activeCategoryId ? 'active' : ''}}" bindtap="clearCategory">全部</view>
|
||||||
|
<view
|
||||||
|
wx:for="{{categories}}"
|
||||||
|
wx:key="id"
|
||||||
|
class="category-item {{activeCategoryId === item.id ? 'active' : ''}}"
|
||||||
|
bindtap="chooseCategory"
|
||||||
|
data-id="{{item.id}}"
|
||||||
|
>
|
||||||
|
{{item.name}}
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
|
||||||
|
<view wx:for="{{products}}" wx:key="id" class="card" bindtap="goDetail" data-id="{{item.id}}">
|
||||||
|
<view class="row between">
|
||||||
|
<view>
|
||||||
|
<view>{{item.name}}</view>
|
||||||
|
<view class="muted">{{item.description || '社区精选商品'}}</view>
|
||||||
|
</view>
|
||||||
|
<view class="tag">{{item.status}}</view>
|
||||||
|
</view>
|
||||||
|
<view wx:if="{{item.skus.length}}" class="price">¥{{item.skus[0].priceCent / 100}} 起</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view wx:if="{{!products.length && !loading}}" class="card muted">暂无商品</view>
|
||||||
|
</view>
|
||||||
|
|||||||
@@ -1,3 +1,23 @@
|
|||||||
.page {
|
.category-scroll {
|
||||||
min-height: 100vh;
|
white-space: nowrap;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.category-item {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-width: 120rpx;
|
||||||
|
height: 64rpx;
|
||||||
|
padding: 0 20rpx;
|
||||||
|
margin-right: 12rpx;
|
||||||
|
background: #ffffff;
|
||||||
|
border: 1rpx solid #d9e0e8;
|
||||||
|
border-radius: 6rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.category-item.active {
|
||||||
|
color: #ffffff;
|
||||||
|
background: #0f766e;
|
||||||
|
border-color: #0f766e;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1,19 @@
|
|||||||
Page({})
|
Page({
|
||||||
|
data: {
|
||||||
|
user: null
|
||||||
|
},
|
||||||
|
|
||||||
|
onShow() {
|
||||||
|
const app = getApp()
|
||||||
|
this.setData({ user: app.globalData.user || null })
|
||||||
|
},
|
||||||
|
|
||||||
|
go(event) {
|
||||||
|
const url = event.currentTarget.dataset.url
|
||||||
|
if (event.currentTarget.dataset.tab) {
|
||||||
|
wx.switchTab({ url })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
wx.navigateTo({ url })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|||||||
@@ -1 +1,11 @@
|
|||||||
<view class="page">我的</view>
|
<view class="page">
|
||||||
|
<view class="card">
|
||||||
|
<view class="section-title">我的</view>
|
||||||
|
<view class="muted">邻小帮居民端</view>
|
||||||
|
</view>
|
||||||
|
<view class="card menu" bindtap="go" data-url="/pages/orders/index">我的订单</view>
|
||||||
|
<view class="card menu" bindtap="go" data-url="/pages/address/index">地址管理</view>
|
||||||
|
<view class="card menu" bindtap="go" data-url="/pages/express/create">代取快递</view>
|
||||||
|
<view class="card menu" bindtap="go" data-url="/pages/products/index">商品预定</view>
|
||||||
|
<view class="card menu" bindtap="go" data-url="/pages/notices/index">社区公告</view>
|
||||||
|
</view>
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
.page {
|
.menu {
|
||||||
min-height: 100vh;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1,52 @@
|
|||||||
Page({})
|
const { createSecondGoods } = require('../../api/secondGoodsApi')
|
||||||
|
const { setField } = require('../../utils/request')
|
||||||
|
|
||||||
|
Page({
|
||||||
|
data: {
|
||||||
|
submitting: false,
|
||||||
|
imageText: '',
|
||||||
|
form: {
|
||||||
|
title: '',
|
||||||
|
priceCent: 0,
|
||||||
|
description: '',
|
||||||
|
category: '',
|
||||||
|
contactPhone: '',
|
||||||
|
tradeMethod: 'FACE_TO_FACE',
|
||||||
|
imageUrls: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onFieldInput(event) {
|
||||||
|
setField(this, event)
|
||||||
|
},
|
||||||
|
|
||||||
|
onPriceInput(event) {
|
||||||
|
this.setData({ 'form.priceCent': Math.round(Number(event.detail.value || 0) * 100) })
|
||||||
|
},
|
||||||
|
|
||||||
|
onTradeMethodChange(event) {
|
||||||
|
this.setData({ 'form.tradeMethod': event.detail.value })
|
||||||
|
},
|
||||||
|
|
||||||
|
onImageInput(event) {
|
||||||
|
const imageText = event.detail.value
|
||||||
|
this.setData({
|
||||||
|
imageText,
|
||||||
|
'form.imageUrls': imageText ? imageText.split(',').map((item) => item.trim()).filter(Boolean) : []
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
submit() {
|
||||||
|
if (this.data.submitting) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.setData({ submitting: true })
|
||||||
|
createSecondGoods(this.data.form)
|
||||||
|
.then(() => {
|
||||||
|
wx.showToast({ title: '待审核' })
|
||||||
|
wx.navigateBack()
|
||||||
|
})
|
||||||
|
.catch((error) => wx.showToast({ title: error.message, icon: 'none' }))
|
||||||
|
.finally(() => this.setData({ submitting: false }))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|||||||
@@ -1 +1,16 @@
|
|||||||
<view class="page">发布闲置</view>
|
<view class="page">
|
||||||
|
<view class="section-title">发布闲置</view>
|
||||||
|
<view class="card">
|
||||||
|
<input class="input" placeholder="标题" data-field="title" bindinput="onFieldInput" />
|
||||||
|
<input class="input" placeholder="价格(元)" type="digit" bindinput="onPriceInput" />
|
||||||
|
<input class="input" placeholder="分类" data-field="category" bindinput="onFieldInput" />
|
||||||
|
<input class="input" placeholder="联系电话" data-field="contactPhone" bindinput="onFieldInput" />
|
||||||
|
<radio-group bindchange="onTradeMethodChange">
|
||||||
|
<label class="radio"><radio value="FACE_TO_FACE" checked="{{form.tradeMethod === 'FACE_TO_FACE'}}" />面交</label>
|
||||||
|
<label class="radio"><radio value="DELIVERY" checked="{{form.tradeMethod === 'DELIVERY'}}" />可配送</label>
|
||||||
|
</radio-group>
|
||||||
|
<input class="input" placeholder="图片 URL,多个用英文逗号分隔" value="{{imageText}}" bindinput="onImageInput" />
|
||||||
|
<textarea class="textarea" placeholder="描述" data-field="description" bindinput="onFieldInput" />
|
||||||
|
<button class="primary" loading="{{submitting}}" bindtap="submit">提交审核</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
.page {
|
.radio {
|
||||||
min-height: 100vh;
|
display: block;
|
||||||
|
height: 60rpx;
|
||||||
|
line-height: 60rpx;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1,37 @@
|
|||||||
Page({})
|
const { listSecondGoods } = require('../../api/secondGoodsApi')
|
||||||
|
|
||||||
|
Page({
|
||||||
|
data: {
|
||||||
|
loading: false,
|
||||||
|
goods: []
|
||||||
|
},
|
||||||
|
|
||||||
|
onLoad() {
|
||||||
|
this.load()
|
||||||
|
},
|
||||||
|
|
||||||
|
onShow() {
|
||||||
|
this.load()
|
||||||
|
},
|
||||||
|
|
||||||
|
load() {
|
||||||
|
this.setData({ loading: true })
|
||||||
|
listSecondGoods()
|
||||||
|
.then((goods) => this.setData({ goods: goods || [] }))
|
||||||
|
.catch((error) => wx.showToast({ title: error.message, icon: 'none' }))
|
||||||
|
.finally(() => this.setData({ loading: false }))
|
||||||
|
},
|
||||||
|
|
||||||
|
goCreate() {
|
||||||
|
wx.navigateTo({ url: '/pages/second-hand/create' })
|
||||||
|
},
|
||||||
|
|
||||||
|
callSeller(event) {
|
||||||
|
const phone = event.currentTarget.dataset.phone
|
||||||
|
if (!phone) {
|
||||||
|
wx.showToast({ title: '暂无电话', icon: 'none' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
wx.makePhoneCall({ phoneNumber: phone })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|||||||
@@ -1 +1,18 @@
|
|||||||
<view class="page">二手闲置</view>
|
<view class="page">
|
||||||
|
<view class="row between section">
|
||||||
|
<view class="section-title">二手闲置</view>
|
||||||
|
<button size="mini" class="primary" bindtap="goCreate">发布</button>
|
||||||
|
</view>
|
||||||
|
<view wx:for="{{goods}}" wx:key="id" class="card">
|
||||||
|
<view class="row between">
|
||||||
|
<view>
|
||||||
|
<view>{{item.title}}</view>
|
||||||
|
<view class="muted">{{item.category}} / {{item.tradeMethod}}</view>
|
||||||
|
</view>
|
||||||
|
<view class="price">¥{{item.priceCent / 100}}</view>
|
||||||
|
</view>
|
||||||
|
<view class="muted">{{item.description}}</view>
|
||||||
|
<button size="mini" class="ghost" data-phone="{{item.contactPhone}}" bindtap="callSeller">联系卖家</button>
|
||||||
|
</view>
|
||||||
|
<view wx:if="{{!goods.length && !loading}}" class="card muted">暂无闲置</view>
|
||||||
|
</view>
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
.page {
|
.ghost {
|
||||||
min-height: 100vh;
|
margin-top: 16rpx;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +1,90 @@
|
|||||||
function request(options) {
|
function ensureToken() {
|
||||||
const app = getApp()
|
const app = getApp()
|
||||||
const token = app.globalData.token
|
if (app.globalData.token) {
|
||||||
|
return Promise.resolve(app.globalData.token)
|
||||||
|
}
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
wx.request({
|
wx.request({
|
||||||
url: app.globalData.apiBaseUrl + options.url,
|
url: app.globalData.apiBaseUrl + '/api/auth/dev-miniapp-login',
|
||||||
method: options.method || 'GET',
|
method: 'POST',
|
||||||
data: options.data || {},
|
data: {
|
||||||
header: Object.assign({
|
username: 'resident'
|
||||||
Authorization: token
|
},
|
||||||
}, options.header || {}),
|
|
||||||
success(res) {
|
success(res) {
|
||||||
if (res.statusCode >= 200 && res.statusCode < 300 && res.data && res.data.code === 0) {
|
if (res.statusCode >= 200 && res.statusCode < 300 && res.data && res.data.code === 0) {
|
||||||
resolve(res.data.data)
|
app.globalData.token = res.data.data.token
|
||||||
|
app.globalData.user = res.data.data
|
||||||
|
resolve(app.globalData.token)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
reject(new Error((res.data && res.data.message) || '请求失败'))
|
reject(new Error((res.data && res.data.message) || '登录失败'))
|
||||||
},
|
},
|
||||||
fail: reject
|
fail: reject
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
function request(options) {
|
||||||
request
|
const app = getApp()
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
ensureToken().then((token) => {
|
||||||
|
wx.request({
|
||||||
|
url: app.globalData.apiBaseUrl + options.url,
|
||||||
|
method: options.method || 'GET',
|
||||||
|
data: options.data || {},
|
||||||
|
header: Object.assign({
|
||||||
|
Authorization: token,
|
||||||
|
satoken: token
|
||||||
|
}, options.header || {}),
|
||||||
|
success(res) {
|
||||||
|
if (res.statusCode >= 200 && res.statusCode < 300 && res.data && res.data.code === 0) {
|
||||||
|
resolve(res.data.data)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
reject(new Error((res.data && res.data.message) || '请求失败'))
|
||||||
|
},
|
||||||
|
fail: reject
|
||||||
|
})
|
||||||
|
}).catch(reject)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function yuan(cent) {
|
||||||
|
return ((cent || 0) / 100).toFixed(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
function statusText(status) {
|
||||||
|
const map = {
|
||||||
|
PENDING_CONFIRM: '待确认',
|
||||||
|
PREPARING: '备货中',
|
||||||
|
PENDING_DELIVERY: '待配送',
|
||||||
|
PENDING_PICKUP: '待自提',
|
||||||
|
DELIVERING: '配送中',
|
||||||
|
DELIVERED: '已送达',
|
||||||
|
COMPLETED: '已完成',
|
||||||
|
CANCELED: '已取消',
|
||||||
|
PENDING_REVIEW: '待审核',
|
||||||
|
PUBLISHED: '已发布',
|
||||||
|
REJECTED: '已驳回',
|
||||||
|
OFF_SHELF: '已下架',
|
||||||
|
SOLD: '已售出'
|
||||||
|
}
|
||||||
|
return map[status] || status || '-'
|
||||||
|
}
|
||||||
|
|
||||||
|
function setField(page, event) {
|
||||||
|
const field = event.currentTarget.dataset.field
|
||||||
|
if (!field) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
page.setData({
|
||||||
|
['form.' + field]: event.detail.value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
request,
|
||||||
|
yuan,
|
||||||
|
statusText,
|
||||||
|
setField
|
||||||
}
|
}
|
||||||
|
|||||||
16411
miniapp/package-lock.json
generated
Normal file
16411
miniapp/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user