| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- <template>
- <el-drawer v-model="visible" title="物流信息" size="38%" direction="rtl" :before-close="handleClose" :close-on-click-modal="true">
- <div class="logistics-detail">
- <div class="section-title">单号查询</div>
- <el-form :model="form" label-width="80px">
- <el-form-item label="物流单号">
- <el-select v-model="form.selectedLogisticNo" placeholder="请选择物流单号" @change="handleLogisticNoChange" style="width: 100%">
- <el-option
- v-for="item in logisticsList"
- :key="item.id"
- :label="`${item.logisticNo},${getDictLabel(deliver_method, item.deliverMethod)}`"
- :value="item.logisticNo"
- />
- </el-select>
- </el-form-item>
- </el-form>
- <div class="section-title">物流信息</div>
- <el-timeline v-if="logisticsInfo.length > 0">
- <el-timeline-item v-for="(item, index) in logisticsInfo" :key="index" :timestamp="item.time" placement="top">
- <div class="timeline-content">
- <div class="timeline-status">{{ index + 1 }}</div>
- <div class="timeline-detail">
- <div>{{ item.time }}</div>
- <div>{{ item.location }}</div>
- <div>{{ item.status }}</div>
- </div>
- </div>
- </el-timeline-item>
- </el-timeline>
- <el-empty v-else description="暂无物流信息" />
- </div>
- </el-drawer>
- </template>
- <script setup lang="ts">
- import { listOrderDeliver, queryTrack } from '@/api/order/orderDeliver';
- import { OrderDeliverVO } from '@/api/order/orderDeliver/types';
- interface Props {
- modelValue: boolean;
- orderId?: string | number;
- }
- interface LogisticsInfo {
- time: string;
- location: string;
- status: string;
- }
- const props = defineProps<Props>();
- const emit = defineEmits(['update:modelValue']);
- const { proxy } = getCurrentInstance() as ComponentInternalInstance;
- const { deliver_method } = toRefs<any>(proxy?.useDict('deliver_method'));
- const visible = ref(false);
- const logisticsList = ref<OrderDeliverVO[]>([]);
- const form = ref({
- selectedLogisticNo: ''
- });
- const logisticsInfo = ref<LogisticsInfo[]>([]);
- watch(
- () => props.modelValue,
- (val) => {
- visible.value = val;
- if (val && props.orderId) {
- loadLogisticsList();
- }
- }
- );
- watch(visible, (val) => {
- emit('update:modelValue', val);
- });
- const loadLogisticsList = async () => {
- try {
- const res = await listOrderDeliver({
- orderId: props.orderId,
- pageNum: 1,
- pageSize: 100
- });
- logisticsList.value = res.rows || [];
- if (logisticsList.value.length > 0) {
- form.value.selectedLogisticNo = logisticsList.value[0].logisticNo;
- handleLogisticNoChange(form.value.selectedLogisticNo);
- }
- } catch (error) {
- console.error('Failed to load logistics list:', error);
- }
- };
- const handleLogisticNoChange = async (logisticNo: string) => {
- const selected = logisticsList.value.find((item) => item.logisticNo === logisticNo);
- if (!selected) return;
- try {
- const res = await queryTrack({
- logisticNo: logisticNo,
- pageNum: 1,
- pageSize: 100
- });
- if (res.data && Array.isArray(res.data) && res.data.length > 0) {
- logisticsInfo.value = res.data.map((item: any) => ({
- time: item.acceptTime || item.time || '',
- location: selected.orderCode ? `${selected.orderCode}` : '',
- status: item.context || ''
- }));
- } else {
- logisticsInfo.value = [
- {
- time: (selected as any).createTime || '',
- location: selected.orderCode ? `${selected.orderCode}` : '',
- status: '已下单'
- }
- ];
- }
- } catch (error) {
- console.error('Failed to query track:', error);
- logisticsInfo.value = [
- {
- time: (selected as any).createTime || '',
- location: selected.orderCode ? `${selected.orderCode}` : '',
- status: '已下单'
- }
- ];
- }
- };
- const getDictLabel = (dictOptions: any[], value: string) => {
- if (!dictOptions || !value) return value;
- const dict = dictOptions.find((item) => item.value === value);
- return dict ? dict.label : value;
- };
- const handleClose = () => {
- visible.value = false;
- form.value.selectedLogisticNo = '';
- logisticsInfo.value = [];
- };
- </script>
- <style scoped lang="scss">
- .logistics-detail {
- .section-title {
- font-size: 16px;
- font-weight: 500;
- margin-bottom: 16px;
- color: #303133;
- }
- .timeline-content {
- display: flex;
- align-items: flex-start;
- gap: 12px;
- .timeline-status {
- width: 24px;
- height: 24px;
- border-radius: 50%;
- background-color: #409eff;
- color: white;
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 12px;
- flex-shrink: 0;
- }
- .timeline-detail {
- flex: 1;
- div {
- margin-bottom: 4px;
- color: #606266;
- font-size: 14px;
- &:last-child {
- margin-bottom: 0;
- }
- }
- }
- }
- :deep(.el-timeline-item__timestamp) {
- display: none;
- }
- }
- </style>
|