Commit 345c09ee by puhui999

订单列表:列表重构 ② and 完善订单详情

parent 161feab2
import request from '@/config/axios'
export interface OrderVO {
id?: number // 订单编号
id?: number | null // 订单编号
no?: string // 订单流水号
createTime?: Date // 下单时间
type?: number // 订单类型
terminal?: number // 订单来源
userId?: number // 用户编号
createTime?: Date | null // 下单时间
type?: number | null // 订单类型
terminal?: number | null // 订单来源
userId?: number | null // 用户编号
userIp?: string // 用户 IP
userRemark?: string // 用户备注
status?: number // 订单状态
productCount?: number // 购买的商品数量
finishTime?: Date // 订单完成时间
cancelTime?: Date // 订单取消时间
cancelType?: number // 取消类型
status?: number | null // 订单状态
productCount?: number | null // 购买的商品数量
finishTime?: Date | null // 订单完成时间
cancelTime?: Date | null // 订单取消时间
cancelType?: number | null // 取消类型
remark?: string // 商家备注
payOrderId: number // 支付订单编号
payOrderId: number | null // 支付订单编号
payed?: boolean // 是否已支付
payTime?: Date // 付款时间
payTime?: Date | null // 付款时间
payChannelCode?: string // 支付渠道
originalPrice?: number // 商品原价(总)
orderPrice?: number // 订单原价(总)
discountPrice?: number // 订单优惠(总)
deliveryPrice?: number // 运费金额
adjustPrice?: number // 订单调价(总)
payPrice?: number // 应付金额(总)
deliveryType?: number // 发货方式
deliveryTemplateId?: number // 配送模板编号
logisticsId?: number // 发货物流公司编号
originalPrice?: number | null // 商品原价(总)
orderPrice?: number | null // 订单原价(总)
discountPrice?: number | null // 订单优惠(总)
deliveryPrice?: number | null // 运费金额
adjustPrice?: number | null // 订单调价(总)
payPrice?: number | null // 应付金额(总)
deliveryType?: number | null // 发货方式
deliveryTemplateId?: number | null // 配送模板编号
logisticsId?: number | null | null // 发货物流公司编号
logisticsNo?: string // 发货物流单号
deliveryStatus?: number // 发货状态
deliveryTime?: Date // 发货时间
receiveTime?: Date // 收货时间
deliveryStatus?: number | null // 发货状态
deliveryTime?: Date | null // 发货时间
receiveTime?: Date | null // 收货时间
receiverName?: string // 收件人名称
receiverMobile?: string // 收件人手机
receiverAreaId?: number // 收件人地区编号
receiverPostCode?: number // 收件人邮编
receiverAreaId?: number | null // 收件人地区编号
receiverPostCode?: number | null // 收件人邮编
receiverDetailAddress?: string // 收件人详细地址
afterSaleStatus?: number // 售后状态
refundPrice?: number // 退款金额
couponId?: number // 优惠劵编号
couponPrice?: number // 优惠劵减免金额
pointPrice?: number // 积分抵扣的金额
afterSaleStatus?: number | null // 售后状态
refundPrice?: number | null // 退款金额
couponId?: number | null // 优惠劵编号
couponPrice?: number | null // 优惠劵减免金额
pointPrice?: number | null // 积分抵扣的金额
receiverAreaName?: string //收件人地区名字
items?: OrderItemRespVO[] // 订单项列表
//用户信息
user?: {
id?: number
id?: number | null
nickname?: string
avatar?: string
}
......@@ -54,33 +54,33 @@ export interface OrderVO {
export interface OrderItemRespVO {
// ========== 订单项基本信息 ==========
id?: number // 编号
userId?: number // 用户编号
orderId?: number // 订单编号
id?: number | null // 编号
userId?: number | null // 用户编号
orderId?: number | null // 订单编号
// ========== 商品基本信息 ==========
spuId?: number // 商品 SPU 编号
spuId?: number | null // 商品 SPU 编号
spuName?: string //商品 SPU 名称
skuId?: number // 商品 SKU 编号
skuId?: number | null // 商品 SKU 编号
picUrl?: string //商品图片
count?: number //购买数量
count?: number | null //购买数量
// ========== 价格 + 支付基本信息 ==========
originalPrice?: number //商品原价(总)
originalUnitPrice?: number //商品原价(单)
discountPrice?: number //商品优惠(总)
payPrice?: number //商品实付金额(总)
orderPartPrice?: number //子订单分摊金额(总)
orderDividePrice?: number //分摊后子订单实付金额(总)
originalPrice?: number | null //商品原价(总)
originalUnitPrice?: number | null //商品原价(单)
discountPrice?: number | null //商品优惠(总)
payPrice?: number | null //商品实付金额(总)
orderPartPrice?: number | null //子订单分摊金额(总)
orderDividePrice?: number | null //分摊后子订单实付金额(总)
// ========== 营销基本信息 ==========
// TODO 芋艿:在捉摸一下
// ========== 售后基本信息 ==========
afterSaleStatus?: number // 售后状态
afterSaleStatus?: number | null // 售后状态
properties?: ProductPropertiesVO[] //属性数组
}
export interface ProductPropertiesVO {
propertyId?: number // 属性的编号
propertyId?: number | null // 属性的编号
propertyName?: string // 属性的名称
valueId?: number //属性值的编号
valueId?: number | null //属性值的编号
valueName?: string // 属性值的名称
}
......@@ -90,8 +90,8 @@ export const getOrderPage = async (params) => {
}
// 查询交易订单详情
export const getOrder = async (id: number) => {
return await request.get({ url: `/trade/order/get?id=` + id })
export const getOrder = async (id: number | null) => {
return await request.get({ url: `/trade/order/get-detail?id=` + id })
}
// 新增交易订单
......@@ -105,6 +105,6 @@ export const updateOrder = async (data: OrderVO) => {
}
// 删除交易订单
export const deleteOrder = async (id: number) => {
export const deleteOrder = async (id: number | null) => {
return await request.delete({ url: `/trade/order/delete?id=` + id })
}
......@@ -5,32 +5,32 @@ const { t } = useI18n()
* redirect: noredirect 当设置 noredirect 的时候该路由在面包屑导航中不可被点击
* name:'router-name' 设定路由的名字,一定要填写不然使用<keep-alive>时会出现各种问题
* meta : {
hidden: true 当设置 true 的时候该路由不会再侧边栏出现 如404,login等页面(默认 false)
hidden: true 当设置 true 的时候该路由不会再侧边栏出现 如404,login等页面(默认 false)
alwaysShow: true 当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式,
只有一个时,会将那个子路由当做根路由显示在侧边栏,
若你想不管路由下面的 children 声明的个数都显示你的根路由,
你可以设置 alwaysShow: true,这样它就会忽略之前定义的规则,
一直显示根路由(默认 false)
alwaysShow: true 当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式,
只有一个时,会将那个子路由当做根路由显示在侧边栏,
若你想不管路由下面的 children 声明的个数都显示你的根路由,
你可以设置 alwaysShow: true,这样它就会忽略之前定义的规则,
一直显示根路由(默认 false)
title: 'title' 设置该路由在侧边栏和面包屑中展示的名字
title: 'title' 设置该路由在侧边栏和面包屑中展示的名字
icon: 'svg-name' 设置该路由的图标
icon: 'svg-name' 设置该路由的图标
noCache: true 如果设置为true,则不会被 <keep-alive> 缓存(默认 false)
noCache: true 如果设置为true,则不会被 <keep-alive> 缓存(默认 false)
breadcrumb: false 如果设置为false,则不会在breadcrumb面包屑中显示(默认 true)
breadcrumb: false 如果设置为false,则不会在breadcrumb面包屑中显示(默认 true)
affix: true 如果设置为true,则会一直固定在tag项中(默认 false)
affix: true 如果设置为true,则会一直固定在tag项中(默认 false)
noTagsView: true 如果设置为true,则不会出现在tag中(默认 false)
noTagsView: true 如果设置为true,则不会出现在tag中(默认 false)
activeMenu: '/dashboard' 显示高亮的路由路径
activeMenu: '/dashboard' 显示高亮的路由路径
followAuth: '/dashboard' 跟随哪个路由进行权限过滤
followAuth: '/dashboard' 跟随哪个路由进行权限过滤
canTo: true 设置为true即使hidden为true,也依然可以进行路由跳转(默认 false)
}
canTo: true 设置为true即使hidden为true,也依然可以进行路由跳转(默认 false)
}
**/
const remainingRouter: AppRouteRecordRaw[] = [
{
......@@ -349,7 +349,7 @@ const remainingRouter: AppRouteRecordRaw[] = [
{
path: '/property',
component: Layout,
name: 'property',
name: 'Property',
meta: {
hidden: true
},
......@@ -412,6 +412,22 @@ const remainingRouter: AppRouteRecordRaw[] = [
]
},
{
path: '/trade/order',
component: Layout,
name: 'Detail',
meta: {
hidden: true
},
children: [
{
path: 'detail/:orderId(\\d+)',
component: () => import('@/views/mall/trade/order/detail/index.vue'),
name: 'TradeOrderDetailForm',
meta: { title: '订单详情', icon: '', activeMenu: '/trade/trade/order' }
}
]
},
{
path: '/pay',
component: Layout,
name: 'pay',
......
......@@ -130,7 +130,7 @@ export enum DICT_TYPE {
BPM_OA_LEAVE_TYPE = 'bpm_oa_leave_type',
// ========== PAY 模块 ==========
PAY_CHANNEL_CODE = 'pay_channel_code', // 支付渠道编码类型
PAY_CHANNEL_CODE_TYPE = 'pay_channel_code_type', // 支付渠道编码类型
PAY_ORDER_STATUS = 'pay_order_status', // 商户支付订单状态
PAY_REFUND_STATUS = 'pay_refund_status', // 退款订单状态
PAY_NOTIFY_STATUS = 'pay_notify_status', // 商户支付回调状态
......
......@@ -111,20 +111,31 @@
<el-table-column fixed="left" type="expand">
<template #default="scope">
<el-table :data="scope.row.items" :span-method="spanMethod" border style="width: 100%">
<el-table-column label="商品" prop="spuName">
<el-table-column label="商品信息" min-width="300" prop="spuName">
<template #default="{ row }">
{{ row.spuName }}
<el-tag v-for="property in row.properties" :key="property.propertyId">
{{ property.propertyName }}: {{ property.valueName }}
</el-tag>
<div class="flex items-center">
<el-image
:src="row.picUrl"
class="w-30px h-30px mr-10px"
@click="imagePreview(row.picUrl)"
/>
<span class="mr-10px">{{ row.spuName }}</span>
<el-tag
v-for="property in row.properties"
:key="property.propertyId"
class="mr-10px"
>
{{ property.propertyName }}: {{ property.valueName }}
</el-tag>
</div>
</template>
</el-table-column>
<el-table-column label="商品原价(元)" prop="price" width="150">
<template #default="{ row }">{{ formatToFraction(row.price) }}</template>
<el-table-column label="商品原价" prop="price" width="150">
<template #default="{ row }">{{ formatToFraction(row.price) }}</template>
</el-table-column>
<el-table-column label="数量" prop="count" width="100" />
<el-table-column label="合计(元)" prop="payPrice" width="150">
<template #default="{ row }">{{ formatToFraction(row.payPrice) }}</template>
<el-table-column label="合计" prop="payPrice" width="150">
<template #default="{ row }">{{ formatToFraction(row.payPrice) }}</template>
</el-table-column>
<el-table-column label="售后状态" prop="afterSaleStatus" width="120">
<template #default="{ row }">
......@@ -134,22 +145,33 @@
/>
</template>
</el-table-column>
<el-table-column align="center" label="实际支付(元)" min-width="120" prop="payPrice">
<el-table-column align="center" label="实际支付" min-width="120" prop="payPrice">
<template #default>
{{ formatToFraction(scope.row.payPrice) + '元' }}
</template>
</el-table-column>
<el-table-column label="买家/收货人" min-width="120">
<template #default>
<div class="flex flex-col">
<span>买家:{{ scope.row.user.nickname }}</span>
<span>
收货人:{{ scope.row.receiverName }} {{ scope.row.receiverMobile }}
{{ scope.row.receiverAreaName }} {{ scope.row.receiverDetailAddress }}
</span>
</div>
</template>
</el-table-column>
<el-table-column align="center" label="配送方式" prop="deliveryType" width="120">
<template #default> 快递</template>
</el-table-column>
<el-table-column align="center" fixed="right" label="操作" width="160">
<template #default="{ row }">
<template #default>
<div class="flex justify-center items-center">
<el-button link type="primary" @click="openForm">
<el-button link type="primary" @click="openForm(scope.row.id)">
<Icon icon="ep:notification" />
详情
</el-button>
<el-dropdown @command="(command) => handleCommand(command, row)">
<el-dropdown @command="(command) => handleCommand(command, scope.row)">
<el-button link type="primary">
<Icon icon="ep:d-arrow-right" />
更多
......@@ -187,13 +209,6 @@
<dict-tag :type="DICT_TYPE.TRADE_ORDER_TYPE" :value="row.type" />
</template>
</el-table-column>
<el-table-column align="center" label="用户信息" min-width="100">
<template #default="{ row }">
<el-button link type="primary">
{{ row.userId }}{{ '[' + row.user.nickname + ']' }}
</el-button>
</template>
</el-table-column>
<el-table-column align="center" label="订单来源" min-width="145">
<template #default="{ row }">
<dict-tag v-if="row.terminal" :type="DICT_TYPE.TERMINAL" :value="row.terminal" />
......@@ -242,28 +257,26 @@
@pagination="getList"
/>
</ContentWrap>
<TradeOrderDetailForm ref="tradeOrderDetailFormRef" />
</template>
<script lang="ts" name="Order" setup>
import TradeOrderDetailForm from './detail/index.vue'
import type { FormInstance, TableColumnCtx } from 'element-plus'
import { dateFormatter } from '@/utils/formatTime'
import * as TradeOrderApi from '@/api/mall/trade/order'
import { OrderItemRespVO, OrderVO } from '@/api/mall/trade/order'
import { DICT_TYPE, getStrDictOptions } from '@/utils/dict'
import { formatToFraction } from '@/utils'
import { testData } from './testData'
import { createImageViewer } from '@/components/ImageViewer'
// const message = useMessage() // 消息弹窗
// const { t } = useI18n() // 国际化
const { currentRoute, push } = useRouter() // 路由跳转
const loading = ref(true) // 列表的加载中
const total = ref(2) // 列表的总页数
const list = ref<OrderVO[]>([]) // 列表的数据
const tradeOrderDetailFormRef = ref<InstanceType<typeof TradeOrderDetailForm>>()
const openForm = () => {
tradeOrderDetailFormRef.value?.open()
const openForm = (id) => {
push('/trade/order/detail/' + id)
}
/** 商品图预览 */
const imagePreview = (imgUrl: string) => {
......@@ -280,7 +293,7 @@ interface SpanMethodProps {
}
const spanMethod = ({ rowIndex, columnIndex }: SpanMethodProps) => {
const colIndex = [5, 6, 7]
const colIndex = [5, 6, 7, 8]
// 处理列
if (colIndex.includes(columnIndex)) {
// 处理被合并的行
......@@ -348,9 +361,18 @@ const searchList = ref([
const getList = async () => {
loading.value = true
try {
// const data = await TradeOrderApi.getOrderPage(queryParams)
// list.value = data.list
// total.value = data.total
const data = await TradeOrderApi.getOrderPage(queryParams)
const list_ = data.list as OrderVO[]
// TODO 测试使用
list_.forEach((item) => {
item.user = {
id: 247,
nickname: '小妮子'
}
})
list.value = list_
total.value = data.total
} finally {
loading.value = false
}
......@@ -368,9 +390,17 @@ const resetQuery = () => {
handleQuery()
}
// 监听路由变化更新列表,解决商品保存后,列表不刷新的问题。
watch(
() => currentRoute.value,
() => {
getList()
}
)
/** 初始化 **/
onMounted(() => {
list.value = testData
// list.value = testData
getList()
})
</script>
......@@ -18,7 +18,7 @@ export const testData: OrderVO = [
remark: '',
payOrderId: 10002,
payed: false,
payTime: null,
payTime: new Date('2023-08-17T12:30:00'),
payChannelCode: 'wx_app',
originalPrice: 80,
orderPrice: 80,
......@@ -32,26 +32,27 @@ export const testData: OrderVO = [
deliveryStatus: 0,
deliveryTime: null,
receiveTime: null,
receiverName: 'Jane Smith',
receiverMobile: '987-654-3210',
receiverName: '李四',
receiverMobile: '19855568989',
receiverAreaId: 4002,
receiverPostCode: 54321,
receiverDetailAddress: '456 Elm St, Apt 2C',
receiverDetailAddress: '翻斗花园',
afterSaleStatus: 0,
refundPrice: 0,
couponId: null,
couponPrice: 0,
pointPrice: 0,
receiverAreaName: 'Townsville',
receiverAreaName: '北京市朝阳区',
items: [
{
id: 103,
userId: 1002,
orderId: 2,
spuId: 5003,
spuName: 'Widget C',
spuName: '毛绒鸭子',
skuId: 6003,
picUrl: 'https://example.com/images/widget_c.jpg',
picUrl:
'http://127.0.0.1:48080/admin-api/infra/file/5/get/20220723041544165856414464011_BIG.jpg',
count: 1,
originalPrice: 40,
originalUnitPrice: 40,
......@@ -61,8 +62,8 @@ export const testData: OrderVO = [
orderDividePrice: 40,
afterSaleStatus: 0,
properties: [
{ propertyId: 7001, propertyName: 'Color', valueId: 8004, valueName: 'Green' },
{ propertyId: 7002, propertyName: 'Size', valueId: 8002, valueName: 'Medium' }
{ propertyId: 7001, propertyName: '颜色', valueId: 8004, valueName: '黄色' },
{ propertyId: 7002, propertyName: '尺寸', valueId: 8002, valueName: '小鸭子' }
]
},
{
......@@ -70,9 +71,10 @@ export const testData: OrderVO = [
userId: 1002,
orderId: 2,
spuId: 5004,
spuName: 'Widget D',
spuName: '毛绒鸭子',
skuId: 6004,
picUrl: 'https://example.com/images/widget_d.jpg',
picUrl:
'http://127.0.0.1:48080/admin-api/infra/file/5/get/20220723041544165856414464011_BIG.jpg',
count: 1,
originalPrice: 40,
originalUnitPrice: 40,
......@@ -82,14 +84,14 @@ export const testData: OrderVO = [
orderDividePrice: 40,
afterSaleStatus: 0,
properties: [
{ propertyId: 7003, propertyName: 'Color', valueId: 8005, valueName: 'Yellow' },
{ propertyId: 7002, propertyName: 'Size', valueId: 8002, valueName: 'Medium' }
{ propertyId: 7001, propertyName: '颜色', valueId: 8004, valueName: '黄色' },
{ propertyId: 7002, propertyName: '尺寸', valueId: 8002, valueName: '大鸭子' }
]
}
],
user: {
id: 1002,
nickname: 'janesmith',
nickname: '小妮子',
avatar: 'https://example.com/images/avatar.jpg'
}
},
......@@ -124,26 +126,26 @@ export const testData: OrderVO = [
deliveryStatus: 2,
deliveryTime: new Date('2023-08-18T10:30:00'),
receiveTime: new Date('2023-08-19T11:30:00'),
receiverName: 'Sarah Johnson',
receiverMobile: '555-123-4567',
receiverName: '张三',
receiverMobile: '13988886656',
receiverAreaId: 4003,
receiverPostCode: 67890,
receiverDetailAddress: '789 Oak Ave',
receiverDetailAddress: '成华大道',
afterSaleStatus: 0,
refundPrice: 0,
couponId: 2001,
couponPrice: 5,
pointPrice: 0,
receiverAreaName: 'Villageville',
receiverAreaName: '四川省成都市',
items: [
{
id: 105,
userId: 1003,
orderId: 3,
spuId: 5005,
spuName: 'Widget E',
spuName: '华为',
skuId: 6005,
picUrl: 'https://example.com/images/widget_e.jpg',
picUrl: 'http://127.0.0.1:48080/admin-api/infra/file/5/get/sj.jpg',
count: 1,
originalPrice: 20,
originalUnitPrice: 20,
......@@ -153,14 +155,14 @@ export const testData: OrderVO = [
orderDividePrice: 15,
afterSaleStatus: 0,
properties: [
{ propertyId: 7001, propertyName: 'Color', valueId: 8006, valueName: 'Black' },
{ propertyId: 7002, propertyName: 'Size', valueId: 8002, valueName: 'Medium' }
{ propertyId: 7001, propertyName: '颜色', valueId: 8006, valueName: '紫色' },
{ propertyId: 7002, propertyName: '选配', valueId: 8002, valueName: '标配' }
]
}
],
user: {
id: 1003,
nickname: 'sarahjohnson',
nickname: '无敌最俊朗',
avatar: 'https://example.com/images/avatar.jpg'
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment