322 lines
8.2 KiB
JavaScript
322 lines
8.2 KiB
JavaScript
import { defineStore } from 'pinia'
|
|
import { ref, computed } from 'vue'
|
|
|
|
// 订单状态枚举
|
|
export const ORDER_STATUS = {
|
|
PENDING: 'pending',
|
|
PROCESSING: 'processing',
|
|
SHIPPED: 'shipped',
|
|
delivered: 'Shipped',
|
|
CANCELLED: 'cancelled',
|
|
REFUNDED: 'refunded'
|
|
}
|
|
|
|
// 订单状态标签
|
|
export const STATUS_LABELS = {
|
|
[ORDER_STATUS.PENDING]: '待处理',
|
|
[ORDER_STATUS.PROCESSING]: '处理中',
|
|
[ORDER_STATUS.SHIPPED]: '已发货',
|
|
[ORDER_STATUS.DELIVERED]: '已送达',
|
|
[ORDER_STATUS.CANCELLED]: '已取消',
|
|
[ORDER_STATUS.REFUNDED]: '已退款'
|
|
}
|
|
|
|
// 订单状态颜色
|
|
export const STATUS_COLORS = {
|
|
[ORDER_STATUS.PENDING]: '#f59e0b',
|
|
[ORDER_STATUS.PROCESSING]: '#3b82f6',
|
|
[ORDER_STATUS.SHIPPED]: '#8b5cf6',
|
|
[ORDER_STATUS.DELIVERED]: '#10b981',
|
|
[ORDER_STATUS.CANCELLED]: '#ef4444',
|
|
[ORDER_STATUS.REFUNDED]: '#6b7280'
|
|
}
|
|
|
|
export const useOrderStore = defineStore('orders', () => {
|
|
// 状态定义
|
|
const orders = ref([])
|
|
const currentOrder = ref(null)
|
|
const loading = ref(false)
|
|
const error = ref(null)
|
|
|
|
// 筛选和搜索状态
|
|
const filters = ref({
|
|
status: null,
|
|
search: '',
|
|
sortBy: 'created_at',
|
|
sortOrder: 'desc',
|
|
dateRange: null
|
|
})
|
|
|
|
// 分页状态
|
|
const pagination = ref({
|
|
currentPage: 1,
|
|
pageSize: 10,
|
|
total: 0
|
|
})
|
|
|
|
// 计算属性
|
|
const filteredOrders = computed(() => {
|
|
let result = [...orders.value]
|
|
|
|
// 状态筛选
|
|
if (filters.value.status) {
|
|
result = result.filter(order => order.status === filters.value.status)
|
|
}
|
|
|
|
// 搜索筛选
|
|
if (filters.value.search) {
|
|
const searchLower = filters.value.search.toLowerCase()
|
|
result = result.filter(order =>
|
|
order.orderId?.toLowerCase().includes(searchLower) ||
|
|
order.customerName?.toLowerCase().includes(searchLower) ||
|
|
order.customerEmail?.toLowerCase().includes(searchLower)
|
|
)
|
|
}
|
|
|
|
// 日期范围筛选
|
|
if (filters.value.dateRange?.start && filters.value.dateRange?.end) {
|
|
const start = new Date(filters.value.dateRange.start)
|
|
const end = new Date(filters.value.dateRange.end)
|
|
result = result.filter(order => {
|
|
const orderDate = new Date(order.created_at)
|
|
return orderDate >= start && orderDate <= end
|
|
})
|
|
}
|
|
|
|
// 排序
|
|
result.sort((a, b) => {
|
|
const { sortBy, sortOrder } = filters.value
|
|
let aVal = a[sortBy]
|
|
let bVal = b[sortBy]
|
|
|
|
// 处理日期排序
|
|
if (sortBy === 'created_at' || sortBy === 'updatedAt') {
|
|
aVal = new Date(aVal).getTime()
|
|
bVal = new Date(bVal).getTime()
|
|
}
|
|
|
|
// 处理字符串排序
|
|
if (typeof aVal === 'string') {
|
|
aVal = aVal.toLowerCase()
|
|
bVal = bVal.toLowerCase()
|
|
}
|
|
|
|
if (sortOrder === 'asc') {
|
|
return aVal > bVal ? 1 : -1
|
|
} else {
|
|
return aVal < bVal ? 1 : -1
|
|
}
|
|
})
|
|
|
|
return result
|
|
})
|
|
|
|
// 分页后的订单列表
|
|
const paginatedOrders = computed(() => {
|
|
const { currentPage, pageSize } = pagination.value
|
|
const start = (currentPage - 1) * pageSize
|
|
const end = start + pageSize
|
|
return filteredOrders.value.slice(start, end)
|
|
})
|
|
|
|
// 订单统计
|
|
const orderStats = computed(() => {
|
|
const total = orders.value.length
|
|
const pending = orders.value.filter(o => o.status === ORDER_STATUS.PENDING).length
|
|
const processing = orders.value.filter(o => o.status === ORDER_STATUS.PROCESSING).length
|
|
const shipped = orders.value.filter(o => o.status === ORDER_STATUS.SHIPPED).length
|
|
const delivered = orders.value.filter(o => o.status === ORDER_STATUS.DELIVERED).length
|
|
const cancelled = orders.value.filter(o => o.status === ORDER_STATUS.CANCELLED).length
|
|
const refunded = orders.value.filter(o => o.status === ORDER_STATUS.REFUNDED).length
|
|
|
|
const totalRevenue = orders.value
|
|
.filter(o => o.status !== ORDER_STATUS.CANCELLED)
|
|
.reduce((sum, order) => sum + (order.total || 0), 0)
|
|
|
|
return {
|
|
total,
|
|
pending,
|
|
processing,
|
|
shipped,
|
|
delivered,
|
|
cancelled,
|
|
refunded,
|
|
totalRevenue
|
|
}
|
|
})
|
|
|
|
// 获取订单总数(用于分页)
|
|
const totalOrders = computed(() => filteredOrders.value.length)
|
|
|
|
// 方法定义
|
|
|
|
// 设置订单数据
|
|
const setOrders = (orderList) => {
|
|
orders.value = orderList.map(order => ({
|
|
...order,
|
|
created_at: order.created_at || new Date().toISOString(),
|
|
updatedAt: order.updatedAt || new Date().toISOString()
|
|
}))
|
|
pagination.value.total = orders.value.length
|
|
}
|
|
|
|
// 添加订单
|
|
const addOrder = (order) => {
|
|
const newOrder = {
|
|
...order,
|
|
id: Date.now().toString(),
|
|
created_at: new Date().toISOString(),
|
|
updatedAt: new Date().toISOString(),
|
|
status: order.status || ORDER_STATUS.PENDING
|
|
}
|
|
orders.value.unshift(newOrder)
|
|
pagination.value.total = orders.value.length
|
|
return newOrder
|
|
}
|
|
|
|
// 更新订单
|
|
const updateOrder = (orderId, updates) => {
|
|
const index = orders.value.findIndex(order => order.id === orderId)
|
|
if (index !== -1) {
|
|
orders.value[index] = {
|
|
...orders.value[index],
|
|
...updates,
|
|
updatedAt: new Date().toISOString()
|
|
}
|
|
}
|
|
return orders.value[index]
|
|
}
|
|
|
|
// 删除订单
|
|
const deleteOrder = (orderId) => {
|
|
const index = orders.value.findIndex(order => order.id === orderId)
|
|
if (index !== -1) {
|
|
orders.value.splice(index, 1)
|
|
pagination.value.total = orders.value.length
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
// 获取单个订单
|
|
const getOrder = (orderId) => {
|
|
return orders.value.find(order => order.id === orderId)
|
|
}
|
|
|
|
// 设置当前订单
|
|
const setCurrentOrder = (order) => {
|
|
currentOrder.value = order
|
|
}
|
|
|
|
// 更新订单状态
|
|
const updateOrderStatus = (orderId, newStatus) => {
|
|
return updateOrder(orderId, {
|
|
status: newStatus,
|
|
statusHistory: [
|
|
...(orders.value.find(o => o.id === orderId)?.statusHistory || []),
|
|
{
|
|
status: newStatus,
|
|
timestamp: new Date().toISOString(),
|
|
note: `状态更新为 ${STATUS_LABELS[newStatus]}`
|
|
}
|
|
]
|
|
})
|
|
}
|
|
|
|
// 更新筛选条件
|
|
const updateFilters = (newFilters) => {
|
|
filters.value = { ...filters.value, ...newFilters }
|
|
pagination.value.currentPage = 1 // 重置到第一页
|
|
}
|
|
|
|
// 更新分页
|
|
const updatePagination = (newPagination) => {
|
|
pagination.value = { ...pagination.value, ...newPagination }
|
|
}
|
|
|
|
// 重置筛选
|
|
const resetFilters = () => {
|
|
filters.value = {
|
|
status: null,
|
|
search: '',
|
|
sortBy: 'created_at',
|
|
sortOrder: 'desc',
|
|
dateRange: null
|
|
}
|
|
pagination.value.currentPage = 1
|
|
}
|
|
|
|
// 获取状态历史
|
|
const getStatusHistory = (orderId) => {
|
|
const order = getOrder(orderId)
|
|
return order?.statusHistory || []
|
|
}
|
|
|
|
// 导出订单数据
|
|
const exportOrders = (format = 'json') => {
|
|
const data = filteredOrders.value
|
|
|
|
if (format === 'csv') {
|
|
// 转换为CSV格式
|
|
const headers = ['订单ID', '客户姓名', '客户邮箱', '状态', '总金额', '创建时间', '更新时间']
|
|
const csvRows = [
|
|
headers.join(','),
|
|
...data.map(order => [
|
|
order.orderId || '',
|
|
order.customerName || '',
|
|
order.customerEmail || '',
|
|
STATUS_LABELS[order.status] || '',
|
|
order.total || 0,
|
|
order.created_at,
|
|
order.updatedAt
|
|
].join(','))
|
|
]
|
|
return csvRows.join('\n')
|
|
}
|
|
|
|
return JSON.stringify(data, null, 2)
|
|
}
|
|
|
|
// 初始化示例数据(用于测试)
|
|
const initSampleData = () => {
|
|
const sampleOrders = []
|
|
setOrders(sampleOrders)
|
|
}
|
|
|
|
return {
|
|
// 状态
|
|
orders,
|
|
currentOrder,
|
|
loading,
|
|
error,
|
|
filters,
|
|
pagination,
|
|
|
|
// 计算属性
|
|
filteredOrders,
|
|
paginatedOrders,
|
|
orderStats,
|
|
totalOrders,
|
|
|
|
// 方法
|
|
setOrders,
|
|
addOrder,
|
|
updateOrder,
|
|
deleteOrder,
|
|
getOrder,
|
|
setCurrentOrder,
|
|
updateOrderStatus,
|
|
updateFilters,
|
|
updatePagination,
|
|
resetFilters,
|
|
getStatusHistory,
|
|
exportOrders,
|
|
initSampleData
|
|
}
|
|
}, {
|
|
persist: {
|
|
key: 'orders',
|
|
storage: localStorage,
|
|
paths: ['filters', 'pagination']
|
|
}
|
|
}) |