优化
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<el-dialog v-model="isShowDialog" title="变更单详情" draggable width="60vw" :close-on-click-modal="false" :destroy-on-close="true">
|
||||
<el-dialog v-model="isShowDialog" title="材料设备详情" draggable width="1200px" :close-on-click-modal="false" :destroy-on-close="true">
|
||||
<el-card :body-style="{ padding: '20px' }" style="border: none; box-shadow: none">
|
||||
<div class="dialog-footer">
|
||||
<div class="btn-item" @click="onLoad">
|
||||
@ -46,26 +46,26 @@
|
||||
</tbody>
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="150">序号</th>
|
||||
<th width="150">名称</th>
|
||||
<th width="150">规格</th>
|
||||
<th width="150">单位</th>
|
||||
<th width="150">数量</th>
|
||||
<th width="150">验收</th>
|
||||
<th width="150">缺件</th>
|
||||
<th width="150">备注</th>
|
||||
<td width="150">序号</td>
|
||||
<td width="150">名称</td>
|
||||
<td width="150">规格</td>
|
||||
<td width="150">单位</td>
|
||||
<td width="150">数量</td>
|
||||
<td width="150">验收</td>
|
||||
<td width="150">缺件</td>
|
||||
<td width="150">备注</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(item, i) of formData.itemList" :key="i">
|
||||
<th width="150">{{ i + 1 }}</th>
|
||||
<th width="150">{{ item.name }}</th>
|
||||
<th width="150">{{ item.specification }}</th>
|
||||
<th width="150">{{ item.unit }}</th>
|
||||
<th width="150">{{ item.quantity }}</th>
|
||||
<th width="150">{{ item.acceptedQuantity }}</th>
|
||||
<th width="150">{{ item.shortageQuantity }}</th>
|
||||
<th width="150">{{ item.remark }}</th>
|
||||
<td width="150">{{ i + 1 }}</td>
|
||||
<td width="150">{{ item.name }}</td>
|
||||
<td width="150">{{ item.specification }}</td>
|
||||
<td width="150">{{ item.unit }}</td>
|
||||
<td width="150">{{ item.quantity }}</td>
|
||||
<td width="150">{{ item.acceptedQuantity }}</td>
|
||||
<td width="150">{{ item.shortageQuantity }}</td>
|
||||
<td width="150">{{ item.remark }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tbody>
|
||||
|
||||
Binary file not shown.
@ -27,6 +27,7 @@
|
||||
<el-table-column prop="num" label="编号" />
|
||||
<el-table-column prop="name" label="工程或费用名称" width="180" />
|
||||
<el-table-column prop="unit" label="单位" />
|
||||
<el-table-column prop="specification" label="规格型号" />
|
||||
<el-table-column prop="quantity" label="数量" width="60" />
|
||||
<el-table-column prop="batchNumber" label="批次号" width="200" />
|
||||
<el-table-column prop="brand" label="品牌" />
|
||||
|
||||
@ -3,18 +3,23 @@
|
||||
<div class="max-w-4xl mx-auto">
|
||||
<!-- 顶部按钮区域 -->
|
||||
<el-card class="mb-4 rounded-lg shadow-sm bg-white border border-gray-100 transition-all hover:shadow-md">
|
||||
<approvalButton @submitForm="submitForm" @approvalVerifyOpen="approvalVerifyOpen"
|
||||
@handleApprovalRecord="handleApprovalRecord" :buttonLoading="buttonLoading" :id="form.id"
|
||||
:status="form.status" :pageType="routeParams.type" />
|
||||
<approvalButton
|
||||
@submitForm="submitForm"
|
||||
@approvalVerifyOpen="approvalVerifyOpen"
|
||||
@handleApprovalRecord="handleApprovalRecord"
|
||||
:buttonLoading="buttonLoading"
|
||||
:id="form.id"
|
||||
:status="form.status"
|
||||
:pageType="routeParams.type"
|
||||
/>
|
||||
</el-card>
|
||||
<!-- 表单区域 -->
|
||||
<el-card
|
||||
class="rounded-lg shadow-sm bg-white border border-gray-100 transition-all hover:shadow-md overflow-hidden">
|
||||
<el-card class="rounded-lg shadow-sm bg-white border border-gray-100 transition-all hover:shadow-md overflow-hidden">
|
||||
<div class="p-4 bg-gradient-to-r from-blue-50 to-indigo-50 border-b border-gray-100">
|
||||
<h3 class="text-lg font-semibold text-gray-800">设计原则</h3>
|
||||
</div>
|
||||
<div class="p-6">
|
||||
<!-- <el-form ref="leaveFormRef" v-loading="loading" :disabled="routeParams.type === 'view' || routeParams.type === 'update'" :model="form"
|
||||
<!-- <el-form ref="leaveFormRef" v-loading="loading" :disabled="routeParams.type === 'view' || form.status == 'waiting' || routeParams.type === 'update'" :model="form"
|
||||
:rules="rules" label-width="100px" class="space-y-4">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
@ -67,7 +72,7 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form> -->
|
||||
<el-table :data="tableData" v-loading="loading" row-key="id" border>
|
||||
<el-table :data="tableData" v-loading="loading" row-key="id" border>
|
||||
<el-table-column prop="num" label="编号" />
|
||||
<el-table-column prop="name" label="名称" />
|
||||
<el-table-column prop="specification" label="规格" />
|
||||
@ -81,8 +86,14 @@
|
||||
<submitVerify ref="submitVerifyRef" :task-variables="taskVariables" @submit-callback="submitCallback" />
|
||||
<approvalRecord ref="approvalRecordRef"></approvalRecord>
|
||||
<!-- 流程选择对话框 -->
|
||||
<el-dialog draggable v-model="dialogVisible.visible" :title="dialogVisible.title" :before-close="handleClose"
|
||||
width="500" class="rounded-lg shadow-lg">
|
||||
<el-dialog
|
||||
draggable
|
||||
v-model="dialogVisible.visible"
|
||||
:title="dialogVisible.title"
|
||||
:before-close="handleClose"
|
||||
width="500"
|
||||
class="rounded-lg shadow-lg"
|
||||
>
|
||||
<div class="p-4">
|
||||
<p class="text-gray-600 mb-4">请选择要启动的流程:</p>
|
||||
<el-select v-model="flowCode" placeholder="请选择流程" style="width: 100%">
|
||||
@ -91,10 +102,12 @@
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer p-4 border-t border-gray-100 flex justify-end space-x-3">
|
||||
<el-button @click="handleClose"
|
||||
class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50 transition-colors">取消</el-button>
|
||||
<el-button type="primary" @click="submitFlow()"
|
||||
class="px-4 py-2 bg-primary text-white rounded-md hover:bg-primary/90 transition-colors">确认</el-button>
|
||||
<el-button @click="handleClose" class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50 transition-colors"
|
||||
>取消</el-button
|
||||
>
|
||||
<el-button type="primary" @click="submitFlow()" class="px-4 py-2 bg-primary text-white rounded-md hover:bg-primary/90 transition-colors"
|
||||
>确认</el-button
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
@ -112,7 +125,7 @@ import { StartProcessBo } from '@/api/workflow/workflowCommon/types';
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
import { useUserStoreHook } from '@/store/modules/user';
|
||||
const { design_change_reason_type } = toRefs<any>(proxy?.useDict('design_change_reason_type'));
|
||||
import { totalsupplyplan,obtainMasterDataList } from '@/api/materials/overallPlanMaterialSupply/index';
|
||||
import { totalsupplyplan, obtainMasterDataList } from '@/api/materials/overallPlanMaterialSupply/index';
|
||||
// 获取用户 store
|
||||
const userStore = useUserStoreHook();
|
||||
// 从 store 中获取项目列表和当前选中的项目
|
||||
|
||||
245
src/views/materials/purchaseDoc/comm/logisticsDetail.vue
Normal file
245
src/views/materials/purchaseDoc/comm/logisticsDetail.vue
Normal file
@ -0,0 +1,245 @@
|
||||
<template>
|
||||
<el-drawer v-model="drawer" :direction="direction" size="40%" :before-close="handleBeforeClose" title-class="drawer-title">
|
||||
<template #header>
|
||||
<span class="font-bold text-lg text-gray-800">物流信息</span>
|
||||
</template>
|
||||
|
||||
<template #default>
|
||||
<!-- 物流头部信息 -->
|
||||
<div class="bg-white rounded-lg shadow-md p-5 mb-6">
|
||||
<div class="flex flex-col md:flex-row md:items-center justify-between gap-6">
|
||||
<!-- 左侧:快递基本信息 -->
|
||||
<div class="flex items-center gap-6">
|
||||
<div class="w-14 h-14 rounded-md overflow-hidden border border-gray-100 flex items-center justify-center">
|
||||
<img
|
||||
:src="logisticsData?.result.logo"
|
||||
alt="快递公司Logo"
|
||||
class="w-full h-full object-contain"
|
||||
:onerror="`this.src='https://via.placeholder.com/48x48?text=暂无Logo'`"
|
||||
/>
|
||||
</div>
|
||||
<div class="text-sm">
|
||||
<p class="text-gray-500">快递单号</p>
|
||||
<p class="font-medium text-gray-900">{{ logisticsData?.result.number }}</p>
|
||||
<p class="text-gray-500 mt-1">{{ logisticsData?.result.expName }} | 最新更新: {{ logisticsData?.result.updateTime }}</p>
|
||||
</div>
|
||||
<div class="ml-auto">
|
||||
<el-tag :type="getStatusType(logisticsData?.result.deliverystatus)" size="medium" class="px-4 py-1">
|
||||
{{ getStatusText(logisticsData?.result.deliverystatus) }}
|
||||
</el-tag>
|
||||
<p class="text-gray-500 text-sm mt-2 text-right">耗时: {{ logisticsData?.result.takeTime || '暂无数据' }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 快递员信息(有数据才显示) -->
|
||||
<div v-if="logisticsData?.result.courier" class="bg-blue-50 rounded-lg p-4 mb-6 border-l-4 border-blue-400">
|
||||
<div class="flex items-center justify-between">
|
||||
<p class="font-medium text-blue-800">配送信息</p>
|
||||
<a :href="`tel:${logisticsData?.result.courierPhone}`" class="text-blue-600 hover:text-blue-800 text-sm flex items-center gap-1">
|
||||
<el-icon class="el-icon-phone"></el-icon>
|
||||
联系快递员
|
||||
</a>
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-x-8 gap-y-3 mt-3 text-gray-700">
|
||||
<div class="flex items-center gap-2">
|
||||
<el-icon class="el-icon-user text-gray-500"></el-icon>
|
||||
<span>快递员: {{ logisticsData?.result.courier }}</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<el-icon class="el-icon-phone-outline text-gray-500"></el-icon>
|
||||
<span>电话: {{ logisticsData?.result.courierPhone || '暂无' }}</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<el-icon class="el-icon-service text-gray-500"></el-icon>
|
||||
<span>客服: {{ logisticsData?.result.expPhone }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 物流轨迹列表 -->
|
||||
<div class="bg-white rounded-lg shadow-md p-5">
|
||||
<p class="font-medium text-gray-800 mb-4">物流轨迹({{ logisticsData?.result.list.length || 0 }}条)</p>
|
||||
<div class="relative" style="border-left: 1px solid #d9d9d9; padding-left: 15px">
|
||||
<div v-for="(item, index) in logisticsData?.result.list" :key="index" class="flex mb-8 relative">
|
||||
<div class="flex flex-col items-center mr-6 z-10">
|
||||
<div
|
||||
:class="[
|
||||
'w-8 h-8 rounded-full flex items-center justify-center',
|
||||
index === 0 ? 'bg-blue-500 text-white' : 'bg-white border border-gray-300 text-gray-500'
|
||||
]"
|
||||
>
|
||||
<el-icon v-if="index === 0" class="el-icon-check text-xs"></el-icon>
|
||||
<span v-else class="text-xs">{{ index + 1 }}</span>
|
||||
</div>
|
||||
<p class="text-xs text-gray-500 mt-2">{{ item.time }}</p>
|
||||
</div>
|
||||
<div class="flex-1 bg-gray-50 rounded-lg p-4 border border-gray-100 shadow-sm">
|
||||
<p class="text-gray-800">{{ item.status }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #footer>
|
||||
<div class="drawer-footer">
|
||||
<el-button @click="close" :loading="cancelLoading" class="mr-3">关闭</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-drawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import type { DrawerProps } from 'element-plus';
|
||||
import { Phone, PhoneOutline, User, Service, Check } from '@element-plus/icons-vue';
|
||||
|
||||
// 抽屉方向
|
||||
const direction = ref<DrawerProps['direction']>('ltr');
|
||||
// 加载状态
|
||||
const cancelLoading = ref(false);
|
||||
const confirmLoading = ref(false);
|
||||
// 抽屉显隐
|
||||
const drawer = ref(false);
|
||||
// 物流数据(初始化为接口返回格式)
|
||||
const logisticsData = ref({
|
||||
status: '0',
|
||||
msg: 'ok',
|
||||
result: {
|
||||
number: '',
|
||||
type: '',
|
||||
list: [],
|
||||
deliverystatus: '0',
|
||||
issign: '0',
|
||||
expName: '',
|
||||
expSite: '',
|
||||
expPhone: '',
|
||||
courier: '',
|
||||
courierPhone: '',
|
||||
updateTime: '',
|
||||
takeTime: '',
|
||||
logo: ''
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 根据物流状态获取标签类型
|
||||
* @param status 物流状态码
|
||||
*/
|
||||
const getStatusType = (status?: string) => {
|
||||
switch (status) {
|
||||
case '0': // 揽件
|
||||
return 'info';
|
||||
case '1': // 在途中
|
||||
return 'warning';
|
||||
case '2': // 派件中
|
||||
return 'primary';
|
||||
case '3': // 已签收
|
||||
return 'success';
|
||||
case '4': // 派送失败
|
||||
case '5': // 疑难件
|
||||
return 'danger';
|
||||
case '6': // 退件签收
|
||||
return 'error';
|
||||
default:
|
||||
return 'default';
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 根据物流状态获取文本描述
|
||||
* @param status 物流状态码
|
||||
*/
|
||||
const getStatusText = (status?: string) => {
|
||||
const statusMap: Record<string, string> = {
|
||||
'0': '快递收件(揽件)',
|
||||
'1': '运输途中',
|
||||
'2': '正在派件',
|
||||
'3': '已签收',
|
||||
'4': '派送失败',
|
||||
'5': '疑难件',
|
||||
'6': '退件签收'
|
||||
};
|
||||
return statusMap[status || '0'] || '未知状态';
|
||||
};
|
||||
|
||||
/**
|
||||
* 打开抽屉并加载物流数据
|
||||
*/
|
||||
const open = (data) => {
|
||||
const mockData = {
|
||||
result: data
|
||||
};
|
||||
logisticsData.value = mockData;
|
||||
drawer.value = true;
|
||||
};
|
||||
/**
|
||||
* 关闭抽屉
|
||||
*/
|
||||
const close = () => {
|
||||
drawer.value = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* 抽屉关闭前钩子(可用于拦截关闭逻辑)
|
||||
*/
|
||||
const handleBeforeClose = (done: () => void) => {
|
||||
done(); // 直接关闭,如需确认可添加弹窗逻辑
|
||||
};
|
||||
|
||||
// 暴露加载状态控制方法
|
||||
const setCancelLoading = (loading: boolean) => {
|
||||
cancelLoading.value = loading;
|
||||
};
|
||||
const setConfirmLoading = (loading: boolean) => {
|
||||
confirmLoading.value = loading;
|
||||
};
|
||||
|
||||
// 暴露方法供父组件调用
|
||||
defineExpose({
|
||||
open,
|
||||
setCancelLoading,
|
||||
setConfirmLoading
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.drawer-title {
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #f2f2f2;
|
||||
}
|
||||
|
||||
.drawer-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 12px;
|
||||
padding: 16px;
|
||||
border-top: 1px solid #eee;
|
||||
}
|
||||
|
||||
:deep(.el-drawer__body) {
|
||||
padding: 20px;
|
||||
overflow-y: auto;
|
||||
max-height: calc(100vh - 160px);
|
||||
}
|
||||
|
||||
:deep(.el-tag) {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
:deep(.el-drawer) {
|
||||
width: 95% !important;
|
||||
}
|
||||
|
||||
.drawer-footer {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
:deep(.drawer-footer .el-button) {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -31,8 +31,8 @@
|
||||
</el-row>
|
||||
</template>
|
||||
<el-table v-loading="loading" :data="purchaseDocList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="采购单编号" align="center" prop="docCode" width="90" />
|
||||
<el-table-column type="index" width="60" label="序号" align="center" />
|
||||
<el-table-column label="采购单编号" align="center" prop="docCode" width="150" />
|
||||
<el-table-column label="批次号" align="center" prop="mrpBaseId">
|
||||
<template #default="scope">
|
||||
{{ batchOptions.find((item) => item.id == scope.row.mrpBaseId)?.planCode }}
|
||||
@ -220,11 +220,16 @@
|
||||
</template>
|
||||
</el-dialog>
|
||||
<!-- 查看文件列表 -->
|
||||
<el-dialog title="文件列表" v-model="viewVisible" width="45%">
|
||||
<el-dialog title="物流单号" v-model="viewVisible" width="45%">
|
||||
<el-table v-if="fileList.length > 0" :data="fileList" style="width: 100%" border>
|
||||
<el-table-column label="单号" align="center" prop="ltn" />
|
||||
<el-table-column label="数量" align="center" prop="num" />
|
||||
<el-table-column label="物资名称" align="center" prop="name" />
|
||||
<el-table-column label="规格型号" align="center" prop="specification">
|
||||
<template #default="scope">
|
||||
<el-button link type="primary" icon="Finished" @click="getDetailList(scope.row.ltn)"> 查看物流信息</el-button></template
|
||||
>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div v-else class="empty-list text-center">暂无文件</div>
|
||||
<template #footer>
|
||||
@ -233,17 +238,19 @@
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<logisticsDetail ref="logisticsDetailRef"></logisticsDetail>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="PurchaseDoc" lang="ts">
|
||||
import { getBatch, listBatch } from '@/api/materials/batchPlan';
|
||||
import { listPurchaseDoc, getPurchaseDoc, listLink, addPurchaseDoc, updatePurchaseDoc } from '@/api/materials/purchaseDoc';
|
||||
import { listPurchaseDoc, getPurchaseDoc, listLink, addPurchaseDoc, updatePurchaseDoc, logisticsDetial } from '@/api/materials/purchaseDoc';
|
||||
import { PurchaseDocVO, PurchaseDocQuery, PurchaseDocForm } from '@/api/materials/purchaseDoc/types';
|
||||
import { listContractor } from '@/api/project/contractor';
|
||||
import { useUserStoreHook } from '@/store/modules/user';
|
||||
import { getToken } from '@/utils/auth';
|
||||
|
||||
import logisticsDetail from './comm/logisticsDetail.vue';
|
||||
import type { DrawerProps } from 'element-plus';
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
@ -262,10 +269,11 @@ const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
const feedbackUrl = ref('');
|
||||
// 组件
|
||||
const logisticsDetailRef = ref<InstanceType<typeof logisticsDetail>>();
|
||||
const queryFormRef = ref<ElFormInstance>();
|
||||
const purchaseDocFormRef = ref<ElFormInstance>();
|
||||
const IP = 'http://192.168.110.151:7788';
|
||||
|
||||
const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
@ -480,8 +488,8 @@ const handleShare = async (row?: PurchaseDocVO) => {
|
||||
});
|
||||
// 获取当前域名地址
|
||||
console.log(location);
|
||||
textarea.value = IP + '/materials/purchaseDoc/uploadCode?data=' + data;
|
||||
// textarea.value = location.host + '/materials/purchaseDoc/uploadCode?data=' + data;
|
||||
// textarea.value = IP + '/materials/purchaseDoc/uploadCode?data=' + data;
|
||||
textarea.value = location.host + '/materials/purchaseDoc/uploadCode?data=' + data;
|
||||
textarea.style.position = 'fixed';
|
||||
textarea.style.opacity = '0';
|
||||
document.body.appendChild(textarea);
|
||||
@ -530,6 +538,12 @@ const handleViewDetail = async (row?: PurchaseDocVO) => {
|
||||
type: 'view'
|
||||
});
|
||||
};
|
||||
const getDetailList = async (id) => {
|
||||
let res = await logisticsDetial(id);
|
||||
if (res.code == 200) {
|
||||
logisticsDetailRef.value.open(res.data);
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
|
||||
Reference in New Issue
Block a user