mirror of
				https://gitee.com/hhyykk/ipms-sjy-ui.git
				synced 2025-10-31 18:28:44 +08:00 
			
		
		
		
	订单列表:列表重构 ①
This commit is contained in:
		| @@ -1,12 +1,110 @@ | ||||
| import request from '@/config/axios' | ||||
|  | ||||
| // 获得交易订单分页 | ||||
| // TODO @xiaobai:改成 getOrderPage | ||||
| export const getOrderList = (params: PageParam) => { | ||||
|   return request.get({ url: '/trade/order/page', params }) | ||||
| export interface OrderVO { | ||||
|   id?: number // 订单编号 | ||||
|   no?: string // 订单流水号 | ||||
|   createTime?: Date // 下单时间 | ||||
|   type?: number // 订单类型 | ||||
|   terminal?: number // 订单来源 | ||||
|   userId?: number // 用户编号 | ||||
|   userIp?: string // 用户 IP | ||||
|   userRemark?: string // 用户备注 | ||||
|   status?: number // 订单状态 | ||||
|   productCount?: number // 购买的商品数量 | ||||
|   finishTime?: Date // 订单完成时间 | ||||
|   cancelTime?: Date // 订单取消时间 | ||||
|   cancelType?: number // 取消类型 | ||||
|   remark?: string // 商家备注 | ||||
|   payOrderId: number // 支付订单编号 | ||||
|   payed?: boolean // 是否已支付 | ||||
|   payTime?: Date // 付款时间 | ||||
|   payChannelCode?: string // 支付渠道 | ||||
|   originalPrice?: number // 商品原价(总) | ||||
|   orderPrice?: number // 订单原价(总) | ||||
|   discountPrice?: number // 订单优惠(总) | ||||
|   deliveryPrice?: number // 运费金额 | ||||
|   adjustPrice?: number // 订单调价(总) | ||||
|   payPrice?: number // 应付金额(总) | ||||
|   deliveryType?: number // 发货方式 | ||||
|   deliveryTemplateId?: number // 配送模板编号 | ||||
|   logisticsId?: number // 发货物流公司编号 | ||||
|   logisticsNo?: string // 发货物流单号 | ||||
|   deliveryStatus?: number // 发货状态 | ||||
|   deliveryTime?: Date // 发货时间 | ||||
|   receiveTime?: Date // 收货时间 | ||||
|   receiverName?: string // 收件人名称 | ||||
|   receiverMobile?: string // 收件人手机 | ||||
|   receiverAreaId?: number // 收件人地区编号 | ||||
|   receiverPostCode?: number // 收件人邮编 | ||||
|   receiverDetailAddress?: string // 收件人详细地址 | ||||
|   afterSaleStatus?: number // 售后状态 | ||||
|   refundPrice?: number // 退款金额 | ||||
|   couponId?: number // 优惠劵编号 | ||||
|   couponPrice?: number // 优惠劵减免金额 | ||||
|   pointPrice?: number // 积分抵扣的金额 | ||||
|   receiverAreaName?: string //收件人地区名字 | ||||
|   items?: OrderItemRespVO[] // 订单项列表 | ||||
|   //用户信息 | ||||
|   user?: { | ||||
|     id?: number | ||||
|     nickname?: string | ||||
|     avatar?: string | ||||
|   } | ||||
| } | ||||
|  | ||||
| // 获得交易订单详情 | ||||
| export const getOrderDetail = (id: number) => { | ||||
|   return request.get({ url: '/trade/order/get-detail?id=' + id }) | ||||
| export interface OrderItemRespVO { | ||||
|   // ========== 订单项基本信息 ========== | ||||
|   id?: number // 编号 | ||||
|   userId?: number // 用户编号 | ||||
|   orderId?: number // 订单编号 | ||||
|   // ========== 商品基本信息 ========== | ||||
|   spuId?: number // 商品 SPU 编号 | ||||
|   spuName?: string //商品 SPU 名称 | ||||
|   skuId?: number // 商品 SKU 编号 | ||||
|   picUrl?: string //商品图片 | ||||
|   count?: number //购买数量 | ||||
|   // ========== 价格 + 支付基本信息 ========== | ||||
|   originalPrice?: number //商品原价(总) | ||||
|   originalUnitPrice?: number //商品原价(单) | ||||
|   discountPrice?: number //商品优惠(总) | ||||
|   payPrice?: number //商品实付金额(总) | ||||
|   orderPartPrice?: number //子订单分摊金额(总) | ||||
|   orderDividePrice?: number //分摊后子订单实付金额(总) | ||||
|   // ========== 营销基本信息 ========== | ||||
|   // TODO 芋艿:在捉摸一下 | ||||
|   // ========== 售后基本信息 ========== | ||||
|   afterSaleStatus?: number // 售后状态 | ||||
|   properties?: ProductPropertiesVO[] //属性数组 | ||||
| } | ||||
|  | ||||
| export interface ProductPropertiesVO { | ||||
|   propertyId?: number // 属性的编号 | ||||
|   propertyName?: string // 属性的名称 | ||||
|   valueId?: number //属性值的编号 | ||||
|   valueName?: string // 属性值的名称 | ||||
| } | ||||
|  | ||||
| // 查询交易订单列表 | ||||
| export const getOrderPage = async (params) => { | ||||
|   return await request.get({ url: `/trade/order/page`, params }) | ||||
| } | ||||
|  | ||||
| // 查询交易订单详情 | ||||
| export const getOrder = async (id: number) => { | ||||
|   return await request.get({ url: `/trade/order/get?id=` + id }) | ||||
| } | ||||
|  | ||||
| // 新增交易订单 | ||||
| export const createOrder = async (data: OrderVO) => { | ||||
|   return await request.post({ url: `/trade/order/create`, data }) | ||||
| } | ||||
|  | ||||
| // 修改交易订单 | ||||
| export const updateOrder = async (data: OrderVO) => { | ||||
|   return await request.put({ url: `/trade/order/update`, data }) | ||||
| } | ||||
|  | ||||
| // 删除交易订单 | ||||
| export const deleteOrder = async (id: number) => { | ||||
|   return await request.delete({ url: `/trade/order/delete?id=` + id }) | ||||
| } | ||||
|   | ||||
| @@ -1,228 +0,0 @@ | ||||
| // TODO @xiaobai:这个放到 order/index.ts  里哈 | ||||
| // TODO @xiaobai:注释放到变量后面,这样简洁一点 | ||||
| // TODO @xiaobai:这个改成 TradeOrderRespVO | ||||
| export interface TradeOrderPageItemRespVO { | ||||
|   // 订单编号 | ||||
|   id?: number | ||||
|   // 订单流水号 | ||||
|   no?: string | ||||
|   // 下单时间 | ||||
|   createTime?: Date | ||||
|   // 订单类型 | ||||
|   type?: number | ||||
|   // 订单来源 | ||||
|   terminal?: number | ||||
|   // 用户编号 | ||||
|   userId?: number | ||||
|   // 用户 IP | ||||
|   userIp?: string | ||||
|   // 用户备注 | ||||
|   userRemark?: string | ||||
|   // 订单状态 | ||||
|   status?: number | ||||
|   // 购买的商品数量 | ||||
|   productCount?: number | ||||
|   // 订单完成时间 | ||||
|   finishTime?: Date | ||||
|   // 订单取消时间 | ||||
|   cancelTime?: Date | ||||
|   // 取消类型 | ||||
|   cancelType?: number | ||||
|   // 商家备注 | ||||
|   remark?: string | ||||
|   // 支付订单编号 | ||||
|   payOrderId: number | ||||
|   // 是否已支付 | ||||
|   payed?: boolean | ||||
|   // 付款时间 | ||||
|   payTime?: Date | ||||
|   // 支付渠道 | ||||
|   payChannelCode?: string | ||||
|   // 商品原价(总) | ||||
|   originalPrice?: number | ||||
|   // 订单原价(总) | ||||
|   orderPrice?: number | ||||
|   // 订单优惠(总) | ||||
|   discountPrice?: number | ||||
|   // 运费金额 | ||||
|   deliveryPrice?: number | ||||
|   // 订单调价(总) | ||||
|   adjustPrice?: number | ||||
|   // 应付金额(总) | ||||
|   payPrice?: number | ||||
|   // 配送模板编号 | ||||
|   deliveryTemplateId?: number | ||||
|   // 发货物流公司编号 | ||||
|   logisticsId?: number | ||||
|   // 发货物流单号 | ||||
|   logisticsNo?: string | ||||
|   // 发货状态 | ||||
|   deliveryStatus?: number | ||||
|   // 发货时间 | ||||
|   deliveryTime?: Date | ||||
|   // 收货时间 | ||||
|   receiveTime?: Date | ||||
|   // 收件人名称 | ||||
|   receiverName?: string | ||||
|   // 收件人手机 | ||||
|   receiverMobile?: string | ||||
|   // 收件人地区编号 | ||||
|   receiverAreaId?: number | ||||
|   // 收件人邮编 | ||||
|   receiverPostCode?: number | ||||
|   // 收件人详细地址 | ||||
|   receiverDetailAddress?: string | ||||
|   // 售后状态 | ||||
|   afterSaleStatus?: number | ||||
|   // 退款金额 | ||||
|   refundPrice?: number | ||||
|   // 优惠劵编号 | ||||
|   couponId?: number | ||||
|   // 优惠劵减免金额 | ||||
|   couponPrice?: number | ||||
|   // 积分抵扣的金额 | ||||
|   pointPrice?: number | ||||
|   //收件人地区名字 | ||||
|   receiverAreaName?: string | ||||
|   // 订单项列表 | ||||
|   items?: TradeOrderItemBaseVO[] | ||||
|   //用户信息 | ||||
|   user?: MemberUserRespDTO | ||||
| } | ||||
|  | ||||
| // TODO @xiaobai:这个改成 TradeOrderItemRespVO | ||||
| /** | ||||
|  * 交易订单项 Base VO,提供给添加、修改、详细的子 VO 使用 | ||||
|  * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 | ||||
|  */ | ||||
| export interface TradeOrderItemBaseVO { | ||||
|   // ========== 订单项基本信息 ========== | ||||
|   /** | ||||
|    * 编号 | ||||
|    */ | ||||
|   id?: number | ||||
|   /** | ||||
|    * 用户编号 | ||||
|    */ | ||||
|   userId?: number | ||||
|   /** | ||||
|    * 订单编号 | ||||
|    */ | ||||
|   orderId?: number | ||||
|   // ========== 商品基本信息 ========== | ||||
|   /** | ||||
|    * 商品 SPU 编号 | ||||
|    */ | ||||
|   spuId?: number | ||||
|   /** | ||||
|    * 商品 SPU 名称 | ||||
|    */ | ||||
|   spuName?: string | ||||
|   /** | ||||
|    * 商品 SKU 编号 | ||||
|    */ | ||||
|   skuId?: number | ||||
|   /** | ||||
|    * 商品图片 | ||||
|    */ | ||||
|   picUrl?: string | ||||
|   /** | ||||
|    * 购买数量 | ||||
|    */ | ||||
|   count?: number | ||||
|   // ========== 价格 + 支付基本信息 ========== | ||||
|   /** | ||||
|    * 商品原价(总) | ||||
|    */ | ||||
|   originalPrice?: number | ||||
|   /** | ||||
|    * 商品原价(单) | ||||
|    */ | ||||
|   originalUnitPrice?: number | ||||
|   /** | ||||
|    * 商品优惠(总) | ||||
|    */ | ||||
|   discountPrice?: number | ||||
|   /** | ||||
|    * 商品实付金额(总) | ||||
|    */ | ||||
|   payPrice?: number | ||||
|   /** | ||||
|    * 子订单分摊金额(总) | ||||
|    */ | ||||
|   orderPartPrice?: number | ||||
|   /** | ||||
|    * 分摊后子订单实付金额(总) | ||||
|    */ | ||||
|   orderDividePrice?: number | ||||
|   // ========== 营销基本信息 ========== | ||||
|   // TODO 芋艿:在捉摸一下 | ||||
|   // ========== 售后基本信息 ========== | ||||
|   /** | ||||
|    * 售后状态 | ||||
|    */ | ||||
|   afterSaleStatus?: number | ||||
|   //属性数组 | ||||
|   properties?: ProductPropertyValueDetailRespVO[] | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * 管理后台 - 商品属性值的明细 Response VO | ||||
|  */ | ||||
| export interface ProductPropertyValueDetailRespVO { | ||||
|   /** | ||||
|    * 属性的编号 | ||||
|    */ | ||||
|   propertyId?: number | ||||
|   /** | ||||
|    * 属性的名称 | ||||
|    */ | ||||
|   propertyName?: string | ||||
|   /** | ||||
|    * 属性值的编号 | ||||
|    */ | ||||
|   valueId?: number | ||||
|   /** | ||||
|    * 属性值的名称 | ||||
|    */ | ||||
|   valueName?: string | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * 订单详情查询 请求 | ||||
|  */ | ||||
| export interface TradeOrderPageReqVO { | ||||
|   pageNo: number | ||||
|   pageSize: number | ||||
|   no?: string | ||||
|   userId?: string | ||||
|   userNickname?: string | ||||
|   userMobile?: string | ||||
|   receiverName?: string | ||||
|   receiverMobile?: string | ||||
|   terminal?: string | ||||
|   type?: number | ||||
|   status?: number | ||||
|   payChannelCode?: string | ||||
|   createTime?: [Date, Date] | ||||
|   spuName?: string | ||||
|   itemCount?: string | ||||
|   all?: string | ||||
| } | ||||
|  | ||||
| //用户信息 | ||||
| export interface MemberUserRespDTO { | ||||
|   id?: number | ||||
|   nickname?: string | ||||
|   status?: number | ||||
|   avatar?: string | ||||
|   mobile?: string | ||||
| } | ||||
| //订单详情选中type | ||||
| export interface SelectType { | ||||
|   queryParams: TradeOrderPageReqVO | ||||
|   selectTotal: number //选中的数量 | ||||
|   selectAllFlag: boolean //全选标识 | ||||
|   selectData: Map<number, Set<string>> //存放涉及选中得页面以及每页选中得数据订单号  全选时根据条件查询 排除取消的list订单 | ||||
|   unSelectList: Set<string> //登记取消的list 全选标识为true 时登记单独取消的list,再次选中时排除, 全选标识为false 时清空list | ||||
| } | ||||
| @@ -21,8 +21,8 @@ | ||||
|             v-model="loginData.loginForm.tenantName" | ||||
|             :placeholder="t('login.tenantNamePlaceholder')" | ||||
|             :prefix-icon="iconHouse" | ||||
|             type="primary" | ||||
|             link | ||||
|             type="primary" | ||||
|           /> | ||||
|         </el-form-item> | ||||
|       </el-col> | ||||
| @@ -148,8 +148,8 @@ import { ElLoading } from 'element-plus' | ||||
| import LoginFormTitle from './LoginFormTitle.vue' | ||||
| import type { RouteLocationNormalizedLoaded } from 'vue-router' | ||||
|  | ||||
| import { CACHE_KEY, useCache } from '@/hooks/web/useCache' | ||||
| const { wsCache } = useCache() | ||||
| // import { CACHE_KEY, useCache } from '@/hooks/web/useCache' | ||||
| // const { wsCache } = useCache() | ||||
| import { useIcon } from '@/hooks/web/useIcon' | ||||
|  | ||||
| import * as authUtil from '@/utils/auth' | ||||
| @@ -246,7 +246,7 @@ const handleLogin = async (params) => { | ||||
|     if (!res) { | ||||
|       return | ||||
|     } | ||||
|     wsCache.delete(CACHE_KEY.USER) // 清除上次登录用户信息 | ||||
|     // wsCache.delete(CACHE_KEY.USER) // 清除上次登录用户信息 | ||||
|     ElLoading.service({ | ||||
|       lock: true, | ||||
|       text: '正在加载系统中...', | ||||
|   | ||||
							
								
								
									
										367
									
								
								src/views/mall/trade/order/detail/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										367
									
								
								src/views/mall/trade/order/detail/index.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,367 @@ | ||||
| <template> | ||||
|   <Dialog v-model="dialogVisible" :scroll="true" :title="dialogTitle" width="65%"> | ||||
|     <ContentWrap> | ||||
|       <!-- 订单信息 --> | ||||
|       <el-descriptions title="订单信息"> | ||||
|         <el-descriptions-item label="订单号: ">{{ order.no }}</el-descriptions-item> | ||||
|         <el-descriptions-item label="配送方式: ">物流配送</el-descriptions-item> | ||||
|         <!-- TODO 芋艿:待实现 --> | ||||
|         <el-descriptions-item label="营销活动: ">物流配送</el-descriptions-item> | ||||
|         <!-- TODO 芋艿:待实现 --> | ||||
|         <el-descriptions-item label="订单类型: "> | ||||
|           <dict-tag :type="DICT_TYPE.TRADE_ORDER_TYPE" :value="order.type" /> | ||||
|         </el-descriptions-item> | ||||
|         <el-descriptions-item label="收货人: ">{{ order.receiverName }}</el-descriptions-item> | ||||
|         <el-descriptions-item label="买家留言: ">{{ order.userRemark }}</el-descriptions-item> | ||||
|         <el-descriptions-item label="订单来源: "> | ||||
|           <dict-tag :type="DICT_TYPE.TERMINAL" :value="order.terminal" /> | ||||
|         </el-descriptions-item> | ||||
|         <el-descriptions-item label="联系电话: ">{{ order.receiverMobile }}</el-descriptions-item> | ||||
|         <el-descriptions-item label="商家备注: ">{{ order.remark }}</el-descriptions-item> | ||||
|         <el-descriptions-item label="支付单号: ">{{ order.payOrderId }}</el-descriptions-item> | ||||
|         <el-descriptions-item label="付款方式: "> | ||||
|           <dict-tag :type="DICT_TYPE.PAY_CHANNEL_CODE_TYPE" :value="order.payChannelCode" /> | ||||
|         </el-descriptions-item> | ||||
|         <!-- <el-descriptions-item label="买家: ">{{ order.user.nickname }}</el-descriptions-item> --> | ||||
|         <!-- TODO 芋艿:待实现:跳转会员 --> | ||||
|         <el-descriptions-item label="收货地址: "> | ||||
|           {{ order.receiverAreaName }} {{ order.receiverDetailAddress }} | ||||
|           <el-link | ||||
|             v-clipboard:copy="order.receiverAreaName + ' ' + order.receiverDetailAddress" | ||||
|             v-clipboard:success="clipboardSuccess" | ||||
|             icon="ep:document-copy" | ||||
|             type="primary" | ||||
|           /> | ||||
|         </el-descriptions-item> | ||||
|       </el-descriptions> | ||||
|  | ||||
|       <!-- 订单状态 --> | ||||
|       <el-descriptions :column="1" title="订单状态"> | ||||
|         <el-descriptions-item label="订单状态: "> | ||||
|           <!-- TODO xiaobai:status 一定有值哈,不用判断 --> | ||||
|           <dict-tag | ||||
|             v-if="order.status !== ''" | ||||
|             :type="DICT_TYPE.TRADE_ORDER_STATUS" | ||||
|             :value="order.status" | ||||
|           /> | ||||
|         </el-descriptions-item> | ||||
|         <el-descriptions-item label-class-name="no-colon"> | ||||
|           <el-button size="small" type="primary">调整价格</el-button> | ||||
|           <!-- TODO 芋艿:待实现 --> | ||||
|           <el-button size="small" type="primary">备注</el-button> | ||||
|           <!-- TODO 芋艿:待实现 --> | ||||
|           <el-button size="small" type="primary">发货</el-button> | ||||
|           <!-- TODO 芋艿:待实现 --> | ||||
|           <el-button size="small" type="primary">关闭订单</el-button> | ||||
|           <!-- TODO 芋艿:待实现 --> | ||||
|           <el-button size="small" type="primary">修改地址</el-button> | ||||
|           <!-- TODO 芋艿:待实现 --> | ||||
|           <el-button size="small" type="primary">打印电子面单</el-button> | ||||
|           <!-- TODO 芋艿:待实现 --> | ||||
|           <el-button size="small" type="primary">打印发货单</el-button> | ||||
|           <!-- TODO 芋艿:待实现 --> | ||||
|           <el-button size="small" type="primary">确认收货</el-button> | ||||
|           <!-- TODO 芋艿:待实现 --> | ||||
|         </el-descriptions-item> | ||||
|         <el-descriptions-item> | ||||
|           <template #label><span style="color: red">提醒: </span></template> | ||||
|           买家付款成功后,货款将直接进入您的商户号(微信、支付宝)<br /> | ||||
|           请及时关注你发出的包裹状态,确保可以配送至买家手中 <br /> | ||||
|           如果买家表示没收到货或货物有问题,请及时联系买家处理,友好协商 | ||||
|         </el-descriptions-item> | ||||
|       </el-descriptions> | ||||
|  | ||||
|       <!-- 物流信息 TODO --> | ||||
|  | ||||
|       <!-- 商品信息 --> | ||||
|       <el-descriptions title="商品信息"> | ||||
|         <el-descriptions-item labelClassName="no-colon"> | ||||
|           <el-row :gutter="20"> | ||||
|             <el-col :span="15"> | ||||
|               <el-table :data="order.items" border> | ||||
|                 <el-table-column label="商品" prop="spuName" width="auto"> | ||||
|                   <template #default="{ row }"> | ||||
|                     {{ row.spuName }} | ||||
|                     <el-tag v-for="property in row.properties" :key="property.propertyId"> | ||||
|                       {{ property.propertyName }}: {{ property.valueName }} | ||||
|                     </el-tag> | ||||
|                   </template> | ||||
|                 </el-table-column> | ||||
|                 <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> | ||||
|                 <el-table-column label="售后状态" prop="afterSaleStatus" width="120"> | ||||
|                   <template #default="{ row }"> | ||||
|                     <dict-tag | ||||
|                       :type="DICT_TYPE.TRADE_ORDER_ITEM_AFTER_SALE_STATUS" | ||||
|                       :value="row.afterSaleStatus" | ||||
|                     /> | ||||
|                   </template> | ||||
|                 </el-table-column> | ||||
|               </el-table> | ||||
|             </el-col> | ||||
|             <el-col :span="10" /> | ||||
|           </el-row> | ||||
|         </el-descriptions-item> | ||||
|         <!-- 占位 --> | ||||
|         <!-- <el-descriptions-item v-for="item in 5" label-class-name="no-colon" :key="item" /> --> | ||||
|       </el-descriptions> | ||||
|       <el-descriptions column="6"> | ||||
|         <el-descriptions-item label="商品总额: "> | ||||
|           {{ formatToFraction(order.totalPrice) }}元 | ||||
|         </el-descriptions-item> | ||||
|         <el-descriptions-item label="运费金额: "> | ||||
|           {{ formatToFraction(order.deliveryPrice) }}元 | ||||
|         </el-descriptions-item> | ||||
|         <el-descriptions-item label="订单调价: "> | ||||
|           {{ formatToFraction(order.adjustPrice) }}元 | ||||
|         </el-descriptions-item> | ||||
|  | ||||
|         <el-descriptions-item> | ||||
|           <template #label><span style="color: red">商品优惠: </span></template> | ||||
|           <!-- 没理解TODO  order.totalPrice - order.totalPrice --> | ||||
|           {{ formatToFraction(order.totalPrice - order.totalPrice) }}元 | ||||
|         </el-descriptions-item> | ||||
|         <el-descriptions-item> | ||||
|           <template #label><span style="color: red">订单优惠: </span></template> | ||||
|           {{ formatToFraction(order.discountPrice) }}元 | ||||
|         </el-descriptions-item> | ||||
|         <el-descriptions-item> | ||||
|           <template #label><span style="color: red">积分抵扣: </span></template> | ||||
|           {{ formatToFraction(order.pointPrice) }}元 | ||||
|         </el-descriptions-item> | ||||
|  | ||||
|         <el-descriptions-item v-for="item in 5" :key="item" label-class-name="no-colon" /> | ||||
|         <!-- 占位 --> | ||||
|         <el-descriptions-item label="应付金额: "> | ||||
|           {{ formatToFraction(order.payPrice) }}元 | ||||
|         </el-descriptions-item> | ||||
|       </el-descriptions> | ||||
|  | ||||
|       <!-- TODO 芋艿:需要改改 --> | ||||
|       <div v-for="group in detailGroups" :key="group.title"> | ||||
|         <el-descriptions :title="group.title" v-bind="group.groupProps"> | ||||
|           <!-- 订单操作日志 --> | ||||
|           <el-descriptions-item v-if="group.key === 'orderLog'" labelClassName="no-colon"> | ||||
|             <el-timeline> | ||||
|               <el-timeline-item | ||||
|                 v-for="activity in detailInfo[group.key]" | ||||
|                 :key="activity.timestamp" | ||||
|                 :timestamp="activity.timestamp" | ||||
|               > | ||||
|                 {{ activity.content }} | ||||
|               </el-timeline-item> | ||||
|             </el-timeline> | ||||
|           </el-descriptions-item> | ||||
|  | ||||
|           <!-- 物流信息 --> | ||||
|           <!-- TODO @xiaobai:改成一个包裹哈;目前只允许发货一次 --> | ||||
|           <el-descriptions-item v-if="group.key === 'expressInfo'" labelClassName="no-colon"> | ||||
|             <!-- 循环包裹物流信息 --> | ||||
|             <div v-show="(pkgInfo = detailInfo[group.key]) !== null" style="border: 1px dashed"> | ||||
|               <!-- 包裹详情 --> | ||||
|               <el-descriptions class="m-5"> | ||||
|                 <el-descriptions-item | ||||
|                   v-for="(pkgChild, pkgCIdx) in group.children" | ||||
|                   :key="`pkgChild_${pkgCIdx}`" | ||||
|                   :label="pkgChild.label" | ||||
|                   v-bind="pkgChild.childProps" | ||||
|                 > | ||||
|                   <!-- 包裹商品列表 --> | ||||
|                   <template v-if="pkgChild.valueKey === 'goodsList' && pkgInfo[pkgChild.valueKey]"> | ||||
|                     <div | ||||
|                       v-for="(goodInfo, goodInfoIdx) in pkgInfo[pkgChild.valueKey]" | ||||
|                       :key="`goodInfo_${goodInfoIdx}`" | ||||
|                       style="display: flex" | ||||
|                     > | ||||
|                       <el-image | ||||
|                         :src="goodInfo.imgUrl" | ||||
|                         style="width: 100px; height: 100px; flex: none" | ||||
|                       /> | ||||
|                       <el-descriptions :column="1"> | ||||
|                         <el-descriptions-item labelClassName="no-colon" | ||||
|                           >{{ goodInfo.name }} | ||||
|                         </el-descriptions-item> | ||||
|                         <el-descriptions-item label="数量" | ||||
|                           >{{ goodInfo.count }} | ||||
|                         </el-descriptions-item> | ||||
|                       </el-descriptions> | ||||
|                     </div> | ||||
|                   </template> | ||||
|  | ||||
|                   <!-- 包裹物流详情 --> | ||||
|                   <template v-else-if="pkgChild.valueKey === 'wlxq'"> | ||||
|                     <el-row :gutter="10"> | ||||
|                       <el-col :offset="1" :span="6"> | ||||
|                         <el-timeline> | ||||
|                           <el-timeline-item | ||||
|                             v-for="(activity, index) in pkgInfo[pkgChild.valueKey]" | ||||
|                             :key="index" | ||||
|                             :timestamp="activity.timestamp" | ||||
|                           > | ||||
|                             {{ activity.content }} | ||||
|                           </el-timeline-item> | ||||
|                         </el-timeline> | ||||
|                       </el-col> | ||||
|                     </el-row> | ||||
|                   </template> | ||||
|                   <template v-else> | ||||
|                     {{ pkgInfo[pkgChild.valueKey] }} | ||||
|                   </template> | ||||
|                 </el-descriptions-item> | ||||
|               </el-descriptions> | ||||
|             </div> | ||||
|           </el-descriptions-item> | ||||
|         </el-descriptions> | ||||
|       </div> | ||||
|     </ContentWrap> | ||||
|   </Dialog> | ||||
| </template> | ||||
| <script lang="ts" setup> | ||||
| import { formatToFraction } from '@/utils' | ||||
| import { DICT_TYPE } from '@/utils/dict' | ||||
|  | ||||
| defineOptions({ name: 'TradeOrderDetailForm' }) | ||||
|  | ||||
| const message = useMessage() // 消息弹窗 | ||||
| const dialogVisible = ref(false) // 弹窗的是否展示 | ||||
| const dialogTitle = ref('订单详情') // 弹窗的标题 | ||||
|  | ||||
| const open = () => { | ||||
|   dialogVisible.value = true | ||||
| } | ||||
| defineExpose({ open }) | ||||
|  | ||||
| const { query } = useRoute() | ||||
| const queryParams = reactive({ | ||||
|   id: query.id | ||||
| }) | ||||
|  | ||||
| const loading = ref(false) | ||||
| const order = ref<any>({ | ||||
|   items: [], | ||||
|   user: {} | ||||
| }) // 详情数据 | ||||
|  | ||||
| const detailGroups = ref([ | ||||
|   { | ||||
|     title: '物流信息', | ||||
|     key: 'expressInfo', | ||||
|     children: [ | ||||
|       { label: '发货时间: ', valueKey: 'fhsj' }, | ||||
|       { label: '物流公司: ', valueKey: 'wlgs' }, | ||||
|       { label: '运单号: ', valueKey: 'ydh' }, | ||||
|       { label: '物流状态: ', valueKey: 'wlzt', childProps: { span: 3 } }, | ||||
|       { label: '物流详情: ', valueKey: 'wlxq' } | ||||
|     ] | ||||
|   }, | ||||
|   { | ||||
|     title: '订单操作日志', | ||||
|     key: 'orderLog' | ||||
|   } | ||||
| ]) | ||||
|  | ||||
| const detailInfo = ref({ | ||||
|   expressInfo: | ||||
|     // 物流信息 | ||||
|     { | ||||
|       label: '包裹1', | ||||
|       name: 'bg1', | ||||
|       fhsj: '2022-11-03 16:50:45', | ||||
|       wlgs: '极兔', | ||||
|       ydh: '2132123', | ||||
|       wlzt: '不支持此快递公司', | ||||
|       wlxq: [ | ||||
|         { | ||||
|           content: '正在派送途中,请您准备签收(派件人:王涛,电话:13854563814)', | ||||
|           timestamp: '2018-04-15 15:00:16' | ||||
|         }, | ||||
|         { | ||||
|           content: '快件到达 【烟台龙口东江村委营业点】', | ||||
|           timestamp: '2018-04-13 14:54:19' | ||||
|         }, | ||||
|         { | ||||
|           content: '快件已发车', | ||||
|           timestamp: '2018-04-11 12:55:52' | ||||
|         }, | ||||
|         { | ||||
|           content: '快件已发车', | ||||
|           timestamp: '2018-04-11 12:55:52' | ||||
|         }, | ||||
|         { | ||||
|           content: '快件已发车', | ||||
|           timestamp: '2018-04-11 12:55:52' | ||||
|         } | ||||
|       ] | ||||
|     }, | ||||
|   orderLog: [ | ||||
|     // 订单操作日志 | ||||
|     { | ||||
|       content: '买家【乌鸦】关闭了订单', | ||||
|       timestamp: '2018-04-15 15:00:16' | ||||
|     }, | ||||
|     { | ||||
|       content: '买家【乌鸦】下单了', | ||||
|       timestamp: '2018-04-15 15:00:16' | ||||
|     } | ||||
|   ], | ||||
|   goodsInfo: [] // 商品详情tableData | ||||
| }) | ||||
| // 暂考虑一次性加载详情页面所有数据 TODO | ||||
| const getlist = async () => { | ||||
|   // dialogVisible.value = true | ||||
|   // loading.value = true | ||||
|   // try { | ||||
|   //   const res = await TradeOrderApi.getOrderDetail(queryParams.id as unknown as number) | ||||
|   //   order.value = res | ||||
|   //   console.log(order) | ||||
|   // } catch { | ||||
|   //   message.error('获取详情数据失败') | ||||
|   // } finally { | ||||
|   //   loading.value = false | ||||
|   // } | ||||
| } | ||||
| onMounted(async () => { | ||||
|   await getlist() | ||||
| }) | ||||
| const clipboardSuccess = () => { | ||||
|   message.success('复制成功') | ||||
| } | ||||
| </script> | ||||
| <style lang="scss" scoped> | ||||
| :deep(.el-descriptions) { | ||||
|   &:not(:nth-child(1)) { | ||||
|     margin-top: 20px; | ||||
|   } | ||||
|  | ||||
|   .el-descriptions__title { | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|  | ||||
|     &::before { | ||||
|       display: inline-block; | ||||
|       width: 3px; | ||||
|       height: 20px; | ||||
|       margin-right: 10px; | ||||
|       background-color: #409eff; | ||||
|       content: ''; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .el-descriptions-item__container { | ||||
|     margin: 0 10px; | ||||
|  | ||||
|     .no-colon { | ||||
|       margin: 0; | ||||
|  | ||||
|       &::after { | ||||
|         content: ''; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </style> | ||||
| @@ -3,13 +3,13 @@ | ||||
|   <ContentWrap> | ||||
|     <el-form | ||||
|       ref="queryFormRef" | ||||
|       :inline="true" | ||||
|       :model="queryParams" | ||||
|       class="-mb-15px" | ||||
|       label-width="68px" | ||||
|       :inline="true" | ||||
|     > | ||||
|       <el-form-item label="订单状态" prop="status"> | ||||
|         <el-select class="!w-280px" v-model="queryParams.status" clearable placeholder="全部"> | ||||
|         <el-select v-model="queryParams.status" class="!w-280px" clearable placeholder="全部"> | ||||
|           <el-option | ||||
|             v-for="dict in getStrDictOptions(DICT_TYPE.TRADE_ORDER_STATUS)" | ||||
|             :key="dict.value as string" | ||||
| @@ -38,14 +38,14 @@ | ||||
|           v-model="queryParams.createTime" | ||||
|           :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]" | ||||
|           class="!w-280px" | ||||
|           start-placeholder="自定义时间" | ||||
|           end-placeholder="自定义时间" | ||||
|           start-placeholder="自定义时间" | ||||
|           type="daterange" | ||||
|           value-format="YYYY-MM-DD HH:mm:ss" | ||||
|         /> | ||||
|       </el-form-item> | ||||
|       <el-form-item label="订单来源" prop="terminal"> | ||||
|         <el-select class="!w-280px" v-model="queryParams.terminal" clearable placeholder="全部"> | ||||
|         <el-select v-model="queryParams.terminal" class="!w-280px" clearable placeholder="全部"> | ||||
|           <el-option | ||||
|             v-for="dict in getStrDictOptions(DICT_TYPE.TERMINAL)" | ||||
|             :key="dict.value as string" | ||||
| @@ -55,7 +55,7 @@ | ||||
|         </el-select> | ||||
|       </el-form-item> | ||||
|       <el-form-item label="订单类型" prop="type"> | ||||
|         <el-select class="!w-280px" v-model="queryParams.type" clearable placeholder="全部"> | ||||
|         <el-select v-model="queryParams.type" class="!w-280px" clearable placeholder="全部"> | ||||
|           <el-option | ||||
|             v-for="dict in getStrDictOptions(DICT_TYPE.TRADE_ORDER_TYPE)" | ||||
|             :key="dict.value as string" | ||||
| @@ -68,13 +68,13 @@ | ||||
|       <el-form-item label="订单搜索"> | ||||
|         <el-input | ||||
|           v-show="true" | ||||
|           class="!w-280px" | ||||
|           v-model="queryType.v" | ||||
|           class="!w-280px" | ||||
|           clearable | ||||
|           placeholder="请输入" | ||||
|         > | ||||
|           <template #prepend> | ||||
|             <el-select style="width: 110px" v-model="queryType.k" clearable placeholder="全部"> | ||||
|             <el-select v-model="queryType.k" clearable placeholder="全部" style="width: 110px"> | ||||
|               <el-option | ||||
|                 v-for="dict in searchList" | ||||
|                 :key="dict.value" | ||||
| @@ -86,180 +86,154 @@ | ||||
|         </el-input> | ||||
|       </el-form-item> | ||||
|       <el-form-item> | ||||
|         <el-button @click="handleQuery" v-hasPermi="['trade:order:query']"> | ||||
|         <!-- TODO 订单按钮相关权限等订单完善后补齐 --> | ||||
|         <el-button @click="handleQuery"> | ||||
|           <Icon class="mr-5px" icon="ep:search" /> | ||||
|           搜索 | ||||
|         </el-button> | ||||
|         <el-button @click="resetQuery" v-hasPermi="['trade:order:query']"> | ||||
|         <el-button @click="resetQuery"> | ||||
|           <Icon class="mr-5px" icon="ep:refresh" /> | ||||
|           重置 | ||||
|         </el-button> | ||||
|         <el-button type="success" plain @click="handleExport" :loading="exportLoading"> | ||||
|           <!--           v-hasPermi="['trade:order:export']"        --> | ||||
|           <Icon icon="ep:download" class="mr-5px" /> 导出TODO | ||||
|         </el-button> | ||||
|       </el-form-item> | ||||
|     </el-form> | ||||
|   </ContentWrap> | ||||
|   <!-- 表格 --> | ||||
|  | ||||
|   <!-- 列表 --> | ||||
|   <ContentWrap> | ||||
|     <!-- 表单 --> | ||||
|     <el-table v-loading="loading" :data="list"> | ||||
|       <el-table-column type="expand" fixed="left"> | ||||
|     <el-table | ||||
|       v-loading="loading" | ||||
|       :data="list" | ||||
|       :show-overflow-tooltip="true" | ||||
|       :stripe="true" | ||||
|       default-expand-all | ||||
|     > | ||||
|       <el-table-column fixed="left" type="expand"> | ||||
|         <template #default="scope"> | ||||
|           <el-descriptions class="mx-40"> | ||||
|             <el-descriptions-item label="商品原价(总): ">{{ | ||||
|               '¥ ' + | ||||
|               parseFloat((scope.row.originalPrice / 100) as unknown as string).toFixed(2) + | ||||
|               ' 元' | ||||
|             }}</el-descriptions-item> | ||||
|             <el-descriptions-item label="下单时间: "> | ||||
|               {{ formatDate(scope.row.createTime) }}</el-descriptions-item | ||||
|             > | ||||
|             <el-descriptions-item label="推广人: ">TODO</el-descriptions-item> | ||||
|             <el-descriptions-item label="用户备注: ">{{ | ||||
|               scope.row.userRemark | ||||
|             }}</el-descriptions-item> | ||||
|             <el-descriptions-item label="商家备注: ">{{ scope.row.remark }}</el-descriptions-item> | ||||
|           </el-descriptions> | ||||
|         </template> | ||||
|       </el-table-column> | ||||
|       <el-table-column width="100" fixed="left"> | ||||
|         <template #header> | ||||
|           <el-dropdown icon="eq:search" @command="handleDropType"> | ||||
|             <el-button link type="primary">全选({{ orderSelect.selectTotal }}) </el-button> | ||||
|  | ||||
|             <template #dropdown> | ||||
|               <el-dropdown-menu> | ||||
|                 <el-dropdown-item command="1">当前页</el-dropdown-item> | ||||
|                 <el-dropdown-item command="2">所有页</el-dropdown-item> | ||||
|               </el-dropdown-menu> | ||||
|             </template> | ||||
|           </el-dropdown> | ||||
|         </template> | ||||
|         <template #default="scope"> | ||||
|           <el-checkbox v-model="scope.row.itemSelect" @change="handcheckclick(scope.row)" /> | ||||
|         </template> | ||||
|       </el-table-column> | ||||
|  | ||||
|       <el-table-column label="订单号" align="center" min-width="110"> | ||||
|         <template #default="scope"> | ||||
|           <el-button link type="primary" @click="showOrderDetail(scope.row)">{{ | ||||
|             scope.row.no | ||||
|           }}</el-button> | ||||
|         </template> | ||||
|       </el-table-column> | ||||
|       <el-table-column label="订单类型" align="center" min-width="100"> | ||||
|         <template #default="scope"> | ||||
|           <dict-tag :type="DICT_TYPE.TRADE_ORDER_TYPE" :value="scope.row.type" /> | ||||
|         </template> | ||||
|       </el-table-column> | ||||
|       <el-table-column label="用户信息" align="center" min-width="100"> | ||||
|         <template #default="scope"> | ||||
|           <el-button link type="primary" @click="goUserDetail(scope.row)" | ||||
|             >{{ scope.row.userId }}{{ '[' + scope.row.user.nickname + ']' }}</el-button | ||||
|           > | ||||
|         </template> | ||||
|       </el-table-column> | ||||
|       <el-table-column | ||||
|         :formatter="dateFormatter" | ||||
|         align="center" | ||||
|         label="创建时间" | ||||
|         prop="createTime" | ||||
|         min-width="180" | ||||
|       /> | ||||
|       <el-table-column label="订单来源" align="center" min-width="100"> | ||||
|         <template #default="scope"> | ||||
|           <dict-tag | ||||
|             v-if="scope.row.terminal" | ||||
|             :type="DICT_TYPE.TERMINAL" | ||||
|             :value="scope.row.terminal" | ||||
|           /> | ||||
|           <span v-else>{{ scope.terminal }}</span> | ||||
|         </template> | ||||
|       </el-table-column> | ||||
|  | ||||
|       <el-table-column label="商品信息" align="left" min-width="200" prop="items"> | ||||
|         <template #default="scope"> | ||||
|           <el-popover | ||||
|             ref="popover" | ||||
|             placement="bottom" | ||||
|             :title="'订单:' + scope.row.no" | ||||
|             :width="400" | ||||
|             trigger="hover" | ||||
|           > | ||||
|             <template #reference> | ||||
|               <div> | ||||
|                 <div v-for="item in scope.row.items" :key="item"> | ||||
|                   <el-image | ||||
|                     style="width: 36px; height: 36px" | ||||
|                     :src="item.picUrl" | ||||
|                     :preview-src-list="[item.picUrl]" | ||||
|                     fit="cover" | ||||
|                     @click="imagePreview(item.picUrl)" | ||||
|                   /> | ||||
|                   <span class="m-2">{{ item.spuName }}</span> | ||||
|           <el-table :data="scope.row.items" :span-method="spanMethod" border style="width: 100%"> | ||||
|             <el-table-column label="商品" prop="spuName"> | ||||
|               <template #default="{ row }"> | ||||
|                 {{ row.spuName }} | ||||
|                 <el-tag v-for="property in row.properties" :key="property.propertyId"> | ||||
|                   {{ property.propertyName }}: {{ property.valueName }} | ||||
|                 </el-tag> | ||||
|               </template> | ||||
|             </el-table-column> | ||||
|             <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> | ||||
|             <el-table-column label="售后状态" prop="afterSaleStatus" width="120"> | ||||
|               <template #default="{ row }"> | ||||
|                 <dict-tag | ||||
|                   :type="DICT_TYPE.TRADE_ORDER_ITEM_AFTER_SALE_STATUS" | ||||
|                   :value="row.afterSaleStatus" | ||||
|                 /> | ||||
|               </template> | ||||
|             </el-table-column> | ||||
|             <el-table-column align="center" label="实际支付(元)" min-width="120" prop="payPrice"> | ||||
|               <template #default> | ||||
|                 {{ formatToFraction(scope.row.payPrice) + '元' }} | ||||
|               </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 }"> | ||||
|                 <div class="flex justify-center items-center"> | ||||
|                   <el-button link type="primary" @click="openForm"> | ||||
|                     <Icon icon="ep:notification" /> | ||||
|                     详情 | ||||
|                   </el-button> | ||||
|                   <el-dropdown @command="(command) => handleCommand(command, row)"> | ||||
|                     <el-button link type="primary"> | ||||
|                       <Icon icon="ep:d-arrow-right" /> | ||||
|                       更多 | ||||
|                     </el-button> | ||||
|                     <template #dropdown> | ||||
|                       <el-dropdown-menu> | ||||
|                         <el-dropdown-item command="orderRemarks"> | ||||
|                           <Icon icon="ep:chat-line-square" /> | ||||
|                           订单备注 | ||||
|                         </el-dropdown-item> | ||||
|                         <el-dropdown-item command="refund"> | ||||
|                           <Icon icon="ep:credit-card" /> | ||||
|                           立即退款 | ||||
|                         </el-dropdown-item> | ||||
|                         <el-dropdown-item command="printReceipt"> | ||||
|                           <Icon icon="ep:takeaway-box" /> | ||||
|                           打印小票 | ||||
|                         </el-dropdown-item> | ||||
|                         <el-dropdown-item command="printInvoice"> | ||||
|                           <Icon icon="ep:takeaway-box" /> | ||||
|                           打印配货单 | ||||
|                         </el-dropdown-item> | ||||
|                       </el-dropdown-menu> | ||||
|                     </template> | ||||
|                   </el-dropdown> | ||||
|                 </div> | ||||
|               </div> | ||||
|             </template> | ||||
|             <div v-for="item in scope.row.items" :key="item"> | ||||
|               <div> | ||||
|                 <p>{{ item.spuName }}</p> | ||||
|                 <!-- TODO xiaobai: 是不是 (item.payPrice / 100.0).toFixed(2) --> | ||||
|                 <p>{{ | ||||
|                   '¥ ' + | ||||
|                   parseFloat((item.payPrice / 100) as unknown as string).toFixed(2) + | ||||
|                   '元 x ' + | ||||
|                   item.count | ||||
|                 }}</p> | ||||
|               </div> | ||||
|             </div> | ||||
|           </el-popover> | ||||
|               </template> | ||||
|             </el-table-column> | ||||
|           </el-table> | ||||
|         </template> | ||||
|       </el-table-column> | ||||
|       <el-table-column label="实际支付(元)" align="center" prop="payPrice" min-width="100"> | ||||
|         <template #default="scope"> | ||||
|           {{ '¥ ' + parseFloat((scope.row.payPrice / 100) as unknown as string).toFixed(2) }} | ||||
|       <el-table-column align="center" label="订单号" min-width="110" prop="no" /> | ||||
|       <el-table-column align="center" label="订单类型" min-width="100"> | ||||
|         <template #default="{ row }"> | ||||
|           <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" /> | ||||
|           <span v-else>{{ row.terminal }}</span> | ||||
|         </template> | ||||
|       </el-table-column> | ||||
|       <el-table-column | ||||
|         :formatter="dateFormatter" | ||||
|         align="center" | ||||
|         label="支付时间" | ||||
|         prop="payTime" | ||||
|         min-width="180" | ||||
|         prop="payTime" | ||||
|       /> | ||||
|       <el-table-column label="支付类型" align="center" min-width="100" prop="payChannelCode"> | ||||
|         <template #default="scope"> | ||||
|       <el-table-column align="center" label="支付类型" min-width="100" prop="payChannelCode"> | ||||
|         <template #default="{ row }"> | ||||
|           <dict-tag | ||||
|             v-if="scope.row.payChannelCode" | ||||
|             v-if="row.payChannelCode" | ||||
|             :type="DICT_TYPE.PAY_CHANNEL_CODE_TYPE" | ||||
|             :value="scope.row.payChannelCode" | ||||
|             :value="row.payChannelCode" | ||||
|           /> | ||||
|         </template> | ||||
|       </el-table-column> | ||||
|       <el-table-column label="订单状态" align="center" prop="status" min-width="100"> | ||||
|         <template #default="scope"> | ||||
|       <el-table-column align="center" label="订单状态" min-width="100" prop="status"> | ||||
|         <template #default="{ row }"> | ||||
|           <dict-tag | ||||
|             v-if="scope.row.status !== ''" | ||||
|             v-if="row.status !== ''" | ||||
|             :type="DICT_TYPE.TRADE_ORDER_STATUS" | ||||
|             :value="scope.row.status" | ||||
|             :value="row.status" | ||||
|           /> | ||||
|           <span v-else>{{ scope.status }}</span> | ||||
|         </template> | ||||
|       </el-table-column> | ||||
|       <el-table-column label="操作" align="center" fixed="right" min-width="150"> | ||||
|         <template #default="scope"> | ||||
|           <!-- <el-button v-if="scope.row.status == '0'" link type="primary" @click="sendXX(scope.row)" | ||||
|             >待支付</el-button> --> | ||||
|           <el-button v-if="scope.row.status == '10'" link type="primary" @click="sendXX(scope.row)" | ||||
|             >发货</el-button | ||||
|           > | ||||
|           <el-button link type="primary" @click="showOrderDetail(scope.row)">详情</el-button> | ||||
|           <span v-else>{{ row.status }}</span> | ||||
|         </template> | ||||
|       </el-table-column> | ||||
|       <el-table-column | ||||
|         :formatter="dateFormatter" | ||||
|         align="center" | ||||
|         label="创建时间" | ||||
|         min-width="180" | ||||
|         prop="createTime" | ||||
|       /> | ||||
|     </el-table> | ||||
|  | ||||
|     <!-- 分页 --> | ||||
|     <Pagination | ||||
|       v-model:limit="queryParams.pageSize" | ||||
| @@ -268,305 +242,135 @@ | ||||
|       @pagination="getList" | ||||
|     /> | ||||
|   </ContentWrap> | ||||
|   <el-image-viewer | ||||
|     v-if="imgViewVisible" | ||||
|     :url-list="imageViewerList" | ||||
|     @close="imgViewVisible = false" | ||||
|   /> | ||||
|   <TradeOrderDetailForm ref="tradeOrderDetailFormRef" /> | ||||
| </template> | ||||
| <script setup lang="ts" name="OrderList"> | ||||
|  | ||||
| <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 { OrderItemRespVO, OrderVO } from '@/api/mall/trade/order' | ||||
| import { DICT_TYPE, getStrDictOptions } from '@/utils/dict' | ||||
| import * as TradeOrderApi from '@/api/mall/trade/order' | ||||
| import { | ||||
|   TradeOrderPageReqVO, | ||||
|   SelectType, | ||||
|   TradeOrderPageItemRespVO | ||||
| } from '@/api/mall/trade/order/type/orderType' | ||||
| import { dateFormatter, formatDate } from '@/utils/formatTime' | ||||
| import download from '@/utils/download' | ||||
| import { formatToFraction } from '@/utils' | ||||
| import { testData } from './testData' | ||||
| import { createImageViewer } from '@/components/ImageViewer' | ||||
|  | ||||
| const message = useMessage() | ||||
| const { push } = useRouter() | ||||
| const imgViewVisible = ref(false) // 商品图预览 | ||||
| const imageViewerList = ref<string[]>([]) // 商品图预览列表 | ||||
| const queryFormRef = ref() | ||||
| const loading = ref(false) | ||||
| const exportLoading = ref(false) | ||||
| const total = ref(0) // 总记录数 | ||||
| const list = ref<Array<TradeOrderPageItemRespVO | any>>([]) //表数据 | ||||
| // const message = useMessage() // 消息弹窗 | ||||
| // const { t } = useI18n() // 国际化 | ||||
|  | ||||
| // 选中状态选中处理 | ||||
| const orderSelect: SelectType = reactive({ | ||||
|   queryParams: {} as TradeOrderPageReqVO, | ||||
|   selectTotal: 0, | ||||
|   selectAllFlag: false, | ||||
|   selectData: new Map<number, Set<string>>(), | ||||
|   unSelectList: new Set<string>() | ||||
| }) | ||||
| const loading = ref(true) // 列表的加载中 | ||||
| const total = ref(2) // 列表的总页数 | ||||
| const list = ref<OrderVO[]>([]) // 列表的数据 | ||||
| const tradeOrderDetailFormRef = ref<InstanceType<typeof TradeOrderDetailForm>>() | ||||
| const openForm = () => { | ||||
|   tradeOrderDetailFormRef.value?.open() | ||||
| } | ||||
| /** 商品图预览 */ | ||||
| const imagePreview = (imgUrl: string) => { | ||||
|   createImageViewer({ | ||||
|     urlList: [imgUrl] | ||||
|   }) | ||||
| } | ||||
|  | ||||
| interface SpanMethodProps { | ||||
|   row: OrderItemRespVO | ||||
|   column: TableColumnCtx<OrderItemRespVO> | ||||
|   rowIndex: number | ||||
|   columnIndex: number | ||||
| } | ||||
|  | ||||
| const spanMethod = ({ rowIndex, columnIndex }: SpanMethodProps) => { | ||||
|   const colIndex = [5, 6, 7] | ||||
|   // 处理列 | ||||
|   if (colIndex.includes(columnIndex)) { | ||||
|     // 处理被合并的行 | ||||
|     if (rowIndex !== 0) { | ||||
|       return { | ||||
|         rowspan: 0, | ||||
|         colspan: 0 | ||||
|       } | ||||
|     } | ||||
|     return { | ||||
|       rowspan: 2, | ||||
|       colspan: 1 | ||||
|     } | ||||
|   } | ||||
| } | ||||
| /** 操作分发 */ | ||||
| const handleCommand = (command: string, row: OrderVO) => { | ||||
|   console.log(row) | ||||
|   switch (command) { | ||||
|     case 'orderRemarks': | ||||
|       break | ||||
|     case 'refund': | ||||
|       break | ||||
|     case 'printReceipt': | ||||
|       break | ||||
|     case 'printInvoice': | ||||
|       break | ||||
|     default: | ||||
|       break | ||||
|   } | ||||
| } | ||||
| const queryFormRef = ref<FormInstance>() // 搜索的表单 | ||||
| //表单搜索 | ||||
| const queryParams: TradeOrderPageReqVO = reactive({ | ||||
| const queryParams = reactive({ | ||||
|   pageNo: 1, //首页 | ||||
|   pageSize: 10 //页面大小 | ||||
|   pageSize: 10, //页面大小 | ||||
|   no: '', | ||||
|   userId: '', | ||||
|   userNickname: '', | ||||
|   userMobile: '', | ||||
|   receiverName: '', | ||||
|   receiverMobile: '', | ||||
|   terminal: '', | ||||
|   type: null, | ||||
|   status: null, | ||||
|   payChannelCode: '', | ||||
|   createTime: [], | ||||
|   spuName: '', | ||||
|   itemCount: '', | ||||
|   all: '' | ||||
| }) | ||||
|  | ||||
| const queryType = reactive({ k: '', v: '' }) // 订单搜索类型kv | ||||
|  | ||||
| /* | ||||
|  * 订单搜索 | ||||
|  * 订单聚合搜索 | ||||
|  * 商品名称  商品件数 全部  需要后端支持TODO | ||||
|  */ | ||||
| const searchList = ref([ | ||||
|   { value: 'no', label: '订单号' }, | ||||
|   { value: 'userId', label: '用户UID' }, | ||||
|   { value: 'userNickname', label: '用户昵称' }, | ||||
|   { value: 'userMobile', label: '用户电话' }, | ||||
|   { value: 'spuName', label: '商品名称TODO' }, | ||||
|   { value: 'itemCount', label: '商品件数TODO' } | ||||
|   { value: 'userMobile', label: '用户电话' } | ||||
| ]) | ||||
|  | ||||
| /** | ||||
|  | ||||
|  当前页/? 如果pageNo存在,则将但前数据全部按照单个选中模式取消 ,不存在,则新增全页 增加 Map.pageNo Map.roderNoList | ||||
|  单个选中  如果pagelist存在,订单号选中状态取反,并对总数按选中状态加减。如果pagelist不存在,订单号选中状态取反,并对总数按选中状态加减,增加 Map.pageNo, | ||||
|  如果当前Map.pageNo 所对应list 为空 ,清除pageNo | ||||
|  * @param command ===1 当前页 选中 ===2 所有页面选中 | ||||
|  */ | ||||
| const handleDropType = (command: string) => { | ||||
|   let i = 0 | ||||
|   //当前页按钮 | ||||
|   if (command === '1') { | ||||
|     //如果该页面有选中数据 则选中事件触发时 取消该页面 | ||||
|     if (orderSelect.selectData && orderSelect.selectData.has(queryParams.pageNo)) { | ||||
|       for (i = 0; i < list.value.length; i++) { | ||||
|         if (orderSelect.selectData.get(queryParams.pageNo)!.has(list.value[i].id)) { | ||||
|           //选中数量减少 | ||||
|           orderSelect.selectTotal -= 1 | ||||
|           //考虑全选中,针对某一页面选中当前页时 会将所有数据中去掉该页面, 需要登记到 orderSelect.unSelectList | ||||
|           unSelectListRecord(list.value[i].id, 'add') | ||||
|         } | ||||
|         list.value[i]['itemSelect'] = false | ||||
|       } | ||||
|       orderSelect.selectData.delete(queryParams.pageNo) //移除该页面 | ||||
|     } else { | ||||
|       //当前页选中状态中 默认全选中 | ||||
|       orderSelect.selectData.set(queryParams.pageNo, new Set<string>()) | ||||
|       for (i = 0; i < list.value.length; i++) { | ||||
|         list.value[i]['itemSelect'] = true | ||||
|         orderSelect.selectData.get(queryParams.pageNo)!.add(list.value[i].id) | ||||
|         //选中数量增加 | ||||
|         orderSelect.selectTotal += 1 | ||||
|         //对于登记过取消状态中的数据排除 | ||||
|         unSelectListRecord(list.value[i].id, 'del') | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   //所有页按钮 | ||||
|   if (command === '2') { | ||||
|     orderSelect.selectAllFlag = !orderSelect.selectAllFlag | ||||
|  | ||||
|     if (orderSelect.selectAllFlag) { | ||||
|       //打勾勾 //全选 | ||||
|       orderSelect.selectData?.set(queryParams.pageNo, new Set<string>()) | ||||
|       for (i = 0; i < list.value.length; i++) { | ||||
|         list.value[i]['itemSelect'] = true | ||||
|         orderSelect.selectData?.get(queryParams.pageNo)?.add(list.value[i].id) //id是主键不重复 | ||||
|       } | ||||
|       orderSelect.selectTotal = total.value | ||||
|     } else { | ||||
|       //取消勾勾 | ||||
|       for (i; i < list.value.length; i++) { | ||||
|         list.value[i]['itemSelect'] = false | ||||
|       } | ||||
|       initSelect() //重置之前选中的类容清空 | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| //对全选状态中的 单选或者当前页面单选时登记取消的数据 | ||||
| const unSelectListRecord = (id: string, op: string) => { | ||||
|   if (!orderSelect.selectAllFlag) { | ||||
|     return | ||||
|   } | ||||
|   if (op == 'add') { | ||||
|     orderSelect.unSelectList.add(id) | ||||
|   } else { | ||||
|     orderSelect.unSelectList.delete(id) | ||||
|   } | ||||
| } | ||||
| /***复选框选中 */ | ||||
| const handcheckclick = (row: any) => { | ||||
|   if (row.itemSelect) { | ||||
|     orderSelect.selectTotal += 1 | ||||
|     if (!orderSelect.selectData.has(queryParams.pageNo)) { | ||||
|       orderSelect.selectData?.set(queryParams.pageNo, new Set<string>()) | ||||
|     } | ||||
|     orderSelect.selectData?.get(queryParams.pageNo)?.add(row.id) | ||||
|     unSelectListRecord(row.id, 'del') | ||||
|   } else { | ||||
|     orderSelect.selectTotal -= 1 | ||||
|     orderSelect.selectData.get(queryParams.pageNo)?.delete(row.id) | ||||
|     unSelectListRecord(row.id, 'add') | ||||
|   } | ||||
| } | ||||
| /** | ||||
|  * 导出数据 | ||||
|  */ | ||||
|  | ||||
| const handleExport = async () => { | ||||
|   try { | ||||
|     // 导出的二次确认 | ||||
|     await message.exportConfirm() | ||||
|     //增加查询条件 用于全选时后台查询数据 | ||||
|     orderSelect.queryParams = queryParams | ||||
|  | ||||
|     // 发起导出 | ||||
|     exportLoading.value = true | ||||
|     //全选时 根据上送的条件查询所有数据,在排除unseleectList 数据, | ||||
|     //非全选时, 根据上送的selectData 直接查询数据 后台实现导出数据接口即可 | ||||
|     console.log(orderSelect) | ||||
|     download.excel(orderSelect as any, '订单信息.xls') //? | ||||
|   } catch { | ||||
|   } finally { | ||||
|     exportLoading.value = false | ||||
|   } | ||||
|   //TODO | ||||
|   exportLoading.value = false | ||||
| } | ||||
|  | ||||
| /** 搜索按钮操作 */ | ||||
| const handleQuery = () => { | ||||
|   getList() | ||||
| } | ||||
|  | ||||
| /** 重置按钮操作 */ | ||||
| const resetQuery = () => { | ||||
|   queryFormRef.value.resetFields() | ||||
|   queryType.v = '' //重置 | ||||
|   queryType.k = '' | ||||
|   //休眠0.1s 等待watch响应 | ||||
|   setTimeout(() => { | ||||
|     initSelect() //重置对选中设置恢复初始状态 | ||||
|     handleQuery() | ||||
|   }, 100) | ||||
| } | ||||
|  | ||||
| /**选中状态初始化**/ | ||||
| const initSelect = () => { | ||||
|   orderSelect.queryParams = {} as TradeOrderPageReqVO | ||||
|   orderSelect.selectTotal = 0 | ||||
|   orderSelect.selectAllFlag = false | ||||
|   orderSelect.selectData?.clear() | ||||
|   orderSelect.unSelectList?.clear() | ||||
| } | ||||
|  | ||||
| /** 查询列表 */ | ||||
| const getList = async () => { | ||||
|   loading.value = true | ||||
|   try { | ||||
|     const data = await TradeOrderApi.getOrderList(queryParams) | ||||
|     list.value = data.list | ||||
|     total.value = data.total | ||||
|     let i = 0 | ||||
|     if (orderSelect.selectData && orderSelect.selectData.has(queryParams.pageNo)) { | ||||
|       //该页面已经加载过了。直接按照之前状态设置选中状态值 | ||||
|       for (i = 0; i < list.value.length; i++) { | ||||
|         if (orderSelect.selectData.get(queryParams.pageNo)!.has(list.value[i].id)) { | ||||
|           list.value[i]['itemSelect'] = true //之前已经选取过了 | ||||
|         } else { | ||||
|           list.value[i]['itemSelect'] = false | ||||
|         } | ||||
|       } | ||||
|     } else if (orderSelect.selectAllFlag) { | ||||
|       //全选状态中 首次加载页面 默认全部选中 | ||||
|       orderSelect.selectData.set(queryParams.pageNo, new Set<string>()) | ||||
|       for (i = 0; i < list.value.length; i++) { | ||||
|         list.value[i]['itemSelect'] = true | ||||
|         orderSelect.selectData.get(queryParams.pageNo)!.add(list.value[i].id) | ||||
|       } | ||||
|     } else { | ||||
|       //非全选状态中  首次加载默认非选中状态 | ||||
|       for (i; i < list.value.length; i++) { | ||||
|         list.value[i]['itemSelect'] = false //设置状态为未选中状态 | ||||
|       } | ||||
|     } | ||||
|     // const data = await TradeOrderApi.getOrderPage(queryParams) | ||||
|     // list.value = data.list | ||||
|     // total.value = data.total | ||||
|   } finally { | ||||
|     loading.value = false | ||||
|   } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * 跳转订单详情 | ||||
|  */ | ||||
| const showOrderDetail = (row: any) => { | ||||
|   push({ name: 'TradeOrderDetail', query: { id: row.id } }) | ||||
| /** 搜索按钮操作 */ | ||||
| const handleQuery = () => { | ||||
|   queryParams.pageNo = 1 | ||||
|   getList() | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * 跳转用户详情 | ||||
|  */ | ||||
| const goUserDetail = (row: any) => { | ||||
|   console.log('TODO User Detail: ' + row.userId) | ||||
| /** 重置按钮操作 */ | ||||
| const resetQuery = () => { | ||||
|   queryFormRef.value?.resetFields() | ||||
|   handleQuery() | ||||
| } | ||||
| /** | ||||
|  * 发货 | ||||
|  */ | ||||
| const sendXX = (row: any) => { | ||||
|   console.log('TODO Send XX: ' + row.no) | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * 商品图预览 | ||||
|  * @param imgUrl | ||||
|  */ | ||||
| const imagePreview = (imgUrl: string) => { | ||||
|   imageViewerList.value = [imgUrl] | ||||
|   imgViewVisible.value = true | ||||
| } | ||||
|  | ||||
| //针对订单搜索类型和值进行调整 使用监听器 | ||||
| watch( | ||||
|   () => [queryType.k, queryType.v], | ||||
|   ([newK, newV], [oldK]) => { | ||||
|     //重置oldK对应得value | ||||
|     if (oldK != newK) { | ||||
|       if (oldK == 'no' && queryParams.no != '') { | ||||
|         queryParams.no = '' | ||||
|       } else if (oldK == 'userId' && queryParams.userId != '') { | ||||
|         queryParams.userId = '' | ||||
|       } else if (oldK == 'userNickname' && queryParams.userNickname != '') { | ||||
|         queryParams.userNickname = '' | ||||
|       } else if (oldK == 'userMobile' && queryParams.userMobile !== '') { | ||||
|         queryParams.userMobile = '' | ||||
|       } else if (oldK == 'spuName' && queryParams.spuName !== '') { | ||||
|         queryParams.spuName = '' | ||||
|       } else if (oldK == 'itemCount' && queryParams.itemCount !== '') { | ||||
|         queryParams.itemCount = '' | ||||
|       } else if (oldK == '' && queryParams.all !== '') { | ||||
|         queryParams.all = '' | ||||
|       } | ||||
|     } | ||||
|     // 根据选中得k设置Value | ||||
|     if (newK == 'no') { | ||||
|       queryParams.no = newV | ||||
|     } else if (newK == 'userId') { | ||||
|       queryParams.userId = newV | ||||
|     } else if (newK == 'userNickname') { | ||||
|       queryParams.userNickname = newV | ||||
|     } else if (newK == 'userMobile') { | ||||
|       queryParams.userMobile = newV | ||||
|     } else if (newK == 'spuName') { | ||||
|       queryParams.spuName = newV | ||||
|     } else if (newK == 'itemCount') { | ||||
|       queryParams.itemCount = newV | ||||
|     } else if (newK == '') { | ||||
|       queryParams.all = newV | ||||
|     } | ||||
|   } | ||||
| ) | ||||
|  | ||||
| /** 初始化 **/ | ||||
| onMounted(() => { | ||||
|   initSelect() | ||||
|   list.value = testData | ||||
|   getList() | ||||
| }) | ||||
| </script> | ||||
|   | ||||
							
								
								
									
										167
									
								
								src/views/mall/trade/order/testData.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								src/views/mall/trade/order/testData.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,167 @@ | ||||
| import { OrderVO } from '@/api/mall/trade/order' | ||||
|  | ||||
| export const testData: OrderVO = [ | ||||
|   { | ||||
|     id: 2, | ||||
|     no: '20230817002', | ||||
|     createTime: new Date('2023-08-17T11:30:00'), | ||||
|     type: 2, | ||||
|     terminal: 10, | ||||
|     userId: 1002, | ||||
|     userIp: '192.168.1.2', | ||||
|     userRemark: 'Urgent delivery required', | ||||
|     status: 20, | ||||
|     productCount: 2, | ||||
|     finishTime: null, | ||||
|     cancelTime: null, | ||||
|     cancelType: null, | ||||
|     remark: '', | ||||
|     payOrderId: 10002, | ||||
|     payed: false, | ||||
|     payTime: null, | ||||
|     payChannelCode: 'wx_app', | ||||
|     originalPrice: 80, | ||||
|     orderPrice: 80, | ||||
|     discountPrice: 0, | ||||
|     deliveryPrice: 5, | ||||
|     adjustPrice: 0, | ||||
|     payPrice: 85, | ||||
|     deliveryTemplateId: 2002, | ||||
|     logisticsId: null, | ||||
|     logisticsNo: '', | ||||
|     deliveryStatus: 0, | ||||
|     deliveryTime: null, | ||||
|     receiveTime: null, | ||||
|     receiverName: 'Jane Smith', | ||||
|     receiverMobile: '987-654-3210', | ||||
|     receiverAreaId: 4002, | ||||
|     receiverPostCode: 54321, | ||||
|     receiverDetailAddress: '456 Elm St, Apt 2C', | ||||
|     afterSaleStatus: 0, | ||||
|     refundPrice: 0, | ||||
|     couponId: null, | ||||
|     couponPrice: 0, | ||||
|     pointPrice: 0, | ||||
|     receiverAreaName: 'Townsville', | ||||
|     items: [ | ||||
|       { | ||||
|         id: 103, | ||||
|         userId: 1002, | ||||
|         orderId: 2, | ||||
|         spuId: 5003, | ||||
|         spuName: 'Widget C', | ||||
|         skuId: 6003, | ||||
|         picUrl: 'https://example.com/images/widget_c.jpg', | ||||
|         count: 1, | ||||
|         originalPrice: 40, | ||||
|         originalUnitPrice: 40, | ||||
|         discountPrice: 0, | ||||
|         payPrice: 40, | ||||
|         orderPartPrice: 40, | ||||
|         orderDividePrice: 40, | ||||
|         afterSaleStatus: 0, | ||||
|         properties: [ | ||||
|           { propertyId: 7001, propertyName: 'Color', valueId: 8004, valueName: 'Green' }, | ||||
|           { propertyId: 7002, propertyName: 'Size', valueId: 8002, valueName: 'Medium' } | ||||
|         ] | ||||
|       }, | ||||
|       { | ||||
|         id: 104, | ||||
|         userId: 1002, | ||||
|         orderId: 2, | ||||
|         spuId: 5004, | ||||
|         spuName: 'Widget D', | ||||
|         skuId: 6004, | ||||
|         picUrl: 'https://example.com/images/widget_d.jpg', | ||||
|         count: 1, | ||||
|         originalPrice: 40, | ||||
|         originalUnitPrice: 40, | ||||
|         discountPrice: 0, | ||||
|         payPrice: 40, | ||||
|         orderPartPrice: 40, | ||||
|         orderDividePrice: 40, | ||||
|         afterSaleStatus: 0, | ||||
|         properties: [ | ||||
|           { propertyId: 7003, propertyName: 'Color', valueId: 8005, valueName: 'Yellow' }, | ||||
|           { propertyId: 7002, propertyName: 'Size', valueId: 8002, valueName: 'Medium' } | ||||
|         ] | ||||
|       } | ||||
|     ], | ||||
|     user: { | ||||
|       id: 1002, | ||||
|       nickname: 'janesmith', | ||||
|       avatar: 'https://example.com/images/avatar.jpg' | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     id: 3, | ||||
|     no: '20230817003', | ||||
|     createTime: new Date('2023-08-17T12:00:00'), | ||||
|     type: 1, | ||||
|     terminal: 10, | ||||
|     userId: 1003, | ||||
|     userIp: '192.168.1.3', | ||||
|     userRemark: '', | ||||
|     status: 10, | ||||
|     productCount: 1, | ||||
|     finishTime: new Date('2023-08-18T09:15:00'), | ||||
|     cancelTime: null, | ||||
|     cancelType: null, | ||||
|     remark: '', | ||||
|     payOrderId: 10003, | ||||
|     payed: true, | ||||
|     payTime: new Date('2023-08-17T12:30:00'), | ||||
|     payChannelCode: 'alipay_app', | ||||
|     originalPrice: 25, | ||||
|     orderPrice: 20, | ||||
|     discountPrice: 5, | ||||
|     deliveryPrice: 5, | ||||
|     adjustPrice: 0, | ||||
|     payPrice: 20, | ||||
|     deliveryTemplateId: 2001, | ||||
|     logisticsId: 3002, | ||||
|     logisticsNo: 'DEF987654', | ||||
|     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', | ||||
|     receiverAreaId: 4003, | ||||
|     receiverPostCode: 67890, | ||||
|     receiverDetailAddress: '789 Oak Ave', | ||||
|     afterSaleStatus: 0, | ||||
|     refundPrice: 0, | ||||
|     couponId: 2001, | ||||
|     couponPrice: 5, | ||||
|     pointPrice: 0, | ||||
|     receiverAreaName: 'Villageville', | ||||
|     items: [ | ||||
|       { | ||||
|         id: 105, | ||||
|         userId: 1003, | ||||
|         orderId: 3, | ||||
|         spuId: 5005, | ||||
|         spuName: 'Widget E', | ||||
|         skuId: 6005, | ||||
|         picUrl: 'https://example.com/images/widget_e.jpg', | ||||
|         count: 1, | ||||
|         originalPrice: 20, | ||||
|         originalUnitPrice: 20, | ||||
|         discountPrice: 5, | ||||
|         payPrice: 15, | ||||
|         orderPartPrice: 15, | ||||
|         orderDividePrice: 15, | ||||
|         afterSaleStatus: 0, | ||||
|         properties: [ | ||||
|           { propertyId: 7001, propertyName: 'Color', valueId: 8006, valueName: 'Black' }, | ||||
|           { propertyId: 7002, propertyName: 'Size', valueId: 8002, valueName: 'Medium' } | ||||
|         ] | ||||
|       } | ||||
|     ], | ||||
|     user: { | ||||
|       id: 1003, | ||||
|       nickname: 'sarahjohnson', | ||||
|       avatar: 'https://example.com/images/avatar.jpg' | ||||
|     } | ||||
|   } | ||||
| ] | ||||
| @@ -1,365 +0,0 @@ | ||||
| <template> | ||||
|   <ContentWrap> | ||||
|     <!-- 订单信息 --> | ||||
|     <el-descriptions title="订单信息"> | ||||
|       <el-descriptions-item label="订单号: ">{{ order.no }}</el-descriptions-item> | ||||
|       <el-descriptions-item label="配送方式: ">物流配送</el-descriptions-item> | ||||
|       <!-- TODO 芋艿:待实现 --> | ||||
|       <el-descriptions-item label="营销活动: ">物流配送</el-descriptions-item> | ||||
|       <!-- TODO 芋艿:待实现 --> | ||||
|       <el-descriptions-item label="订单类型: "> | ||||
|         <dict-tag :type="DICT_TYPE.TRADE_ORDER_TYPE" :value="order.type" /> | ||||
|       </el-descriptions-item> | ||||
|       <el-descriptions-item label="收货人: ">{{ order.receiverName }}</el-descriptions-item> | ||||
|       <el-descriptions-item label="买家留言: ">{{ order.userRemark }}</el-descriptions-item> | ||||
|       <el-descriptions-item label="订单来源: "> | ||||
|         <dict-tag :type="DICT_TYPE.TERMINAL" :value="order.terminal" /> | ||||
|       </el-descriptions-item> | ||||
|       <el-descriptions-item label="联系电话: ">{{ order.receiverMobile }}</el-descriptions-item> | ||||
|       <el-descriptions-item label="商家备注: ">{{ order.remark }}</el-descriptions-item> | ||||
|       <el-descriptions-item label="支付单号: ">{{ order.payOrderId }}</el-descriptions-item> | ||||
|       <el-descriptions-item label="付款方式: "> | ||||
|         <dict-tag :type="DICT_TYPE.PAY_CHANNEL_CODE_TYPE" :value="order.payChannelCode" /> | ||||
|       </el-descriptions-item> | ||||
|       <!-- <el-descriptions-item label="买家: ">{{ order.user.nickname }}</el-descriptions-item> --> | ||||
|       <!-- TODO 芋艿:待实现:跳转会员 --> | ||||
|       <el-descriptions-item label="收货地址: "> | ||||
|         {{ order.receiverAreaName }} {{ order.receiverDetailAddress }} | ||||
|         <el-link | ||||
|           v-clipboard:copy="order.receiverAreaName + ' ' + order.receiverDetailAddress" | ||||
|           v-clipboard:success="clipboardSuccess" | ||||
|           icon="ep:document-copy" | ||||
|           type="primary" | ||||
|         /> | ||||
|       </el-descriptions-item> | ||||
|     </el-descriptions> | ||||
|  | ||||
|     <!-- 订单状态 --> | ||||
|     <el-descriptions title="订单状态" :column="1"> | ||||
|       <el-descriptions-item label="订单状态: "> | ||||
|         <!-- TODO xiaobai:status 一定有值哈,不用判断 --> | ||||
|         <dict-tag | ||||
|           v-if="order.status !== ''" | ||||
|           :type="DICT_TYPE.TRADE_ORDER_STATUS" | ||||
|           :value="order.status" | ||||
|         /> | ||||
|       </el-descriptions-item> | ||||
|       <el-descriptions-item label-class-name="no-colon"> | ||||
|         <el-button type="primary" size="small">调整价格</el-button> | ||||
|         <!-- TODO 芋艿:待实现 --> | ||||
|         <el-button type="primary" size="small">备注</el-button> | ||||
|         <!-- TODO 芋艿:待实现 --> | ||||
|         <el-button type="primary" size="small">发货</el-button> | ||||
|         <!-- TODO 芋艿:待实现 --> | ||||
|         <el-button type="primary" size="small">关闭订单</el-button> | ||||
|         <!-- TODO 芋艿:待实现 --> | ||||
|         <el-button type="primary" size="small">修改地址</el-button> | ||||
|         <!-- TODO 芋艿:待实现 --> | ||||
|         <el-button type="primary" size="small">打印电子面单</el-button> | ||||
|         <!-- TODO 芋艿:待实现 --> | ||||
|         <el-button type="primary" size="small">打印发货单</el-button> | ||||
|         <!-- TODO 芋艿:待实现 --> | ||||
|         <el-button type="primary" size="small">确认收货</el-button> | ||||
|         <!-- TODO 芋艿:待实现 --> | ||||
|       </el-descriptions-item> | ||||
|       <el-descriptions-item> | ||||
|         <template #label><span style="color: red">提醒: </span></template> | ||||
|         买家付款成功后,货款将直接进入您的商户号(微信、支付宝)<br /> | ||||
|         请及时关注你发出的包裹状态,确保可以配送至买家手中 <br /> | ||||
|         如果买家表示没收到货或货物有问题,请及时联系买家处理,友好协商 | ||||
|       </el-descriptions-item> | ||||
|     </el-descriptions> | ||||
|  | ||||
|     <!-- 物流信息 TODO --> | ||||
|  | ||||
|     <!-- 商品信息 --> | ||||
|     <el-descriptions title="商品信息"> | ||||
|       <el-descriptions-item labelClassName="no-colon"> | ||||
|         <el-row :gutter="20"> | ||||
|           <el-col :span="15"> | ||||
|             <el-table :data="order.items" border> | ||||
|               <el-table-column prop="spuName" label="商品" width="auto"> | ||||
|                 <template #default="{ row }"> | ||||
|                   {{ row.spuName }} | ||||
|                   <el-tag | ||||
|                     size="medium" | ||||
|                     v-for="property in row.properties" | ||||
|                     :key="property.propertyId" | ||||
|                   > | ||||
|                     {{ property.propertyName }}: {{ property.valueName }}</el-tag | ||||
|                   > | ||||
|                 </template> | ||||
|               </el-table-column> | ||||
|               <el-table-column prop="price" label="商品原价(元)" width="150"> | ||||
|                 <template #default="{ row }"> ¥{{ (row.price / 100.0).toFixed(2) }} </template> | ||||
|               </el-table-column> | ||||
|               <el-table-column prop="count" label="数量" width="100" /> | ||||
|               <el-table-column prop="payPrice" label="合计(元)" width="150"> | ||||
|                 <template #default="{ row }"> ¥{{ (row.payPrice / 100.0).toFixed(2) }} </template> | ||||
|               </el-table-column> | ||||
|               <el-table-column prop="afterSaleStatus" label="售后状态" width="auto"> | ||||
|                 <template #default="{ row }"> | ||||
|                   <dict-tag | ||||
|                     :type="DICT_TYPE.TRADE_ORDER_ITEM_AFTER_SALE_STATUS" | ||||
|                     :value="row.afterSaleStatus" | ||||
|                   /> | ||||
|                 </template> | ||||
|               </el-table-column> | ||||
|             </el-table> | ||||
|           </el-col> | ||||
|           <el-col :span="10" /> | ||||
|         </el-row> | ||||
|       </el-descriptions-item> | ||||
|       <!-- 占位 --> | ||||
|       <!-- <el-descriptions-item v-for="item in 5" label-class-name="no-colon" :key="item" /> --> | ||||
|     </el-descriptions> | ||||
|     <el-descriptions column="6"> | ||||
|       <el-descriptions-item label="商品总额: "> | ||||
|         <!-- TODO xiaobai: 是不是 (item.payPrice / 100.0).toFixed(2) --> | ||||
|         ¥{{ parseFloat((order.totalPrice / 100.0) as unknown as string).toFixed(2) }} | ||||
|       </el-descriptions-item> | ||||
|       <el-descriptions-item label="运费金额: "> | ||||
|         ¥{{ parseFloat((order.deliveryPrice / 100.0) as unknown as string).toFixed(2) }} | ||||
|       </el-descriptions-item> | ||||
|       <el-descriptions-item label="订单调价: "> | ||||
|         ¥{{ | ||||
|           parseFloat((order.adjustPrice / 100.0) as unknown as string).toFixed(2) | ||||
|         }}</el-descriptions-item | ||||
|       > | ||||
|  | ||||
|       <el-descriptions-item> | ||||
|         <template #label><span style="color: red">商品优惠: </span></template> | ||||
|         <!-- 没理解TODO  order.totalPrice - order.totalPrice --> | ||||
|         ¥{{ | ||||
|           parseFloat(((order.totalPrice - order.totalPrice) / 100.0) as unknown as string).toFixed( | ||||
|             2 | ||||
|           ) | ||||
|         }} | ||||
|       </el-descriptions-item> | ||||
|       <el-descriptions-item> | ||||
|         <template #label><span style="color: red">订单优惠: </span></template> | ||||
|         ¥{{ parseFloat((order.discountPrice / 100.0) as unknown as string).toFixed(2) }} | ||||
|       </el-descriptions-item> | ||||
|       <el-descriptions-item> | ||||
|         <template #label><span style="color: red">积分抵扣: </span></template> | ||||
|         ¥{{ parseFloat((order.pointPrice / 100.0) as unknown as string).toFixed(2) }} | ||||
|       </el-descriptions-item> | ||||
|  | ||||
|       <el-descriptions-item v-for="item in 5" label-class-name="no-colon" :key="item" /> | ||||
|       <!-- 占位 --> | ||||
|       <el-descriptions-item label="应付金额: "> | ||||
|         ¥{{ (order.payPrice / 100.0).toFixed(2) }} | ||||
|       </el-descriptions-item> | ||||
|     </el-descriptions> | ||||
|  | ||||
|     <!-- TODO 芋艿:需要改改 --> | ||||
|     <div v-for="group in detailGroups" :key="group.title"> | ||||
|       <el-descriptions v-bind="group.groupProps" :title="group.title"> | ||||
|         <!-- 订单操作日志 --> | ||||
|         <el-descriptions-item v-if="group.key === 'orderLog'" labelClassName="no-colon"> | ||||
|           <el-timeline> | ||||
|             <el-timeline-item | ||||
|               v-for="activity in detailInfo[group.key]" | ||||
|               :key="activity.timestamp" | ||||
|               :timestamp="activity.timestamp" | ||||
|             > | ||||
|               {{ activity.content }} | ||||
|             </el-timeline-item> | ||||
|           </el-timeline> | ||||
|         </el-descriptions-item> | ||||
|  | ||||
|         <!-- 物流信息 --> | ||||
|         <!-- TODO @xiaobai:改成一个包裹哈;目前只允许发货一次 --> | ||||
|         <el-descriptions-item v-if="group.key === 'expressInfo'" labelClassName="no-colon"> | ||||
|           <!-- 循环包裹物流信息 --> | ||||
|           <div v-show="(pkgInfo = detailInfo[group.key]) !== null" style="border: 1px dashed"> | ||||
|             <!-- 包裹详情 --> | ||||
|             <el-descriptions class="m-5"> | ||||
|               <el-descriptions-item | ||||
|                 v-for="(pkgChild, pkgCIdx) in group.children" | ||||
|                 v-bind="pkgChild.childProps" | ||||
|                 :key="`pkgChild_${pkgCIdx}`" | ||||
|                 :label="pkgChild.label" | ||||
|               > | ||||
|                 <!-- 包裹商品列表 --> | ||||
|                 <template v-if="pkgChild.valueKey === 'goodsList' && pkgInfo[pkgChild.valueKey]"> | ||||
|                   <div | ||||
|                     v-for="(goodInfo, goodInfoIdx) in pkgInfo[pkgChild.valueKey]" | ||||
|                     :key="`goodInfo_${goodInfoIdx}`" | ||||
|                     style="display: flex" | ||||
|                   > | ||||
|                     <el-image | ||||
|                       style="width: 100px; height: 100px; flex: none" | ||||
|                       :src="goodInfo.imgUrl" | ||||
|                     /> | ||||
|                     <el-descriptions :column="1"> | ||||
|                       <el-descriptions-item labelClassName="no-colon">{{ | ||||
|                         goodInfo.name | ||||
|                       }}</el-descriptions-item> | ||||
|                       <el-descriptions-item label="数量">{{ goodInfo.count }}</el-descriptions-item> | ||||
|                     </el-descriptions> | ||||
|                   </div> | ||||
|                 </template> | ||||
|  | ||||
|                 <!-- 包裹物流详情 --> | ||||
|                 <template v-else-if="pkgChild.valueKey === 'wlxq'"> | ||||
|                   <el-row :gutter="10"> | ||||
|                     <el-col :span="6" :offset="1"> | ||||
|                       <el-timeline> | ||||
|                         <el-timeline-item | ||||
|                           v-for="(activity, index) in pkgInfo[pkgChild.valueKey]" | ||||
|                           :key="index" | ||||
|                           :timestamp="activity.timestamp" | ||||
|                         > | ||||
|                           {{ activity.content }} | ||||
|                         </el-timeline-item> | ||||
|                       </el-timeline> | ||||
|                     </el-col> | ||||
|                   </el-row> | ||||
|                 </template> | ||||
|                 <template v-else> | ||||
|                   {{ pkgInfo[pkgChild.valueKey] }} | ||||
|                 </template> | ||||
|               </el-descriptions-item> | ||||
|             </el-descriptions> | ||||
|           </div> | ||||
|         </el-descriptions-item> | ||||
|       </el-descriptions> | ||||
|     </div> | ||||
|   </ContentWrap> | ||||
| </template> | ||||
| <script lang="ts" name="TradeOrderDetail" setup> | ||||
| // TODO @xiaobai:在 order 下创建一个 order/detail,然后改名为 index.vue | ||||
| import { DICT_TYPE } from '@/utils/dict' | ||||
| import * as TradeOrderApi from '@/api/mall/trade/order' | ||||
| const message = useMessage() // 消息弹窗 | ||||
|  | ||||
| const { query } = useRoute() | ||||
| const queryParams = reactive({ | ||||
|   id: query.id | ||||
| }) | ||||
| const dialogVisible = ref(false) | ||||
| const loading = ref(false) | ||||
| const order = ref<any>({ | ||||
|   items: [], | ||||
|   user: {} | ||||
| }) // 详情数据 | ||||
|  | ||||
| const detailGroups = ref([ | ||||
|   { | ||||
|     title: '物流信息', | ||||
|     key: 'expressInfo', | ||||
|     children: [ | ||||
|       { label: '发货时间: ', valueKey: 'fhsj' }, | ||||
|       { label: '物流公司: ', valueKey: 'wlgs' }, | ||||
|       { label: '运单号: ', valueKey: 'ydh' }, | ||||
|       { label: '物流状态: ', valueKey: 'wlzt', childProps: { span: 3 } }, | ||||
|       { label: '物流详情: ', valueKey: 'wlxq' } | ||||
|     ] | ||||
|   }, | ||||
|   { | ||||
|     title: '订单操作日志', | ||||
|     key: 'orderLog' | ||||
|   } | ||||
| ]) | ||||
|  | ||||
| const detailInfo = ref({ | ||||
|   expressInfo: | ||||
|     // 物流信息 | ||||
|     { | ||||
|       label: '包裹1', | ||||
|       name: 'bg1', | ||||
|       fhsj: '2022-11-03 16:50:45', | ||||
|       wlgs: '极兔', | ||||
|       ydh: '2132123', | ||||
|       wlzt: '不支持此快递公司', | ||||
|       wlxq: [ | ||||
|         { | ||||
|           content: '正在派送途中,请您准备签收(派件人:王涛,电话:13854563814)', | ||||
|           timestamp: '2018-04-15 15:00:16' | ||||
|         }, | ||||
|         { | ||||
|           content: '快件到达 【烟台龙口东江村委营业点】', | ||||
|           timestamp: '2018-04-13 14:54:19' | ||||
|         }, | ||||
|         { | ||||
|           content: '快件已发车', | ||||
|           timestamp: '2018-04-11 12:55:52' | ||||
|         }, | ||||
|         { | ||||
|           content: '快件已发车', | ||||
|           timestamp: '2018-04-11 12:55:52' | ||||
|         }, | ||||
|         { | ||||
|           content: '快件已发车', | ||||
|           timestamp: '2018-04-11 12:55:52' | ||||
|         } | ||||
|       ] | ||||
|     }, | ||||
|   orderLog: [ | ||||
|     // 订单操作日志 | ||||
|     { | ||||
|       content: '买家【乌鸦】关闭了订单', | ||||
|       timestamp: '2018-04-15 15:00:16' | ||||
|     }, | ||||
|     { | ||||
|       content: '买家【乌鸦】下单了', | ||||
|       timestamp: '2018-04-15 15:00:16' | ||||
|     } | ||||
|   ], | ||||
|   goodsInfo: [] // 商品详情tableData | ||||
| }) | ||||
| // 暂考虑一次性加载详情页面所有数据 TODO | ||||
| const getlist = async () => { | ||||
|   dialogVisible.value = true | ||||
|   loading.value = true | ||||
|   try { | ||||
|     const res = await TradeOrderApi.getOrderDetail(queryParams.id as unknown as number) | ||||
|     order.value = res | ||||
|     console.log(order) | ||||
|   } catch { | ||||
|     message.error('获取详情数据失败') | ||||
|   } finally { | ||||
|     loading.value = false | ||||
|   } | ||||
| } | ||||
| onMounted(async () => { | ||||
|   await getlist() | ||||
| }) | ||||
| const clipboardSuccess = () => { | ||||
|   message.success('复制成功') | ||||
| } | ||||
| </script> | ||||
| <style lang="scss" scoped> | ||||
| :deep(.el-descriptions) { | ||||
|   &:not(:nth-child(1)) { | ||||
|     margin-top: 20px; | ||||
|   } | ||||
|  | ||||
|   .el-descriptions__title { | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|  | ||||
|     &::before { | ||||
|       display: inline-block; | ||||
|       width: 3px; | ||||
|       height: 20px; | ||||
|       margin-right: 10px; | ||||
|       background-color: #409eff; | ||||
|       content: ''; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .el-descriptions-item__container { | ||||
|     margin: 0 10px; | ||||
|  | ||||
|     .no-colon { | ||||
|       margin: 0; | ||||
|  | ||||
|       &::after { | ||||
|         content: ''; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </style> | ||||
		Reference in New Issue
	
	Block a user
	 puhui999
					puhui999