feat(M08-C): 补管理员订单处置与代下单
This commit is contained in:
@@ -20,6 +20,17 @@ const orderStatusLabels = {
|
||||
REFUNDED: '已退款',
|
||||
CLOSED: '已关闭',
|
||||
}
|
||||
const orderActionsByStatus = {
|
||||
DRAFT: [{ action: 'SUBMIT', label: '提交订单' }, { action: 'CANCEL', label: '取消订单' }, { action: 'CLOSE', label: '关闭订单' }],
|
||||
PENDING_PAYMENT: [{ action: 'CANCEL', label: '取消订单' }, { action: 'CLOSE', label: '关闭订单' }],
|
||||
PAID: [{ action: 'RESERVE', label: '确认预留' }, { action: 'START', label: '开始使用' }, { action: 'CANCEL', label: '取消订单' }, { action: 'BEGIN_REFUND', label: '发起退款' }],
|
||||
RESERVED: [{ action: 'START', label: '开始使用' }, { action: 'CANCEL', label: '取消订单' }, { action: 'BEGIN_REFUND', label: '发起退款' }],
|
||||
IN_PROGRESS: [{ action: 'FINISH', label: '结束使用' }, { action: 'BEGIN_REFUND', label: '发起退款' }],
|
||||
FINISHED: [{ action: 'BEGIN_REFUND', label: '发起退款' }, { action: 'CLOSE', label: '关闭订单' }],
|
||||
CANCELLED: [{ action: 'BEGIN_REFUND', label: '发起退款' }, { action: 'CLOSE', label: '关闭订单' }],
|
||||
REFUNDING: [{ action: 'COMPLETE_REFUND', label: '确认退款完成' }],
|
||||
REFUNDED: [{ action: 'CLOSE', label: '关闭订单' }],
|
||||
}
|
||||
|
||||
Page({
|
||||
data: {
|
||||
@@ -32,7 +43,17 @@ Page({
|
||||
rooms: [],
|
||||
orders: [],
|
||||
visibleOrders: [],
|
||||
orderFilters: [
|
||||
{ value: '', label: '全部' },
|
||||
{ value: 'PENDING_PAYMENT', label: '待支付' },
|
||||
{ value: 'RESERVED', label: '待开始' },
|
||||
{ value: 'IN_PROGRESS', label: '进行中' },
|
||||
{ value: 'FINISHED', label: '已结束' },
|
||||
{ value: 'REFUNDING', label: '退款中' },
|
||||
],
|
||||
selectedOrderStatus: '',
|
||||
busyRoomId: '',
|
||||
busyOrderId: '',
|
||||
summary: {
|
||||
roomTotal: 0,
|
||||
available: 0,
|
||||
@@ -46,6 +67,10 @@ Page({
|
||||
await this.loadDashboard()
|
||||
},
|
||||
|
||||
async onShow() {
|
||||
if (this.data.selectedStoreId) await this.loadStoreData(this.data.selectedStoreId)
|
||||
},
|
||||
|
||||
async onPullDownRefresh() {
|
||||
await this.loadDashboard(this.data.selectedStoreId)
|
||||
wx.stopPullDownRefresh()
|
||||
@@ -60,10 +85,7 @@ Page({
|
||||
if (!access.roles.some((role) => managerRoles.includes(role))) {
|
||||
throw new Error('当前账号没有门店运营权限')
|
||||
}
|
||||
const [storesResponse, ordersResponse] = await Promise.all([
|
||||
request('/management/stores'),
|
||||
request('/orders?page=1&pageSize=50'),
|
||||
])
|
||||
const storesResponse = await request('/management/stores')
|
||||
const stores = storesResponse.data || []
|
||||
const selectedStoreId = stores.some((store) => store.id === preferredStoreId)
|
||||
? preferredStoreId
|
||||
@@ -73,11 +95,10 @@ Page({
|
||||
|| access.capabilities.includes('tenant.manage')
|
||||
|| access.roles.includes('PLATFORM_ADMIN'),
|
||||
stores,
|
||||
orders: (ordersResponse.data?.items || []).map((item) => this.presentOrder(item)),
|
||||
selectedStoreId,
|
||||
selectedStoreName: stores.find((store) => store.id === selectedStoreId)?.name || '',
|
||||
})
|
||||
await this.loadRooms(selectedStoreId)
|
||||
await this.loadStoreData(selectedStoreId)
|
||||
} catch (error) {
|
||||
this.setData({ errorMessage: error.message || '门店运营数据加载失败' })
|
||||
} finally {
|
||||
@@ -89,33 +110,54 @@ Page({
|
||||
const storeId = event.currentTarget.dataset.storeId
|
||||
if (!storeId || storeId === this.data.selectedStoreId) return
|
||||
const store = this.data.stores.find((item) => item.id === storeId)
|
||||
this.setData({ selectedStoreId: storeId, selectedStoreName: store?.name || '' })
|
||||
await this.loadRooms(storeId)
|
||||
this.setData({
|
||||
selectedStoreId: storeId,
|
||||
selectedStoreName: store?.name || '',
|
||||
selectedOrderStatus: '',
|
||||
})
|
||||
await this.loadStoreData(storeId)
|
||||
},
|
||||
|
||||
async loadRooms(storeId) {
|
||||
async loadStoreData(storeId) {
|
||||
if (!storeId) {
|
||||
this.setData({ rooms: [], visibleOrders: [] })
|
||||
this.setData({ rooms: [], orders: [], visibleOrders: [] })
|
||||
this.refreshSummary()
|
||||
return
|
||||
}
|
||||
try {
|
||||
const response = await request(`/management/stores/${encodeURIComponent(storeId)}/rooms`)
|
||||
const rooms = (response.data || []).map((item) => ({
|
||||
const encodedStoreId = encodeURIComponent(storeId)
|
||||
const [roomsResponse, ordersResponse] = await Promise.all([
|
||||
request(`/management/stores/${encodedStoreId}/rooms`),
|
||||
request(`/orders?page=1&pageSize=50&storeId=${encodedStoreId}`),
|
||||
])
|
||||
const rooms = (roomsResponse.data || []).map((item) => ({
|
||||
...item,
|
||||
statusText: roomStatusLabels[item.operationalStatus] || item.operationalStatus,
|
||||
priceText: cents(item.basePriceCents),
|
||||
}))
|
||||
this.setData({
|
||||
rooms,
|
||||
visibleOrders: this.data.orders.filter((item) => item.storeId === storeId),
|
||||
})
|
||||
const orders = (ordersResponse.data?.items || []).map((item) => this.presentOrder(item))
|
||||
this.setData({ rooms, orders })
|
||||
this.applyOrderFilter()
|
||||
this.refreshSummary()
|
||||
} catch (error) {
|
||||
this.setData({ errorMessage: error.message || '房态加载失败' })
|
||||
this.setData({ errorMessage: error.message || '门店运营数据加载失败' })
|
||||
}
|
||||
},
|
||||
|
||||
selectOrderFilter(event) {
|
||||
this.setData({ selectedOrderStatus: event.currentTarget.dataset.status || '' })
|
||||
this.applyOrderFilter()
|
||||
},
|
||||
|
||||
applyOrderFilter() {
|
||||
const status = this.data.selectedOrderStatus
|
||||
this.setData({
|
||||
visibleOrders: status
|
||||
? this.data.orders.filter((item) => item.status === status)
|
||||
: this.data.orders,
|
||||
})
|
||||
},
|
||||
|
||||
refreshSummary() {
|
||||
const rooms = this.data.rooms
|
||||
const activeStatuses = ['PAID', 'RESERVED', 'IN_PROGRESS']
|
||||
@@ -125,7 +167,7 @@ Page({
|
||||
available: rooms.filter((item) => item.configurationStatus === 'ENABLED' && item.operationalStatus === 'AVAILABLE').length,
|
||||
inUse: rooms.filter((item) => ['RESERVED', 'IN_USE'].includes(item.operationalStatus)).length,
|
||||
attention: rooms.filter((item) => item.configurationStatus === 'DISABLED' || ['MAINTENANCE', 'CLEANING_REQUIRED'].includes(item.operationalStatus)).length,
|
||||
activeOrders: this.data.visibleOrders.filter((item) => activeStatuses.includes(item.status)).length,
|
||||
activeOrders: this.data.orders.filter((item) => activeStatuses.includes(item.status)).length,
|
||||
},
|
||||
})
|
||||
},
|
||||
@@ -158,7 +200,7 @@ Page({
|
||||
method: 'PATCH',
|
||||
data: { storeId: this.data.selectedStoreId, ...status, reason },
|
||||
})
|
||||
await this.loadRooms(this.data.selectedStoreId)
|
||||
await this.loadStoreData(this.data.selectedStoreId)
|
||||
wx.showToast({ title: '房态已更新', icon: 'success' })
|
||||
} catch (error) {
|
||||
this.setData({ errorMessage: error.message || '房态更新失败' })
|
||||
@@ -167,10 +209,82 @@ Page({
|
||||
}
|
||||
},
|
||||
|
||||
openOrder(event) {
|
||||
createOrder() {
|
||||
if (!this.data.canWrite || !this.data.selectedStoreId) return
|
||||
wx.navigateTo({
|
||||
url: `/pages/manager/order-create?storeId=${encodeURIComponent(this.data.selectedStoreId)}&storeName=${encodeURIComponent(this.data.selectedStoreName)}`,
|
||||
})
|
||||
},
|
||||
|
||||
manageOrder(event) {
|
||||
if (!this.data.canWrite) return
|
||||
const orderId = event.currentTarget.dataset.orderId
|
||||
if (!orderId) return
|
||||
wx.navigateTo({ url: `/pages/orders/detail?orderId=${encodeURIComponent(orderId)}` })
|
||||
const status = event.currentTarget.dataset.status
|
||||
const actions = orderActionsByStatus[status] || []
|
||||
if (!actions.length) {
|
||||
wx.showToast({ title: '当前状态无可用动作', icon: 'none' })
|
||||
return
|
||||
}
|
||||
wx.showActionSheet({
|
||||
itemList: actions.map((item) => item.label),
|
||||
success: ({ tapIndex }) => {
|
||||
const selected = actions[tapIndex]
|
||||
wx.showModal({
|
||||
title: selected.label,
|
||||
content: `确认对订单执行“${selected.label}”吗?`,
|
||||
success: ({ confirm }) => {
|
||||
if (confirm) this.executeOrderAction(orderId, selected)
|
||||
},
|
||||
})
|
||||
},
|
||||
})
|
||||
},
|
||||
|
||||
addOrderNote(event) {
|
||||
if (!this.data.canWrite) return
|
||||
const orderId = event.currentTarget.dataset.orderId
|
||||
wx.showModal({
|
||||
title: '添加订单备注',
|
||||
editable: true,
|
||||
placeholderText: '请输入备注内容',
|
||||
success: ({ confirm, content }) => {
|
||||
const note = String(content || '').trim()
|
||||
if (confirm && note) this.saveOrderNote(orderId, note)
|
||||
},
|
||||
})
|
||||
},
|
||||
|
||||
async executeOrderAction(orderId, selected) {
|
||||
if (!orderId || this.data.busyOrderId) return
|
||||
this.setData({ busyOrderId: orderId, errorMessage: '' })
|
||||
try {
|
||||
await request(`/management/orders/${encodeURIComponent(orderId)}/actions`, {
|
||||
method: 'POST',
|
||||
data: { action: selected.action, reason: `管理员小程序:${selected.label}` },
|
||||
})
|
||||
await this.loadStoreData(this.data.selectedStoreId)
|
||||
wx.showToast({ title: '订单已更新', icon: 'success' })
|
||||
} catch (error) {
|
||||
this.setData({ errorMessage: error.message || '订单操作失败' })
|
||||
} finally {
|
||||
this.setData({ busyOrderId: '' })
|
||||
}
|
||||
},
|
||||
|
||||
async saveOrderNote(orderId, note) {
|
||||
if (!orderId || this.data.busyOrderId) return
|
||||
this.setData({ busyOrderId: orderId, errorMessage: '' })
|
||||
try {
|
||||
await request(`/management/orders/${encodeURIComponent(orderId)}/note`, {
|
||||
method: 'POST',
|
||||
data: { note },
|
||||
})
|
||||
wx.showToast({ title: '备注已保存', icon: 'success' })
|
||||
} catch (error) {
|
||||
this.setData({ errorMessage: error.message || '订单备注保存失败' })
|
||||
} finally {
|
||||
this.setData({ busyOrderId: '' })
|
||||
}
|
||||
},
|
||||
|
||||
presentOrder(item) {
|
||||
|
||||
Reference in New Issue
Block a user