!174 订单列表和详情 页面

Merge pull request !174 from 矿泉水/dev
This commit is contained in:
芋道源码
2023-06-23 13:23:02 +00:00
committed by Gitee
5 changed files with 458 additions and 498 deletions

View File

@ -12,7 +12,7 @@
<el-select class="!w-280px" v-model="queryParams.status" clearable placeholder="全部">
<el-option
v-for="dict in getStrDictOptions(DICT_TYPE.TRADE_ORDER_STATUS)"
:key="dict.value"
:key="(dict.value as string)"
:label="dict.label"
:value="dict.value"
/>
@ -27,7 +27,7 @@
>
<el-option
v-for="dict in getStrDictOptions(DICT_TYPE.PAY_CHANNEL_CODE_TYPE)"
:key="dict.value"
:key="(dict.value as string)"
:label="dict.label"
:value="dict.value"
/>
@ -45,10 +45,10 @@
/>
</el-form-item>
<el-form-item label="订单来源" prop="terminal">
<el-select class="!w-280px" v-model="queryParams.terminal" clearable placeholder="全部TODO">
<el-select class="!w-280px" v-model="queryParams.terminal" clearable placeholder="全部">
<el-option
v-for="dict in getStrDictOptions(DICT_TYPE.TERMINAL)"
:key="dict.value"
:key="(dict.value as string)"
:label="dict.label"
:value="dict.value"
/>
@ -58,66 +58,60 @@
<el-select class="!w-280px" v-model="queryParams.type" clearable placeholder="全部">
<el-option
v-for="dict in getStrDictOptions(DICT_TYPE.TRADE_ORDER_TYPE)"
:key="dict.value"
:key="(dict.value as string)"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="订单搜索" prop="searchValue">
<!-- item 绑定 2 个变量用于 reset 时没法重置 -->
<el-form-item class="!w-280px" prop="searchType">
<el-input
class="!w-280px"
v-model="queryParams.searchValue"
clearable
placeholder="请输入TODO"
>
<template #prepend>
<el-select
style="width: 100px"
v-model="queryParams.searchType"
clearable
placeholder="全部"
>
<el-option
v-for="dict in searchList"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</template>
</el-input>
</el-form-item>
<el-form-item label="订单搜索">
<el-input
v-show="true"
class="!w-280px"
v-model="queryType.v"
clearable
placeholder="请输入"
>
<template #prepend>
<el-select style="width: 110px" v-model="queryType.k" clearable placeholder="全部">
<el-option
v-for="dict in searchList"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</template>
</el-input>
</el-form-item>
<el-form-item>
<el-button @click="handleQuery">
<el-button @click="handleQuery" v-hasPermi="['trade:order:query']">
<Icon class="mr-5px" icon="ep:search" />
搜索
</el-button>
<el-button @click="resetQuery">
<el-button @click="resetQuery" v-hasPermi="['trade:order:query']">
<Icon class="mr-5px" icon="ep:refresh" />
重置
</el-button>
<!-- v-hasPermi="['trade:order:export']" TODO 待开发
需要将选中的数据存入orderSelect.multipleSelection中
需要考虑全选时数据如何处理-->
<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">
<template #default="scope">
<el-descriptions class="mx-40">
<el-descriptions-item label="商品原价(总): ">{{
'¥ ' + parseFloat(scope.row.originalPrice / 100).toFixed(2) + ' 元'
'¥ ' +
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
@ -130,11 +124,11 @@
</el-descriptions>
</template>
</el-table-column>
<!-- <el-table-column label="全选" type="selection" width="55" fixed="left">x</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.checkTotal }}) </el-button>
<el-button link type="primary">全选({{ orderSelect.selectTotal }}) </el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="1">当前页</el-dropdown-item>
@ -160,6 +154,20 @@
<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
@ -170,14 +178,7 @@
<span v-else>{{ scope.terminal }}</span>
</template>
</el-table-column>
<el-table-column label="用户信息" align="center" min-width="100">
<!-- TODO xiaobai展示昵称跳转到用户详情 -->
<template #default="scope">
<el-button link type="primary" @click="goUserDetail(scope.row)">{{
scope.row.userId
}}</el-button>
</template>
</el-table-column>
<el-table-column label="商品信息" align="left" min-width="200" prop="items">
<template #default="scope">
<el-popover
@ -204,18 +205,21 @@
<div v-for="item in scope.row.items" :key="item">
<div>
<p>{{ item.spuName }}</p>
<!-- TODO @xiaobai不用 parseFloat 操作直接 / 100.0 -->
<p>{{
'¥ ' + parseFloat(item.payPrice / 100).toFixed(2) + '元 x ' + item.count
'¥ ' +
parseFloat((item.payPrice / 100) as unknown as string).toFixed(2) +
'元 x ' +
item.count
}}</p>
</div>
</div>
</el-popover>
</template>
</el-table-column>
<el-table-column label="实际支付(元)" align="center" prop="payPrice" min-width="100">
<template #default="scope">
{{ '¥ ' + parseFloat(scope.row.payPrice / 100).toFixed(2) }}
{{ '¥ ' + parseFloat((scope.row.payPrice / 100) as unknown as string).toFixed(2) }}
</template>
</el-table-column>
<el-table-column
@ -225,7 +229,6 @@
prop="payTime"
min-width="180"
/>
<!-- TODO @xiaobai增加一个 createTime 时间的展示 -->
<el-table-column label="支付类型" align="center" min-width="100" prop="payChannelCode">
<template #default="scope">
<dict-tag
@ -237,9 +240,8 @@
</el-table-column>
<el-table-column label="订单状态" align="center" prop="status" min-width="100">
<template #default="scope">
<!-- TODO @xiaobai不用做判断直接 dict-tag 渲染就好列 -->
<dict-tag
v-if="scope.row.status === ''"
v-if="scope.row.status !== ''"
:type="DICT_TYPE.TRADE_ORDER_STATUS"
:value="scope.row.status"
/>
@ -248,16 +250,16 @@
</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 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>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination
v-model:limit="queryParams.pageSize"
@ -275,198 +277,155 @@
<script setup lang="ts" name="OrderList">
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'
const message = useMessage() // 消息弹窗
const { push } = useRouter() // 路由
interface CurrentType {
checkTotal: number //选中的数量
currentType: string //页面选中类型, 0-noPage无选中页面 1-currentPage 当前页面 2-allPage所有页面
selectAll: boolean //全选标识
multipleSelection: [] // 选中的数据 暂未记录,需考虑全选时数据应该如何处理 ,部分选中可以使用该数据,需要登记
pageNoList: [] //当前页面选中的页号 如果再次选中当前页将取消本页面的选中数据 全选时 将所有的页面list 都放进去 再次全选时 全部清空
}
const orderSelect: CurrentType = reactive({
checkTotal: 0,
currentType: '0',
selectAll: false,
multipleSelection: [],
pageNoList: []
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 orderSelect: SelectType = reactive({
queryParams: {} as TradeOrderPageReqVO,
selectTotal: 0,
selectAllFlag: false,
selectData: new Map<number, Set<string>>(),
unSelectList: new Set<string>()
})
const loading = ref(false) // 列表的加载中
const total = ref(0) // 总记录数
const list = ref<any>([]) // 表数据
const queryFormRef = ref() //表单搜索
const queryParams = ref({
pageNo: 1, // 首页
pageSize: 10, // 页面大小
tabIndex: 0 // 详情页面数据
//表单搜索
const queryParams: TradeOrderPageReqVO = reactive({
pageNo: 1, //首页
pageSize: 10 //页面大小
})
const exportLoading = ref(false) // 导出按钮的加载中
// 订单搜索
const queryType = reactive({ k: '', v: '' }) // 订单搜索类型kv
/*
* 订单搜索
* 商品名称 商品件数 全部 需要后端支持TODO
*/
const searchList = ref([
{
value: 'orderNo',
label: '订单号'
},
{
value: 'userId',
label: '用户UID'
},
{
value: 'userName', // TODO @xiaobaiuserNickname
label: '用户姓名'
},
{
value: 'userTel', // TODO @xiaobaiuserMobile 改成
label: '用户电话'
},
{
value: 'itemName', // TODO @xiaobai不用筛选
label: '商品名称'
},
{
value: 'itemCount', // TODO @xiaobai件数不用筛选好列
label: '商品件数'
}
{ value: 'no', label: '订单号' },
{ value: 'userId', label: '用户UID' },
{ value: 'userNickname', label: '用户昵称' },
{ value: 'userMobile', label: '用户电话' },
{ value: 'spuName', label: '商品名称TODO' },
{ value: 'itemCount', label: '商品件数TODO' }
])
const imgViewVisible = ref(false) // 商品图预览
/**
const imageViewerList = ref<string[]>([]) // 商品图预览列表
// TODO @xiaobai要不全选逻辑先不做
/**当前页 所有页 暂不考虑数据本地化 会导致选中当前页 从后台重新拉取数据时出现数据不一致*/
当前页/ 如果pageNo存在则将但前数据全部按照单个选中模式取消 ,不存在,则新增全页 增加 Map.pageNo Map.roderNoList
单个选中 如果pagelist存在订单号选中状态取反并对总数按选中状态加减。如果pagelist不存在订单号选中状态取反并对总数按选中状态加减增加 Map.pageNo
如果当前Map.pageNo 所对应list 为空 清除pageNo
* @param command ===1 当前页 选中 ===2 所有页面选中
*/
const handleDropType = (command: string) => {
orderSelect.currentType = command
let i = 0
//当前页按钮
if (command === '1') {
// pageNoList 当前页面选中的页号 如果再次选中当前页将取消页面的选中数据
//取消本页面记录
var index = orderSelect.pageNoList.indexOf(queryParams.value.pageNo)
if (index > -1) {
for (i; i < list.value.length; i++) {
if (list.value[i]['itemSelect'] === true) {
list.value[i]['itemSelect'] = false
orderSelect.checkTotal = orderSelect.checkTotal - 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.pageNoList.splice(index, 1)
orderSelect.selectData.delete(queryParams.pageNo) //移除该页面
} else {
for (i; i < list.value.length; i++) {
if (list.value[i]['itemSelect'] === false) {
list.value[i]['itemSelect'] = true
orderSelect.checkTotal = orderSelect.checkTotal + 1
}
//当前页选中状态中 默认全选中
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')
}
orderSelect.pageNoList.splice(0, 0, queryParams.value.pageNo)
}
}
//所有页按钮
if (command === '2') {
orderSelect.selectAll = !orderSelect.selectAll
//全选时 将所有的页面list 都放进去 再次全选时 全部清空
if (orderSelect.selectAll) {
//打勾勾
for (i; i < list.value.length; i++) {
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是主键不重复
}
// 初始化页面数组
const array1: [] = Array.from(
{ length: total.value / queryParams.value.pageSize + 1 },
(item, idx) => idx + 1
)
orderSelect.pageNoList = [] //清空原有的
orderSelect.pageNoList = [].concat(array1)
orderSelect.checkTotal = total.value
orderSelect.selectTotal = total.value
} else {
//取消勾勾
for (i; i < list.value.length; i++) {
list.value[i]['itemSelect'] = false
}
orderSelect.pageNoList = [] //清空
orderSelect.checkTotal = 0
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) => {
//选中增加1
if (!row.itemSelect) {
// 取消 -1
orderSelect.checkTotal = orderSelect.checkTotal - 1
//
} else {
//选中 +1
orderSelect.checkTotal = orderSelect.checkTotal + 1
}
}
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
const data = await TradeOrderApi.getOrderList(queryParams.value)
list.value = data.list
total.value = data.total
let i = 0
//给数组添加选中属性 itemSelect 默认为false 当前状态如果时全选 则新加载的页面都为选中状态
if (
orderSelect.currentType === '2' || //全选状态加载状态设置为选中
orderSelect.pageNoList.indexOf(queryParams.value.pageNo) > -1 //已选择页面加载状态设置为默认选中,会存在选中当前页面后手动取消该页面部分数据,再重新加载该页面时设置为选中状态,但是没有增加选中的数量
) {
for (i; i < list.value.length; i++) {
list.value[i]['itemSelect'] = true
}
} else {
//还需要判断当前页面是否已经选中了? 而且还要出来选中的数据是否后来手动一行行取消了处理
for (i; i < list.value.length; i++) {
list.value[i]['itemSelect'] = false //暂定为未选中状态, 实际情况需要考虑已选中状态,后期优化
}
if (row.itemSelect) {
orderSelect.selectTotal += 1
if (!orderSelect.selectData.has(queryParams.pageNo)) {
orderSelect.selectData?.set(queryParams.pageNo, new Set<string>())
}
} finally {
loading.value = false
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 handleQuery = () => {
//选中状态初始化
orderSelect.checkTotal = 0
orderSelect.currentType = '0'
orderSelect.multipleSelection = []
orderSelect.pageNoList = []
orderSelect.selectAll = false
// queryParams.pageNo = 1 TODO @xiaobai缺了个
getList()
}
/** 重置按钮操作 */
const resetQuery = () => {
//选中状态初始化
orderSelect.checkTotal = 0
orderSelect.currentType = '0'
orderSelect.multipleSelection = []
orderSelect.pageNoList = []
orderSelect.selectAll = false
queryFormRef.value.resetFields()
handleQuery()
}
/**
* 导出数据
*/
const handleExport = async () => {
try {
// 导出的二次确认
await message.exportConfirm()
//增加查询条件 用于全选时后台查询数据
orderSelect.queryParams = queryParams
// 发起导出
exportLoading.value = true
//TODO导出的数据是后台导出还是从前端中获取数据(全选时数据怎么打印?)
download.excel(orderSelect.multipleSelection as any, '订单信息.xls') //
//全选时 根据上送的条件查询所有数据在排除unseleectList 数据,
//非全选时, 根据上送的selectData 直接查询数据 后台实现导出数据接口即可
console.log(orderSelect)
download.excel(orderSelect as any, '订单信息.xls') //?
} catch {
} finally {
exportLoading.value = false
@ -475,32 +434,86 @@ const handleExport = async () => {
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 //设置状态为未选中状态
}
}
} finally {
loading.value = false
}
}
/**
* 跳转订单详情
*/
const showOrderDetail = (row: any) => {
push({
name: 'TradeOrderDetail',
query: {
id: row.id
}
})
push({ name: 'TradeOrderDetail', query: { id: row.id } })
}
/**
* 跳转用户详情 TODO
* 跳转用户详情
*/
const goUserDetail = (row: any) => {
console.log('TODO User Detail: ' + row.userId)
}
/**
* 发货 TODO
* 发货
*/
const sendXX = (row: any) => {
console.log('TODO Send XX: ' + row.no)
}
// TOPDO @xiaobaihttps://kailong110120130.gitee.io/vue-element-plus-admin-doc/components/image-viewer.html 使用这个组件哈
/**
* 商品图预览
* @param imgUrl
@ -510,8 +523,50 @@ const imagePreview = (imgUrl: string) => {
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()
getList()
})
</script>

View File

@ -1,141 +0,0 @@
<template>
<el-drawer v-model="drawerVisiable" width="50%">
<el-form inline="true">
<el-form-item>
<div>
<span text="普通订单:">普通订单:</span>
<span text="订单号: ">1111112546</span>
</div>
</el-form-item>
<el-form-item> <el-button type="primary" icon="search">发送货</el-button></el-form-item>
<el-form-item><el-button type="success" icon="search">小票打印</el-button> </el-form-item>
<el-form-item>
<el-dropdown @command="handleCommand">
<el-button> ... </el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="remark">订单备注</el-dropdown-item>
<el-dropdown-item command="b">立即退款</el-dropdown-item>
<el-dropdown-item command="print">打印配货单</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-form-item>
</el-form>
<el-descriptions class="m-10" direction="vertical" column="4">
<el-descriptions-item label="订单状态">未发货TODO</el-descriptions-item>
<el-descriptions-item label="实际支付">1000 TODO</el-descriptions-item>
<el-descriptions-item label="支付方式">手机支付</el-descriptions-item>
<el-descriptions-item label="支付时间"> {{ formatDate(Date()) }}</el-descriptions-item>
</el-descriptions>
<el-tabs @tab-click="handleClick">
<el-tab-pane label="订单信息">
<el-descriptions title="订单信息">
<el-descriptions-item label="用户UID: ">kooriookami</el-descriptions-item>
<el-descriptions-item label="用户昵称: ">18100000000</el-descriptions-item>
<el-descriptions-item label="绑定电话: ">Suzhou</el-descriptions-item>
</el-descriptions>
<el-divider border-style="dashed" />
<el-descriptions title="收货信息" column="1">
<el-descriptions-item label="收货人: ">kooriookami</el-descriptions-item>
<el-descriptions-item label="收货电话: ">18100000000</el-descriptions-item>
<el-descriptions-item label="收货地址: ">{{ detailData }}</el-descriptions-item>
</el-descriptions>
<el-divider border-style="dashed" />
<el-descriptions title="供应商信息">
<el-descriptions-item label="供应商: ">kooriookami</el-descriptions-item>
<el-descriptions-item label="供应商姓名: ">18100000000</el-descriptions-item>
<el-descriptions-item label="联系方式: ">Suzhou</el-descriptions-item>
<el-descriptions-item label="供应商邮箱: ">Suzhou</el-descriptions-item>
</el-descriptions>
<el-divider border-style="dashed" />
<el-descriptions title="订单信息">
<el-descriptions-item label="创建时间: "> {{ formatDate(Date()) }} </el-descriptions-item>
<el-descriptions-item label="商品总数: ">18100000000</el-descriptions-item>
<el-descriptions-item label="商品总价: ¥">200.00 </el-descriptions-item>
<el-descriptions-item label="优惠券金额: ¥">200.00 </el-descriptions-item>
<el-descriptions-item label="积分抵扣: ">200.00</el-descriptions-item>
<el-descriptions-item label="支付邮费: ¥">200.00 </el-descriptions-item>
<el-descriptions-item label="会员商品优惠: ¥">200.00 </el-descriptions-item>
<el-descriptions-item label="推广人: ¥">200.00 </el-descriptions-item>
<el-descriptions-item label="支付时间: "> {{ formatDate(Date()) }} </el-descriptions-item>
<el-descriptions-item label="支付方式: ¥">200.00 </el-descriptions-item>
</el-descriptions>
<el-divider v-if="true" border-style="dashed" />
<el-descriptions v-if="true" title="订单备注">
<el-descriptions-item label="备注: ">TODO</el-descriptions-item>
</el-descriptions>
</el-tab-pane>
<el-tab-pane label="商品信息">
<el-descriptions title="商品信息">
<el-descriptions-item label="用户UID: ">kooriookami</el-descriptions-item>
<el-descriptions-item label="用户昵称: ">18100000000</el-descriptions-item>
<el-descriptions-item label="绑定电话: ">Suzhou</el-descriptions-item>
</el-descriptions>
</el-tab-pane>
<el-tab-pane label="订单记录">
<el-descriptions title="订单记录">
<el-descriptions-item label="用户UID: ">kooriookami</el-descriptions-item>
<el-descriptions-item label="用户昵称: ">18100000000</el-descriptions-item>
<el-descriptions-item label="绑定电话: ">Suzhou</el-descriptions-item>
</el-descriptions>
</el-tab-pane>
<el-tab-pane label="发货记录">
<el-descriptions title="发货记录">
<el-descriptions-item label="用户UID: ">kooriookami</el-descriptions-item>
<el-descriptions-item label="用户昵称: ">18100000000</el-descriptions-item>
<el-descriptions-item label="绑定电话: ">Suzhou</el-descriptions-item>
</el-descriptions>
</el-tab-pane>
</el-tabs>
</el-drawer>
</template>
<script lang="ts" name="tradeOrderDetail-crmeb" setup>
import { formatDate } from '@/utils/formatTime'
import * as TradeOrderApi from '@/api/mall/trade/order'
const message = useMessage() // 消息弹窗
const drawerVisiable = ref(false)
let detailData = reactive<any>({
items: [],
user: {}
}) //详情数据
const handleClick = () => {}
const handleCommand = (command: string) => {
console.log(command)
}
//暂考虑一次性加载详情页面所有数据
const queryDetail = async (no: string) => {
try {
const res = await TradeOrderApi.getOrderDetail(no)
console.log(res)
detailData.value = res
console.log(detailData.value)
} catch {
message.error('获取详情数据失败')
}
}
//显示详情
const show = async (no: string) => {
drawerVisiable.value = true
try {
queryDetail(no)
} finally {
}
}
defineExpose({ show }) //显示详情方法
</script>
<style>
.el-dropdown-link {
cursor: pointer;
color: #409eff;
}
.el-icon-arrow-down {
font-size: 12px;
}
</style>

View File

@ -21,10 +21,10 @@
<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>
<!-- <el-descriptions-item label="买家: ">{{ order.user.nickname }}</el-descriptions-item> -->
<!-- TODO 芋艿待实现跳转会员 -->
<el-descriptions-item label="收货地址: ">
{{ order.receiverAreaName }} " "{{ order.receiverDetailAddress }} " "
{{ order.receiverAreaName }} {{ order.receiverDetailAddress }}
<el-link
v-clipboard:copy="order.receiverAreaName + ' ' + order.receiverDetailAddress"
v-clipboard:success="clipboardSuccess"
@ -37,7 +37,11 @@
<!-- 订单状态 -->
<el-descriptions title="订单状态" :column="1">
<el-descriptions-item label="订单状态: ">
<dict-tag :type="DICT_TYPE.TRADE_ORDER_STATUS" :value="order.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>
@ -68,12 +72,12 @@
<!-- 物流信息 TODO -->
<!-- 商品信息 -->
<el-descriptions title="商品信息" column="6">
<el-descriptions title="商品信息">
<el-descriptions-item labelClassName="no-colon">
<el-row :gutter="20">
<el-col :span="10">
<el-col :span="15">
<el-table :data="order.items" border>
<el-table-column prop="spuName" label="商品" width="400">
<el-table-column prop="spuName" label="商品" width="auto">
<template #default="{ row }">
{{ row.spuName }}
<el-tag
@ -81,22 +85,18 @@
v-for="property in row.properties"
:key="property.propertyId"
>
{{ property.propertyName }}{{ property.valueName }}
</el-tag>
{{ property.propertyName }}: {{ property.valueName }}</el-tag
>
</template>
</el-table-column>
<el-table-column prop="originalUnitPrice" label="价(元)" width="180">
<template #default="{ row }">
{{ (row.originalUnitPrice / 100.0).toFixed(2) }}
</template>
<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="originalPrice" label="小计(元)" width="100">
<template #default="{ row }">
{{ (row.originalPrice / 100.0).toFixed(2) }}
</template>
<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="退款状态">
<el-table-column prop="afterSaleStatus" label="售后状态" width="auto">
<template #default="{ row }">
<dict-tag
:type="DICT_TYPE.TRADE_ORDER_ITEM_AFTER_SALE_STATUS"
@ -114,25 +114,33 @@
</el-descriptions>
<el-descriptions column="6">
<el-descriptions-item label="商品总额: ">
{{ (order.originalPrice / 100.0).toFixed(2) }}
{{ parseFloat((order.totalPrice / 100.0) as unknown as string).toFixed(2) }}
</el-descriptions-item>
<el-descriptions-item label="运费金额: ">
{{ (order.deliveryPrice / 100.0).toFixed(2) }}
{{ parseFloat((order.deliveryPrice / 100.0) as unknown as string).toFixed(2) }}
</el-descriptions-item>
<el-descriptions-item label="订单调价: ">
{{ (order.adjustPrice / 100.0).toFixed(2) }}
</el-descriptions-item>
{{
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>
{{ ((order.originalPrice - order.originalPrice) / 100.0).toFixed(2) }}
<!-- 没理解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>
{{ (order.discountPrice / 100.0).toFixed(2) }}
{{ 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>
{{ (order.pointPrice / 100.0).toFixed(2) }}
{{ 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" />
@ -160,66 +168,58 @@
<!-- 物流信息 -->
<!-- TODO @xiaobai改成一个包裹哈目前只允许发货一次 -->
<el-descriptions-item v-if="group.key === 'expressInfo'" labelClassName="no-colon">
<el-tabs type="card">
<!-- 循环包裹物流信息 -->
<el-tab-pane
v-for="pkgInfo in detailInfo[group.key]"
:key="pkgInfo.label"
:label="pkgInfo.label"
>
<!-- 包裹详情 -->
<el-descriptions>
<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>
<!-- 循环包裹物流信息 -->
<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>
</el-tab-pane>
</el-tabs>
<!-- 包裹物流详情 -->
<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>
@ -261,7 +261,7 @@ const detailGroups = ref([
])
const detailInfo = ref({
expressInfo: [
expressInfo:
// 物流信息
{
label: '包裹1',
@ -292,8 +292,7 @@ const detailInfo = ref({
timestamp: '2018-04-11 12:55:52'
}
]
}
],
},
orderLog: [
// 订单操作日志
{
@ -307,13 +306,14 @@ const detailInfo = ref({
],
goodsInfo: [] // 商品详情tableData
})
// 暂考虑一次性加载详情页面所有数据 TODO @xiaobaigetDetail
// 暂考虑一次性加载详情页面所有数据 TODO
const getlist = async () => {
dialogVisible.value = true
loading.value = true
try {
const res = await TradeOrderApi.getOrderDetail(queryParams.id)
const res = await TradeOrderApi.getOrderDetail(queryParams.id as unknown as number)
order.value = res
console.log(order)
} catch {
message.error('获取详情数据失败')
} finally {
@ -332,9 +332,11 @@ const clipboardSuccess = () => {
&:not(:nth-child(1)) {
margin-top: 20px;
}
.el-descriptions__title {
display: flex;
align-items: center;
&::before {
content: '';
display: inline-block;
@ -344,10 +346,13 @@ const clipboardSuccess = () => {
background-color: #409eff;
}
}
.el-descriptions-item__container {
margin: 0 10px;
.no-colon {
margin: 0;
&::after {
content: '';
}