752 lines
21 KiB
Vue
752 lines
21 KiB
Vue
<template>
|
||
<DrawerPro padding-bottom="16px" @register="register" @cancel="handleCancel">
|
||
<div class="detail-drawer-container">
|
||
<!-- Tab 切换 -->
|
||
<div class="detail-tabs">
|
||
<a-tabs
|
||
v-model:active-key="activeTab"
|
||
type="line"
|
||
size="large"
|
||
@change="handleTabChange"
|
||
>
|
||
<a-tab-pane
|
||
v-for="tab in tabList"
|
||
:key="tab.key"
|
||
:title="tab.label"
|
||
/>
|
||
</a-tabs>
|
||
</div>
|
||
|
||
<!-- Tab 内容 -->
|
||
<div class="detail-tab-content">
|
||
<!-- 明细 -->
|
||
<div v-if="activeTab === 'detail'" class="detail-content">
|
||
<!-- 操作按钮和开关 -->
|
||
<div class="detail-toolbar">
|
||
<div class="custom-buttons">
|
||
<a-button
|
||
class="btn-add"
|
||
type="primary"
|
||
size="small"
|
||
@click="handleAction('add')"
|
||
>
|
||
{{ $t('track.order.actions.addTrajectory') }}
|
||
</a-button>
|
||
<a-button
|
||
class="btn-update"
|
||
size="small"
|
||
@click="handleAction('update')"
|
||
>
|
||
{{ $t('track.order.actions.updateTrajectory') }}
|
||
</a-button>
|
||
<a-button
|
||
class="btn-delete"
|
||
size="small"
|
||
:disabled="!hasSelectedRows"
|
||
@click="handleAction('delete')"
|
||
>
|
||
{{ $t('track.order.actions.deleteTrajectory') }}
|
||
</a-button>
|
||
<a-button
|
||
class="btn-push"
|
||
size="small"
|
||
@click="handleAction('push')"
|
||
>
|
||
{{ $t('track.order.actions.pushTrajectory') }}
|
||
</a-button>
|
||
</div>
|
||
<div class="toolbar-right">
|
||
<a-checkbox :checked="isSourceTrajectory" @change="handleSourceTrajectoryChange">
|
||
{{ $t('track.order.detail.showAllSourceTrajectory') }}
|
||
</a-checkbox>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Handsontable 表格 -->
|
||
<div class="handsontable-container">
|
||
<div ref="detailHotContainer" class="handsontable-wrapper ht-theme-classic"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 推送记录 -->
|
||
<div v-if="activeTab === 'pushRecord'" class="push-record-content">
|
||
<!-- Handsontable 表格 -->
|
||
<div class="handsontable-container">
|
||
<div ref="pushRecordHotContainer" class="handsontable-wrapper ht-theme-classic"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 日志 -->
|
||
<div v-if="activeTab === 'log'" class="log-content">
|
||
<!-- Handsontable 表格 -->
|
||
<div class="handsontable-container">
|
||
<div ref="logHotContainer" class="handsontable-wrapper ht-theme-classic"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 轨迹抓取配置 -->
|
||
<div v-if="activeTab === 'pullConfig'" class="pull-config-content">
|
||
<a-spin :loading="pullConfigLoading">
|
||
<pre v-if="pullConfigJson" class="pull-config-json">{{ pullConfigJson }}</pre>
|
||
<a-empty v-else-if="!pullConfigLoading" :description="$t('track.order.pullConfig.noData')" />
|
||
</a-spin>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</DrawerPro>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { ref, computed, nextTick, watch, onUnmounted } from 'vue';
|
||
import { useI18n } from 'vue-i18n';
|
||
import Handsontable from 'handsontable';
|
||
import useDrawer from '@/components/DrawerPro/useDrawer';
|
||
import { $baseMessage } from '@/utils';
|
||
import { getGetTrackPushRecords, getGetOrderOperationsById } from '@/api/TrackOrder/trackOrder';
|
||
import { postOrderFindOrderPullConfigs } from '@/api/InterfaceMappingProvider/order';
|
||
|
||
const { t } = useI18n();
|
||
|
||
interface Props {
|
||
orderId?: number;
|
||
orderNumber?: string;
|
||
orderType?: number;
|
||
appKey?: string;
|
||
detailData?: API.TrackOrderDetailDto[];
|
||
isSourceTrajectory?: boolean;
|
||
}
|
||
|
||
const props = withDefaults(defineProps<Props>(), {
|
||
orderId: undefined,
|
||
orderNumber: '',
|
||
orderType: 1,
|
||
appKey: '',
|
||
detailData: () => [],
|
||
isSourceTrajectory: false
|
||
});
|
||
|
||
const emit = defineEmits<{
|
||
action: [type: 'add' | 'update' | 'delete' | 'push', orderNumber?: string];
|
||
cancel: [];
|
||
rowSelect: [row: any];
|
||
toggleSourceTrajectory: [show: boolean];
|
||
}>();
|
||
|
||
const [register, { openDrawer: innerOpenDrawer, setDrawerProps, closeDrawer }] = useDrawer();
|
||
|
||
// Tab 相关
|
||
const activeTab = ref('detail');
|
||
const tabList = computed(() => [
|
||
{ key: 'detail', label: t('track.order.drawer.tabs.detail') },
|
||
{ key: 'pushRecord', label: t('track.order.drawer.tabs.pushRecord') },
|
||
{ key: 'log', label: t('track.order.drawer.tabs.log') },
|
||
{ key: 'pullConfig', label: t('track.order.drawer.tabs.pullConfig') }
|
||
]);
|
||
|
||
// Handsontable 容器和实例
|
||
const detailHotContainer = ref<HTMLElement | null>(null);
|
||
const pushRecordHotContainer = ref<HTMLElement | null>(null);
|
||
const logHotContainer = ref<HTMLElement | null>(null);
|
||
let detailHotInstance: Handsontable | null = null;
|
||
let pushRecordHotInstance: Handsontable | null = null;
|
||
let logHotInstance: Handsontable | null = null;
|
||
|
||
// 数据
|
||
const sourceTrajectoryData = ref<API.TrackOrderDetailDto[]>([]);
|
||
const pushRecordData = ref<any[]>([]);
|
||
const logData = ref<any[]>([]);
|
||
const detailSelectAll = ref(false);
|
||
const selectedDetailRows = ref<any[]>([]);
|
||
const pullConfigData = ref<any>(null);
|
||
const pullConfigLoading = ref(false);
|
||
|
||
const hasSelectedRows = computed(() => selectedDetailRows.value.length > 0);
|
||
|
||
// 轨迹抓取配置:报文 JSON 展示
|
||
const pullConfigJson = computed(() => {
|
||
const data = pullConfigData.value;
|
||
if (!data) return '';
|
||
try {
|
||
return JSON.stringify(data, null, 2);
|
||
} catch {
|
||
return String(data);
|
||
}
|
||
});
|
||
|
||
// 监听详情数据变化
|
||
watch(() => props.detailData, (newData) => {
|
||
if (newData && newData.length > 0) {
|
||
sourceTrajectoryData.value = newData.map((item: any) => ({
|
||
...item,
|
||
checked: false
|
||
}));
|
||
if (activeTab.value === 'detail') {
|
||
nextTick(() => {
|
||
initDetailHandsontable();
|
||
});
|
||
}
|
||
}
|
||
}, { immediate: true, deep: true });
|
||
|
||
// 处理服务商轨迹开关变化
|
||
function handleSourceTrajectoryChange(checked: boolean) {
|
||
emit('toggleSourceTrajectory', checked);
|
||
}
|
||
|
||
// 创建只带省略号、不带气泡(tooltip)的单元格渲染器
|
||
const createEllipsisRenderer = () => {
|
||
return function(instance: any, td: any, row: number, col: number, prop: any, value: any) {
|
||
const text = value || '--';
|
||
const textStr = String(text);
|
||
|
||
td.style.textAlign = 'left';
|
||
td.style.verticalAlign = 'middle';
|
||
td.style.overflow = 'hidden';
|
||
td.style.textOverflow = 'ellipsis';
|
||
td.style.whiteSpace = 'nowrap';
|
||
td.style.padding = '7px 16px';
|
||
|
||
td.textContent = textStr;
|
||
};
|
||
};
|
||
|
||
// 初始化明细列表 Handsontable
|
||
const initDetailHandsontable = () => {
|
||
if (!detailHotContainer.value) {
|
||
return;
|
||
}
|
||
|
||
if (detailHotInstance) {
|
||
detailHotInstance.destroy();
|
||
detailHotInstance = null;
|
||
}
|
||
|
||
const ellipsisRenderer = createEllipsisRenderer();
|
||
|
||
const columns = [
|
||
{
|
||
data: 0,
|
||
type: 'checkbox',
|
||
width: 50,
|
||
className: 'htLeft',
|
||
},
|
||
{
|
||
data: 1,
|
||
type: 'text',
|
||
readOnly: true,
|
||
width: 60,
|
||
className: 'htLeft',
|
||
renderer: ellipsisRenderer,
|
||
},
|
||
{
|
||
data: 2,
|
||
type: 'text',
|
||
readOnly: true,
|
||
width: 120,
|
||
className: 'htLeft',
|
||
renderer: ellipsisRenderer,
|
||
},
|
||
{
|
||
data: 3,
|
||
type: 'text',
|
||
readOnly: true,
|
||
width: 120,
|
||
className: 'htLeft',
|
||
renderer: ellipsisRenderer,
|
||
},
|
||
{
|
||
data: 4,
|
||
type: 'text',
|
||
readOnly: true,
|
||
width: 200,
|
||
className: 'htLeft',
|
||
renderer: ellipsisRenderer,
|
||
},
|
||
{
|
||
data: 5,
|
||
type: 'text',
|
||
readOnly: true,
|
||
width: 180,
|
||
className: 'htLeft',
|
||
renderer: ellipsisRenderer,
|
||
},
|
||
{
|
||
data: 6,
|
||
type: 'text',
|
||
readOnly: true,
|
||
width: 250,
|
||
className: 'htLeft',
|
||
renderer: ellipsisRenderer,
|
||
},
|
||
{
|
||
data: 7,
|
||
type: 'text',
|
||
readOnly: true,
|
||
width: 250,
|
||
className: 'htLeft',
|
||
renderer: ellipsisRenderer,
|
||
},
|
||
{
|
||
data: 8,
|
||
type: 'text',
|
||
readOnly: true,
|
||
width: 120,
|
||
className: 'htLeft',
|
||
renderer: ellipsisRenderer,
|
||
},
|
||
{
|
||
data: 9,
|
||
type: 'text',
|
||
readOnly: true,
|
||
width: 120,
|
||
className: 'htCenter',
|
||
renderer: function(instance: any, td: any, row: number, col: number, prop: any, value: any) {
|
||
td.style.textAlign = 'center';
|
||
td.style.verticalAlign = 'middle';
|
||
const isVisibility = value;
|
||
td.textContent = isVisibility ? t('track.order.common.yes') : t('track.order.common.no');
|
||
},
|
||
},
|
||
{
|
||
data: 10,
|
||
type: 'text',
|
||
readOnly: true,
|
||
width: 150,
|
||
className: 'htLeft',
|
||
renderer: ellipsisRenderer,
|
||
},
|
||
{
|
||
data: 11,
|
||
type: 'text',
|
||
readOnly: true,
|
||
width: 120,
|
||
className: 'htLeft',
|
||
renderer: ellipsisRenderer,
|
||
},
|
||
{
|
||
data: 12,
|
||
type: 'text',
|
||
readOnly: true,
|
||
width: 120,
|
||
className: 'htLeft',
|
||
renderer: function(instance: any, td: any, row: number, col: number, prop: any, value: any) {
|
||
const sourceText = value === 1 ? t('track.order.detail.trajectoryType.external')
|
||
: value === 2 ? t('track.order.detail.trajectoryType.internal')
|
||
: value === 3 ? t('track.order.detail.trajectoryType.manual')
|
||
: '--';
|
||
td.textContent = sourceText;
|
||
td.style.textAlign = 'left';
|
||
td.style.verticalAlign = 'middle';
|
||
},
|
||
},
|
||
];
|
||
|
||
const colHeaders = [
|
||
'',
|
||
t('track.order.table.serialNo'),
|
||
t('track.order.detail.title.trackTime'),
|
||
t('track.order.detail.title.trackTimeZone'),
|
||
t('track.order.detail.title.trackPlace'),
|
||
t('track.order.detail.title.trajectoryContent'),
|
||
t('track.order.detail.title.trajectoryContentEn'),
|
||
t('track.order.detail.title.originTrackContent'),
|
||
t('track.order.detail.title.pushDetail'),
|
||
t('track.order.detail.title.isVisibility'),
|
||
t('track.order.table.createTime'),
|
||
t('track.order.detail.title.createUser'),
|
||
t('track.order.detail.title.trajectoryType'),
|
||
];
|
||
|
||
const data = sourceTrajectoryData.value.map((row, index) => [
|
||
(row as any).checked || false,
|
||
index + 1,
|
||
row.trackTime || '--',
|
||
row.trackTimeZoneValue !== undefined && row.trackTimeZoneValue !== null ? String(row.trackTimeZoneValue) : '--',
|
||
row.trackPlace || '--',
|
||
row.content || '--',
|
||
row.enContent || '--',
|
||
row.originTrackContent || '--',
|
||
(row as any).pushContent || '--',
|
||
row.isVisibility !== undefined && row.isVisibility !== null ? row.isVisibility : false,
|
||
row.createTime || '--',
|
||
row.createUser || '--',
|
||
row.source ?? '--',
|
||
]);
|
||
|
||
try {
|
||
detailHotInstance = new Handsontable(detailHotContainer.value, {
|
||
data: data,
|
||
columns: columns,
|
||
colHeaders: colHeaders,
|
||
rowHeaders: false,
|
||
width: '100%',
|
||
height: 1000,
|
||
licenseKey: 'non-commercial-and-evaluation',
|
||
className: 'ht-theme-classic',
|
||
language: 'zh-CN',
|
||
readOnly: false,
|
||
contextMenu: false,
|
||
manualColumnResize: true,
|
||
stretchH: 'all',
|
||
afterChange: function(changes: any, source: string) {
|
||
if (source === 'edit' && changes) {
|
||
changes.forEach(([row, col, oldValue, newValue]: any[]) => {
|
||
if (col === 0) {
|
||
const dataRow = sourceTrajectoryData.value[row];
|
||
if (dataRow) {
|
||
(dataRow as any).checked = newValue || false;
|
||
handleDetailRowSelect(dataRow);
|
||
}
|
||
}
|
||
});
|
||
}
|
||
},
|
||
});
|
||
} catch (error) {
|
||
console.error('初始化明细列表 Handsontable 失败:', error);
|
||
}
|
||
};
|
||
|
||
// 更新明细 Handsontable
|
||
const updateDetailHandsontableData = () => {
|
||
if (!detailHotInstance || !sourceTrajectoryData.value.length) {
|
||
return;
|
||
}
|
||
|
||
const data = sourceTrajectoryData.value.map((row, index) => [
|
||
(row as any).checked || false,
|
||
index + 1,
|
||
row.trackTime || '--',
|
||
row.trackTimeZoneValue !== undefined && row.trackTimeZoneValue !== null ? String(row.trackTimeZoneValue) : '--',
|
||
row.trackPlace || '--',
|
||
row.content || '--',
|
||
row.enContent || '--',
|
||
row.originTrackContent || '--',
|
||
(row as any).pushContent || '--',
|
||
row.isVisibility !== undefined && row.isVisibility !== null ? row.isVisibility : false,
|
||
row.createTime || '--',
|
||
row.createUser || '--',
|
||
row.source ?? '--',
|
||
]);
|
||
|
||
detailHotInstance.loadData(data);
|
||
detailHotInstance.render();
|
||
};
|
||
|
||
// 初始化推送记录列表 Handsontable
|
||
const initPushRecordHandsontable = () => {
|
||
if (!pushRecordHotContainer.value) {
|
||
return;
|
||
}
|
||
|
||
if (pushRecordHotInstance) {
|
||
pushRecordHotInstance.destroy();
|
||
pushRecordHotInstance = null;
|
||
}
|
||
|
||
const ellipsisRenderer = createEllipsisRenderer();
|
||
|
||
const columns = [
|
||
{ data: 0, type: 'text', readOnly: true, width: 80, className: 'htLeft', renderer: ellipsisRenderer },
|
||
{ data: 1, type: 'text', readOnly: true, width: 150, className: 'htLeft', renderer: ellipsisRenderer },
|
||
{ data: 2, type: 'text', readOnly: true, width: 100, className: 'htLeft', renderer: ellipsisRenderer },
|
||
{ data: 3, type: 'text', readOnly: true, width: 200, className: 'htLeft', renderer: ellipsisRenderer },
|
||
{ data: 4, type: 'text', readOnly: true, width: 120, className: 'htLeft', renderer: ellipsisRenderer },
|
||
{ data: 5, type: 'text', readOnly: true, width: 120, className: 'htLeft', renderer: ellipsisRenderer },
|
||
{ data: 6, type: 'text', readOnly: true, width: 120, className: 'htLeft', renderer: ellipsisRenderer },
|
||
{ data: 7, type: 'text', readOnly: true, width: 200, className: 'htLeft', renderer: ellipsisRenderer },
|
||
{ data: 8, type: 'text', readOnly: true, width: 150, className: 'htLeft', renderer: ellipsisRenderer },
|
||
{ data: 9, type: 'text', readOnly: true, width: 120, className: 'htLeft', renderer: ellipsisRenderer },
|
||
{ data: 10, type: 'text', readOnly: true, width: 300, className: 'htLeft', renderer: ellipsisRenderer },
|
||
{ data: 11, type: 'text', readOnly: true, width: 180, className: 'htLeft', renderer: ellipsisRenderer },
|
||
];
|
||
|
||
const colHeaders = [
|
||
t('track.order.table.serialNo'),
|
||
t('track.order.pushRecord.table.requestId'),
|
||
t('track.order.pushRecord.table.isSuccess'),
|
||
t('track.order.pushRecord.table.message'),
|
||
t('track.order.pushRecord.table.optionType'),
|
||
t('track.order.pushRecord.table.trackStatus'),
|
||
t('track.order.pushRecord.table.trackCode'),
|
||
t('track.order.pushRecord.table.trackContent'),
|
||
t('track.order.pushRecord.table.trackPlace'),
|
||
t('track.order.pushRecord.table.trackGTMTimeZone'),
|
||
t('track.order.pushRecord.table.pushContent'),
|
||
t('track.order.pushRecord.table.createTime'),
|
||
];
|
||
|
||
const data = pushRecordData.value.map((row, index) => [
|
||
index + 1,
|
||
row.requestId || '--',
|
||
row.isSuccess ? t('track.order.common.yes') : t('track.order.common.no'),
|
||
row.message || '--',
|
||
row.optionType || '--',
|
||
row.trackStatus || '--',
|
||
row.trackCode || '--',
|
||
row.trackContent || '--',
|
||
row.trackPlace || '--',
|
||
row.trackGTMTimeZone || '--',
|
||
row.pushContent || '--',
|
||
row.createTime || '--',
|
||
]);
|
||
|
||
try {
|
||
pushRecordHotInstance = new Handsontable(pushRecordHotContainer.value, {
|
||
data: data,
|
||
columns: columns,
|
||
colHeaders: colHeaders,
|
||
rowHeaders: false,
|
||
width: '100%',
|
||
height: 1000,
|
||
licenseKey: 'non-commercial-and-evaluation',
|
||
className: 'ht-theme-classic',
|
||
language: 'zh-CN',
|
||
readOnly: true,
|
||
contextMenu: false,
|
||
manualColumnResize: true,
|
||
stretchH: 'all',
|
||
});
|
||
} catch (error) {
|
||
console.error('初始化推送记录 Handsontable 失败:', error);
|
||
}
|
||
};
|
||
|
||
// 初始化日志列表 Handsontable
|
||
const initLogHandsontable = () => {
|
||
if (!logHotContainer.value) {
|
||
return;
|
||
}
|
||
|
||
if (logHotInstance) {
|
||
logHotInstance.destroy();
|
||
logHotInstance = null;
|
||
}
|
||
|
||
const ellipsisRenderer = createEllipsisRenderer();
|
||
|
||
const columns = [
|
||
{ data: 0, type: 'text', readOnly: true, width: 80, className: 'htLeft', renderer: ellipsisRenderer },
|
||
{ data: 1, type: 'text', readOnly: true, width: 180, className: 'htLeft', renderer: ellipsisRenderer },
|
||
{ data: 2, type: 'text', readOnly: true, width: 400, className: 'htLeft', renderer: ellipsisRenderer },
|
||
{ data: 3, type: 'text', readOnly: true, width: 150, className: 'htLeft', renderer: ellipsisRenderer },
|
||
{ data: 4, type: 'text', readOnly: true, width: 150, className: 'htLeft', renderer: ellipsisRenderer },
|
||
];
|
||
|
||
const colHeaders = [
|
||
t('track.order.table.serialNo'),
|
||
t('track.order.log.table.createTime'),
|
||
t('track.order.log.table.content'),
|
||
t('track.order.log.table.optionType'),
|
||
t('track.order.log.table.createUserName'),
|
||
];
|
||
|
||
const data = logData.value.map((row, index) => [
|
||
index + 1,
|
||
row.createTime || '--',
|
||
row.content || '--',
|
||
row.optionType || '--',
|
||
row.createUserName || '--',
|
||
]);
|
||
|
||
try {
|
||
logHotInstance = new Handsontable(logHotContainer.value, {
|
||
data: data,
|
||
columns: columns,
|
||
colHeaders: colHeaders,
|
||
rowHeaders: false,
|
||
width: '100%',
|
||
height: 400,
|
||
licenseKey: 'non-commercial-and-evaluation',
|
||
className: 'ht-theme-classic',
|
||
language: 'zh-CN',
|
||
readOnly: true,
|
||
contextMenu: false,
|
||
manualColumnResize: true,
|
||
stretchH: 'all',
|
||
});
|
||
} catch (error) {
|
||
console.error('初始化日志 Handsontable 失败:', error);
|
||
}
|
||
};
|
||
|
||
// 加载推送记录数据
|
||
async function loadPushRecordData(orderId: number) {
|
||
try {
|
||
const response: any = await getGetTrackPushRecords({ orderId });
|
||
pushRecordData.value = response?.data || response || [];
|
||
nextTick(() => {
|
||
initPushRecordHandsontable();
|
||
});
|
||
} catch (error) {
|
||
$baseMessage('加载推送记录失败', 'error');
|
||
pushRecordData.value = [];
|
||
}
|
||
}
|
||
|
||
// 加载日志数据
|
||
async function loadLogData(orderId: number) {
|
||
try {
|
||
const response: any = await getGetOrderOperationsById({ orderId });
|
||
logData.value = response?.data || response || [];
|
||
nextTick(() => {
|
||
initLogHandsontable();
|
||
});
|
||
} catch (error) {
|
||
$baseMessage('加载日志数据失败', 'error');
|
||
logData.value = [];
|
||
}
|
||
}
|
||
|
||
// 加载轨迹抓取配置
|
||
async function loadPullConfigData() {
|
||
if (!props.appKey || !props.orderNumber) {
|
||
pullConfigData.value = null;
|
||
return;
|
||
}
|
||
pullConfigLoading.value = true;
|
||
pullConfigData.value = null;
|
||
try {
|
||
const orderNos = props.orderNumber.split(',').map((s) => s.trim()).filter(Boolean);
|
||
const response: any = await postOrderFindOrderPullConfigs({
|
||
appKey: props.appKey,
|
||
orderType: props.orderType ?? 1,
|
||
orderNos
|
||
});
|
||
pullConfigData.value = response ?? null;
|
||
} catch (error) {
|
||
$baseMessage('加载轨迹抓取配置失败', 'error');
|
||
pullConfigData.value = null;
|
||
} finally {
|
||
pullConfigLoading.value = false;
|
||
}
|
||
}
|
||
|
||
// 处理 Tab 切换
|
||
function handleTabChange(tabKey: string) {
|
||
if (!props.orderId && tabKey !== 'pullConfig') return;
|
||
|
||
switch (tabKey) {
|
||
case 'detail':
|
||
nextTick(() => {
|
||
initDetailHandsontable();
|
||
});
|
||
break;
|
||
case 'pushRecord':
|
||
loadPushRecordData(props.orderId!);
|
||
break;
|
||
case 'log':
|
||
loadLogData(props.orderId!);
|
||
break;
|
||
case 'pullConfig':
|
||
loadPullConfigData();
|
||
break;
|
||
}
|
||
}
|
||
|
||
// 处理操作按钮点击
|
||
function handleAction(type: 'add' | 'update' | 'delete' | 'push') {
|
||
emit('action', type, props.orderNumber);
|
||
}
|
||
|
||
// 处理行选择
|
||
function handleDetailRowSelect(row: any) {
|
||
selectedDetailRows.value = sourceTrajectoryData.value.filter((r: any) => r.checked);
|
||
emit('rowSelect', row);
|
||
}
|
||
|
||
// 处理取消
|
||
function handleCancel() {
|
||
emit('cancel');
|
||
}
|
||
|
||
// 暴露方法
|
||
defineExpose({
|
||
openDrawer: () => {
|
||
// 每次打开详情时,默认切回“明细”Tab
|
||
activeTab.value = 'detail';
|
||
innerOpenDrawer();
|
||
},
|
||
setDrawerProps,
|
||
closeDrawer,
|
||
updateDetailData: () => {
|
||
if (activeTab.value === 'detail') {
|
||
updateDetailHandsontableData();
|
||
}
|
||
},
|
||
getSelectedRows: () => selectedDetailRows.value
|
||
});
|
||
|
||
// 清理
|
||
onUnmounted(() => {
|
||
if (detailHotInstance) {
|
||
detailHotInstance.destroy();
|
||
detailHotInstance = null;
|
||
}
|
||
if (pushRecordHotInstance) {
|
||
pushRecordHotInstance.destroy();
|
||
pushRecordHotInstance = null;
|
||
}
|
||
if (logHotInstance) {
|
||
logHotInstance.destroy();
|
||
logHotInstance = null;
|
||
}
|
||
});
|
||
</script>
|
||
|
||
<style lang="less" scoped>
|
||
.detail-drawer-container {
|
||
display: flex;
|
||
flex-direction: column;
|
||
height: 100%;
|
||
|
||
.detail-tabs {
|
||
margin-bottom: 16px;
|
||
}
|
||
|
||
.detail-tab-content {
|
||
flex: 1;
|
||
overflow: hidden;
|
||
|
||
.detail-content,
|
||
.push-record-content,
|
||
.log-content {
|
||
height: 100%;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.pull-config-content {
|
||
padding: 16px 0;
|
||
min-height: 200px;
|
||
|
||
.pull-config-json {
|
||
margin: 0;
|
||
padding: 12px;
|
||
background: #f7f8fa;
|
||
border-radius: 4px;
|
||
font-size: 12px;
|
||
line-height: 1.5;
|
||
overflow: auto;
|
||
white-space: pre-wrap;
|
||
word-break: break-all;
|
||
}
|
||
}
|
||
}
|
||
|
||
.handsontable-container {
|
||
width: 100%;
|
||
border: 0.5px solid #f0f0f0;
|
||
border-radius: 4px;
|
||
overflow: hidden;
|
||
flex: 1;
|
||
min-height: 0;
|
||
|
||
.handsontable-wrapper {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
}
|
||
}
|
||
</style>
|