This commit is contained in:
@@ -1,188 +1,50 @@
|
||||
<template>
|
||||
<div class="exchange-detail-page">
|
||||
<ElPageHeader @back="handleBack">
|
||||
<template #content>
|
||||
<span class="page-header-title">换货单详情</span>
|
||||
</template>
|
||||
</ElPageHeader>
|
||||
|
||||
<ElCard v-loading="loading" style="margin-top: 20px">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>换货单信息</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<ElDescriptions v-if="exchangeDetail" :column="2" border>
|
||||
<ElDescriptionsItem label="换货单号">
|
||||
{{ exchangeDetail.exchange_no }}
|
||||
</ElDescriptionsItem>
|
||||
<ElDescriptionsItem label="状态">
|
||||
<ElTag :type="getStatusType(exchangeDetail.status)">
|
||||
{{ exchangeDetail.status_text }}
|
||||
</ElTag>
|
||||
</ElDescriptionsItem>
|
||||
|
||||
<ElDescriptionsItem label="换货原因" :span="2">
|
||||
{{ exchangeDetail.exchange_reason }}
|
||||
</ElDescriptionsItem>
|
||||
|
||||
<ElDescriptionsItem label="旧资产类型">
|
||||
{{ exchangeDetail.old_asset_type === 'iot_card' ? 'IoT卡' : '设备' }}
|
||||
</ElDescriptionsItem>
|
||||
<ElDescriptionsItem label="旧资产标识符">
|
||||
{{ exchangeDetail.old_asset_identifier }}
|
||||
</ElDescriptionsItem>
|
||||
|
||||
<ElDescriptionsItem label="新资产类型">
|
||||
{{
|
||||
exchangeDetail.new_asset_type
|
||||
? exchangeDetail.new_asset_type === 'iot_card'
|
||||
? 'IoT卡'
|
||||
: '设备'
|
||||
: '--'
|
||||
}}
|
||||
</ElDescriptionsItem>
|
||||
<ElDescriptionsItem label="新资产标识符">
|
||||
{{ exchangeDetail.new_asset_identifier || '--' }}
|
||||
</ElDescriptionsItem>
|
||||
|
||||
<ElDescriptionsItem label="收货人姓名">
|
||||
{{ exchangeDetail.recipient_name || '--' }}
|
||||
</ElDescriptionsItem>
|
||||
<ElDescriptionsItem label="收货人电话">
|
||||
{{ exchangeDetail.recipient_phone || '--' }}
|
||||
</ElDescriptionsItem>
|
||||
|
||||
<ElDescriptionsItem label="收货地址" :span="2">
|
||||
{{ exchangeDetail.recipient_address || '--' }}
|
||||
</ElDescriptionsItem>
|
||||
|
||||
<ElDescriptionsItem label="快递公司">
|
||||
{{ exchangeDetail.express_company || '--' }}
|
||||
</ElDescriptionsItem>
|
||||
<ElDescriptionsItem label="快递单号">
|
||||
{{ exchangeDetail.express_no || '--' }}
|
||||
</ElDescriptionsItem>
|
||||
|
||||
<ElDescriptionsItem label="备注" :span="2">
|
||||
{{ exchangeDetail.remark || '--' }}
|
||||
</ElDescriptionsItem>
|
||||
|
||||
<ElDescriptionsItem label="创建时间">
|
||||
{{ formatDateTime(exchangeDetail.created_at) }}
|
||||
</ElDescriptionsItem>
|
||||
<ElDescriptionsItem label="更新时间">
|
||||
{{ formatDateTime(exchangeDetail.updated_at) }}
|
||||
</ElDescriptionsItem>
|
||||
</ElDescriptions>
|
||||
|
||||
<ElEmpty v-else description="未找到换货单信息" />
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<div v-if="exchangeDetail" style="margin-top: 20px; text-align: center">
|
||||
<ElButton
|
||||
v-if="exchangeDetail.status === 1"
|
||||
type="warning"
|
||||
@click="handleCancel"
|
||||
v-permission="'exchange:cancel'"
|
||||
>
|
||||
取消换货
|
||||
<ElCard shadow="never">
|
||||
<!-- 页面头部 -->
|
||||
<div class="detail-header">
|
||||
<ElButton @click="handleBack">
|
||||
<template #icon>
|
||||
<ElIcon><ArrowLeft /></ElIcon>
|
||||
</template>
|
||||
返回
|
||||
</ElButton>
|
||||
<h2 class="detail-title">换货单详情</h2>
|
||||
</div>
|
||||
|
||||
<ElButton
|
||||
v-if="exchangeDetail.status === 2"
|
||||
@click="handleRenew"
|
||||
v-permission="'exchange:renew'"
|
||||
>
|
||||
旧资产转新
|
||||
</ElButton>
|
||||
<!-- 详情内容 -->
|
||||
<DetailPage v-if="exchangeDetail" :sections="detailSections" :data="exchangeDetail" />
|
||||
|
||||
<ElButton
|
||||
v-if="exchangeDetail.status === 2"
|
||||
type="primary"
|
||||
@click="showShipDialog"
|
||||
v-permission="'exchange:ship'"
|
||||
>
|
||||
发货
|
||||
</ElButton>
|
||||
|
||||
<ElButton
|
||||
v-if="exchangeDetail.status === 3"
|
||||
type="success"
|
||||
@click="handleComplete"
|
||||
v-permission="'exchange:complete'"
|
||||
>
|
||||
确认完成
|
||||
</ElButton>
|
||||
<!-- 加载中 -->
|
||||
<div v-if="loading" class="loading-container">
|
||||
<ElIcon class="is-loading"><Loading /></ElIcon>
|
||||
<span>加载中...</span>
|
||||
</div>
|
||||
</ElCard>
|
||||
|
||||
<!-- 发货对话框 -->
|
||||
<ElDialog v-model="shipDialogVisible" title="换货发货" width="600px">
|
||||
<ElForm ref="shipFormRef" :model="shipForm" :rules="shipRules" label-width="120px">
|
||||
<ElFormItem label="新资产标识符" prop="new_identifier">
|
||||
<ElInput v-model="shipForm.new_identifier" placeholder="请输入新资产标识符(ICCID/虚拟号/IMEI/SN)" />
|
||||
</ElFormItem>
|
||||
<ElFormItem label="快递公司" prop="express_company">
|
||||
<ElInput v-model="shipForm.express_company" placeholder="请输入快递公司" />
|
||||
</ElFormItem>
|
||||
<ElFormItem label="快递单号" prop="express_no">
|
||||
<ElInput v-model="shipForm.express_no" placeholder="请输入快递单号" />
|
||||
</ElFormItem>
|
||||
<ElFormItem label="是否迁移数据">
|
||||
<ElSwitch v-model="shipForm.migrate_data" />
|
||||
</ElFormItem>
|
||||
</ElForm>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<ElButton @click="shipDialogVisible = false">取消</ElButton>
|
||||
<ElButton type="primary" @click="handleConfirmShip" :loading="shipLoading">
|
||||
确认发货
|
||||
</ElButton>
|
||||
</div>
|
||||
</template>
|
||||
</ElDialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { h } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { ExchangeService } from '@/api/modules'
|
||||
import type { ExchangeResponse } from '@/api/modules/exchange'
|
||||
import { ElMessage, ElMessageBox, ElTag, ElSwitch } from 'element-plus'
|
||||
import type { FormInstance, FormRules } from 'element-plus'
|
||||
import { ElTag, ElCard, ElButton, ElIcon } from 'element-plus'
|
||||
import { ArrowLeft, Loading } from '@element-plus/icons-vue'
|
||||
import { formatDateTime } from '@/utils/business/format'
|
||||
import { useAuth } from '@/composables/useAuth'
|
||||
import DetailPage from '@/components/common/DetailPage.vue'
|
||||
import type { DetailSection } from '@/components/common/DetailPage.vue'
|
||||
|
||||
defineOptions({ name: 'ExchangeDetail' })
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const { hasAuth } = useAuth()
|
||||
|
||||
const loading = ref(false)
|
||||
const shipDialogVisible = ref(false)
|
||||
const shipLoading = ref(false)
|
||||
const shipFormRef = ref<FormInstance>()
|
||||
|
||||
const exchangeDetail = ref<ExchangeResponse | null>(null)
|
||||
const exchangeId = ref<number>(0)
|
||||
|
||||
const shipForm = reactive({
|
||||
new_identifier: '',
|
||||
express_company: '',
|
||||
express_no: '',
|
||||
migrate_data: true
|
||||
})
|
||||
|
||||
const shipRules = reactive<FormRules>({
|
||||
new_identifier: [{ required: true, message: '请输入新资产标识符', trigger: 'blur' }],
|
||||
express_company: [{ required: true, message: '请输入快递公司', trigger: 'blur' }],
|
||||
express_no: [{ required: true, message: '请输入快递单号', trigger: 'blur' }]
|
||||
})
|
||||
|
||||
const getStatusType = (status: number) => {
|
||||
const types: Record<number, string> = {
|
||||
1: 'warning',
|
||||
@@ -194,6 +56,102 @@
|
||||
return types[status] || 'info'
|
||||
}
|
||||
|
||||
// 详情页配置
|
||||
const detailSections: DetailSection[] = [
|
||||
{
|
||||
title: '基本信息',
|
||||
fields: [
|
||||
{ label: '换货单号', prop: 'exchange_no' },
|
||||
{
|
||||
label: '状态',
|
||||
render: (data) =>
|
||||
h(ElTag, { type: getStatusType(data.status) }, () => data.status_text)
|
||||
},
|
||||
{
|
||||
label: '换货原因',
|
||||
prop: 'exchange_reason',
|
||||
fullWidth: true
|
||||
},
|
||||
{
|
||||
label: '旧资产类型',
|
||||
formatter: (_, data) => (data.old_asset_type === 'iot_card' ? 'IoT卡' : '设备')
|
||||
},
|
||||
{ label: '旧资产标识符', prop: 'old_asset_identifier' },
|
||||
{
|
||||
label: '新资产类型',
|
||||
formatter: (_, data) =>
|
||||
data.new_asset_type
|
||||
? data.new_asset_type === 'iot_card'
|
||||
? 'IoT卡'
|
||||
: '设备'
|
||||
: '--'
|
||||
},
|
||||
{
|
||||
label: '新资产标识符',
|
||||
formatter: (value) => value || '--',
|
||||
prop: 'new_asset_identifier'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '收货信息',
|
||||
fields: [
|
||||
{
|
||||
label: '收货人姓名',
|
||||
formatter: (value) => value || '--',
|
||||
prop: 'recipient_name'
|
||||
},
|
||||
{
|
||||
label: '收货人电话',
|
||||
formatter: (value) => value || '--',
|
||||
prop: 'recipient_phone'
|
||||
},
|
||||
{
|
||||
label: '收货地址',
|
||||
formatter: (value) => value || '--',
|
||||
prop: 'recipient_address',
|
||||
fullWidth: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '物流信息',
|
||||
fields: [
|
||||
{
|
||||
label: '快递公司',
|
||||
formatter: (value) => value || '--',
|
||||
prop: 'express_company'
|
||||
},
|
||||
{
|
||||
label: '快递单号',
|
||||
formatter: (value) => value || '--',
|
||||
prop: 'express_no'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '其他信息',
|
||||
fields: [
|
||||
{
|
||||
label: '备注',
|
||||
formatter: (value) => value || '--',
|
||||
prop: 'remark',
|
||||
fullWidth: true
|
||||
},
|
||||
{
|
||||
label: '创建时间',
|
||||
formatter: (value) => formatDateTime(value),
|
||||
prop: 'created_at'
|
||||
},
|
||||
{
|
||||
label: '更新时间',
|
||||
formatter: (value) => formatDateTime(value),
|
||||
prop: 'updated_at'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
// 加载换货单详情
|
||||
const loadExchangeDetail = async () => {
|
||||
loading.value = true
|
||||
@@ -209,95 +167,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 取消换货
|
||||
const handleCancel = () => {
|
||||
ElMessageBox.prompt('请输入取消备注', '取消换货', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
inputType: 'textarea'
|
||||
})
|
||||
.then(async ({ value }) => {
|
||||
try {
|
||||
const res = await ExchangeService.cancelExchange(exchangeId.value, { remark: value })
|
||||
if (res.code === 0) {
|
||||
ElMessage.success('取消成功')
|
||||
loadExchangeDetail()
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('取消换货失败:', error)
|
||||
}
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
|
||||
// 旧资产转新
|
||||
const handleRenew = () => {
|
||||
ElMessageBox.confirm('确定要将旧资产转为新资产吗?', '确认操作', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
.then(async () => {
|
||||
try {
|
||||
const res = await ExchangeService.renewExchange(exchangeId.value)
|
||||
if (res.code === 0) {
|
||||
ElMessage.success('操作成功')
|
||||
loadExchangeDetail()
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('旧资产转新失败:', error)
|
||||
}
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
|
||||
// 显示发货对话框
|
||||
const showShipDialog = () => {
|
||||
shipDialogVisible.value = true
|
||||
}
|
||||
|
||||
// 确认发货
|
||||
const handleConfirmShip = () => {
|
||||
shipFormRef.value?.validate(async (valid) => {
|
||||
if (!valid) return
|
||||
|
||||
shipLoading.value = true
|
||||
try {
|
||||
const res = await ExchangeService.shipExchange(exchangeId.value, shipForm)
|
||||
if (res.code === 0) {
|
||||
ElMessage.success('发货成功')
|
||||
shipDialogVisible.value = false
|
||||
loadExchangeDetail()
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('发货失败:', error)
|
||||
} finally {
|
||||
shipLoading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 确认完成
|
||||
const handleComplete = () => {
|
||||
ElMessageBox.confirm('确定要确认换货完成吗?', '确认操作', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
.then(async () => {
|
||||
try {
|
||||
const res = await ExchangeService.completeExchange(exchangeId.value)
|
||||
if (res.code === 0) {
|
||||
ElMessage.success('操作成功')
|
||||
loadExchangeDetail()
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('确认完成失败:', error)
|
||||
}
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
|
||||
// 返回
|
||||
const handleBack = () => {
|
||||
router.back()
|
||||
@@ -314,17 +183,34 @@
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.exchange-detail-page {
|
||||
height: 100%;
|
||||
padding: 20px;
|
||||
|
||||
.page-header-title {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
.detail-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.detail-title {
|
||||
margin-left: 16px;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.card-header {
|
||||
.loading-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 40px 0;
|
||||
color: var(--el-text-color-secondary);
|
||||
|
||||
.el-icon {
|
||||
margin-bottom: 8px;
|
||||
font-size: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user