Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
08fa9c07b3
455
mes-ui/mes-ui-admin-vue3/src/views/biz/tsoorder/OrderDetail.vue
Normal file
455
mes-ui/mes-ui-admin-vue3/src/views/biz/tsoorder/OrderDetail.vue
Normal file
@ -0,0 +1,455 @@
|
||||
<template>
|
||||
<!-- 全屏模式(详情) -->
|
||||
<div v-if="dialogVisible" class="fullscreen-form">
|
||||
<div class="form-header">
|
||||
<h2>{{ dialogTitle }}</h2>
|
||||
</div>
|
||||
<div class="form-content">
|
||||
<!-- 基础信息区域 -->
|
||||
<div class="basic-info">
|
||||
<h3 class="section-title">基础信息</h3>
|
||||
<el-form
|
||||
:model="formData"
|
||||
label-width="100px"
|
||||
v-loading="formLoading"
|
||||
>
|
||||
<!-- 第一行:订单编号、订单类型、订单状态、下单日期 -->
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="订单编号">
|
||||
<el-input v-model="formData.saleOrdNo" disabled />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="订单类型">
|
||||
<el-select v-model="formData.ordType" disabled>
|
||||
<el-option
|
||||
v-for="dict in getStrDictOptions(DICT_TYPE.ORDER_TYPE)"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="订单状态">
|
||||
<el-select v-model="formData.ordStatus" disabled>
|
||||
<el-option
|
||||
v-for="dict in getIntDictOptions(DICT_TYPE.ORDER_STATUS)"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="下单日期">
|
||||
<el-date-picker
|
||||
v-model="formData.ordDate"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
format="YYYY-MM-DD"
|
||||
disabled
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- 第二行:业务部门、业务人员、客户名称、是否急单 -->
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="业务部门">
|
||||
<el-input v-model="formData.saleDeptName" disabled />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="业务人员">
|
||||
<el-input v-model="formData.saleManName" disabled />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="客户名称">
|
||||
<el-input v-model="formData.custName" disabled />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="是否急单">
|
||||
<el-select v-model="formData.isUrgent" disabled>
|
||||
<el-option
|
||||
v-for="dict in getStrDictOptions(DICT_TYPE.SYSTEM_IS_CELL)"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- 第三行:交货日期、合同编号、付款方式、是否变更 -->
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="交货日期">
|
||||
<el-date-picker
|
||||
v-model="formData.reqDeliveryDate"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
format="YYYY-MM-DD"
|
||||
disabled
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="合同编号">
|
||||
<el-input v-model="formData.contractNo" disabled />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="付款方式">
|
||||
<el-select v-model="formData.paymentTerms" disabled>
|
||||
<el-option
|
||||
v-for="dict in getStrDictOptions(DICT_TYPE.PAY_METH)"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="是否变更">
|
||||
<el-select v-model="formData.isChange" disabled>
|
||||
<el-option
|
||||
v-for="dict in getStrDictOptions(DICT_TYPE.SYSTEM_IS_CELL)"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- 第四行:税率、含税总金额、发货状态 -->
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="税率">
|
||||
<el-input v-model="formData.taxRate" disabled class="text-right" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="含税总金额">
|
||||
<el-input v-model="formData.totalAmount" disabled class="text-right" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="发货状态">
|
||||
<el-select v-model="formData.deliveryStatus" disabled>
|
||||
<el-option
|
||||
v-for="dict in getIntDictOptions(DICT_TYPE.SHIPPING_STATUS)"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- 第五行:包装要求、质量要求 -->
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="包装要求">
|
||||
<el-input v-model="formData.packReq" type="textarea" disabled :rows="3" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="质量要求">
|
||||
<el-input v-model="formData.qualityReq" type="textarea" disabled :rows="3" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- 备注 -->
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="formData.remark" type="textarea" disabled :rows="3" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<!-- 产品明细区域 -->
|
||||
<div class="product-detail">
|
||||
<div class="section-header">
|
||||
<h3 class="section-title">产品明细</h3>
|
||||
</div>
|
||||
<el-table
|
||||
:data="productList"
|
||||
stripe
|
||||
style="width: 100%;"
|
||||
:show-overflow-tooltip="true"
|
||||
>
|
||||
<el-table-column label="序号" align="center" type="index" width="60px" />
|
||||
<el-table-column label="产品名称" align="center" prop="materialName" />
|
||||
<el-table-column label="规格型号" align="center" prop="spec" />
|
||||
<el-table-column label="单位" align="center" prop="unit">
|
||||
<template #default="scope">
|
||||
<dict-tag :type="DICT_TYPE.UNIT" :value="scope.row.unit" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="订单数量" align="center" prop="ordQty" />
|
||||
<el-table-column label="含税单价" align="center" prop="priceTax" />
|
||||
<el-table-column label="用途" align="center" width="120px">
|
||||
<template #default="scope">
|
||||
<dict-tag :type="DICT_TYPE.PURPOSE" :value="scope.row.materialUse" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="发货数量" align="center" prop="deliveriedQty" />
|
||||
<el-table-column label="已转生成数量" align="center" prop="produceQty" />
|
||||
<el-table-column label="备注" align="center" prop="remark" />
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<!-- 附件信息区域 -->
|
||||
<div class="attachment-info">
|
||||
<h3 class="section-title">附件信息</h3>
|
||||
<el-table
|
||||
v-if="uploadedFiles.length > 0"
|
||||
:data="uploadedFiles"
|
||||
border
|
||||
size="small"
|
||||
class="mt-20px"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="80" align="center" />
|
||||
<el-table-column prop="name" label="文件名称" align="center" />
|
||||
<el-table-column prop="uploadTime" label="上传时间" width="200" align="center" />
|
||||
</el-table>
|
||||
<div v-else class="no-data">暂无附件</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部按钮区域 -->
|
||||
<div class="form-footer">
|
||||
<el-button @click="handleCancel">关闭</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import * as OrderApi from '@/api/biz/tsoorder/'
|
||||
import { getIntDictOptions, getStrDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||
|
||||
const { t } = useI18n()
|
||||
const message = useMessage()
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const dialogTitle = ref('订单详情')
|
||||
const formLoading = ref(false)
|
||||
|
||||
const formData = reactive({
|
||||
id: undefined,
|
||||
saleOrdNo: undefined,
|
||||
ordDate: undefined,
|
||||
custId: undefined,
|
||||
custName: undefined,
|
||||
contact: undefined,
|
||||
conPhone: undefined,
|
||||
saleMan: undefined,
|
||||
saleManName: undefined,
|
||||
saleDeptId: undefined,
|
||||
saleDeptName: undefined,
|
||||
ordType: undefined,
|
||||
paymentTerms: undefined,
|
||||
taxRate: undefined,
|
||||
totalAmount: undefined,
|
||||
reqDeliveryDate: undefined,
|
||||
isUrgent: undefined,
|
||||
isChange: undefined,
|
||||
ordStatus: undefined,
|
||||
contractNo: undefined,
|
||||
packReq: undefined,
|
||||
qualityReq: undefined,
|
||||
remark: undefined,
|
||||
attFile: undefined,
|
||||
proStatus: undefined,
|
||||
deliveryStatus: undefined,
|
||||
})
|
||||
|
||||
// 产品列表
|
||||
const productList = ref([])
|
||||
|
||||
// 文件上传相关
|
||||
const uploadedFiles = ref<Array<{ id: string; name: string; uploadTime: string; url: string }>>([])
|
||||
|
||||
const open = async (id: number) => {
|
||||
formLoading.value = true
|
||||
try {
|
||||
const response = await OrderApi.getOrder(id)
|
||||
const data = response.data || response
|
||||
|
||||
if (!data || typeof data !== 'object') {
|
||||
console.error('API响应数据格式异常:', response)
|
||||
return
|
||||
}
|
||||
|
||||
const normalizeValue = (val: any) => {
|
||||
if (Array.isArray(val) && val.length > 0) {
|
||||
return val[0]
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
const normalizeDate = (val: any) => {
|
||||
if (!val) return undefined
|
||||
if (typeof val === 'string') {
|
||||
return val
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
const cleanedData: any = {}
|
||||
for (const key in data) {
|
||||
if (key === 'items') continue
|
||||
if (key === 'ordDate' || key === 'reqDeliveryDate') {
|
||||
cleanedData[key] = normalizeDate(data[key])
|
||||
} else if (key === 'ordStatus' || key === 'deliveryStatus' || key === 'proStatus') {
|
||||
cleanedData[key] = Number(normalizeValue(data[key])) || 0
|
||||
} else {
|
||||
cleanedData[key] = normalizeValue(data[key])
|
||||
}
|
||||
}
|
||||
|
||||
Object.assign(formData, cleanedData)
|
||||
|
||||
// 处理产品明细列表
|
||||
const rawItems = data?.items
|
||||
const rows = Array.isArray(rawItems) ? rawItems : (rawItems != null ? [rawItems] : [])
|
||||
productList.value = rows.length ? rows.map((r) => ({ ...r })) : []
|
||||
|
||||
// 处理附件信息回显
|
||||
const rawAttFile = data?.attFile
|
||||
if (rawAttFile) {
|
||||
try {
|
||||
const attFileArray = typeof rawAttFile === 'string' ? JSON.parse(rawAttFile) : rawAttFile
|
||||
if (Array.isArray(attFileArray)) {
|
||||
uploadedFiles.value = attFileArray.map((item: any) => ({
|
||||
id: item.filePath?.split('/').pop() || Date.now().toString(),
|
||||
name: item.fileName,
|
||||
uploadTime: item.uploadTime || '-',
|
||||
url: item.filePath
|
||||
}))
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('解析附件信息失败', e)
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
const handleCancel = () => {
|
||||
dialogVisible.value = false
|
||||
}
|
||||
|
||||
defineExpose({ open })
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.fullscreen-form {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: #f5f7fa;
|
||||
z-index: 2000;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.form-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 15px 20px;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #e4e7ed;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
||||
|
||||
h2 {
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
}
|
||||
}
|
||||
|
||||
.form-content {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
min-width: 0;
|
||||
overflow-y: auto;
|
||||
padding: 20px;
|
||||
padding-bottom: 80px;
|
||||
}
|
||||
|
||||
.basic-info,
|
||||
.product-detail,
|
||||
.attachment-info {
|
||||
margin-bottom: 20px;
|
||||
padding: 15px;
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
margin: 0 0 15px 0;
|
||||
}
|
||||
|
||||
.product-detail .section-title {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.text-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.no-data {
|
||||
text-align: center;
|
||||
color: #909399;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.form-footer {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 15px;
|
||||
padding: 15px 20px;
|
||||
background: #fff;
|
||||
border-top: 1px solid #e4e7ed;
|
||||
box-shadow: 0 -2px 4px rgba(0, 0, 0, 0.05);
|
||||
z-index: 2001;
|
||||
}
|
||||
|
||||
.mt-20px {
|
||||
margin-top: 20px;
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue
Block a user