You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

405 lines
14 KiB

4 weeks ago
<template>
<el-dialog v-model="visible" title="船舶历史记录" width="1200px" :before-close="handleClose">
<el-tabs v-model="activeTab">
<!-- 船舶靠泊历史记录 tab -->
<el-tab-pane label="船舶靠泊历史记录" name="shipBerthing">
<!-- 搜索和筛选区域 -->
<div class="filter-container">
<el-form :model="berthingQueryParams" label-width="80px" inline>
<el-form-item label="关键字">
4 weeks ago
<el-input v-model="berthingQueryParams.keyword" placeholder="请输入关键字搜索" clearable
@keyup.enter="handleBerthingSearch" />
4 weeks ago
</el-form-item>
<el-form-item label="时间范围">
<el-date-picker v-model="berthingDateRange" type="daterange" range-separator="" start-placeholder="开始日期"
end-placeholder="结束日期" value-format="YYYY-MM-DD" @change="handleBerthingDateChange" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleBerthingSearch">搜索</el-button>
<el-button @click="resetBerthingQuery">重置</el-button>
</el-form-item>
</el-form>
</div>
<!-- 数据表格 -->
<el-table :data="berthingTableData" border stripe style="width: 100%" v-loading="berthingLoading">
4 weeks ago
<el-table-column v-for="column in berthingColumns" :key="column.prop" :prop="column.prop"
:label="column.label" :width="column.width" :formatter="column.formatter" />
4 weeks ago
</el-table>
<!-- 分页 -->
<div class="pagination-container">
4 weeks ago
<el-pagination v-model:current-page="berthingQueryParams.pageNo"
v-model:page-size="berthingQueryParams.pageSize" :page-sizes="[10, 20, 50, 100]" :total="berthingTotal"
layout="total, sizes, prev, pager, next, jumper" @size-change="handleBerthingSizeChange"
@current-change="handleBerthingCurrentChange" />
4 weeks ago
</div>
</el-tab-pane>
<!-- 船舶连接岸电箱历史记录 tab -->
<el-tab-pane label="船舶连接岸电箱历史记录" name="shorePowerConnection">
<!-- 搜索和筛选区域 -->
<div class="filter-container">
<el-form :model="shorePowerConnectionQueryParams" label-width="80px" inline>
<el-form-item label="关键字">
<el-input v-model="shorePowerConnectionQueryParams.keyword" placeholder="请输入关键字搜索" clearable
@keyup.enter="handleShorePowerConnectionSearch" />
</el-form-item>
<el-form-item label="时间范围">
<el-date-picker v-model="shorePowerConnectionDateRange" type="daterange" range-separator=""
start-placeholder="开始日期" end-placeholder="结束日期" value-format="YYYY-MM-DD"
@change="handleShorePowerConnectionDateChange" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleShorePowerConnectionSearch">搜索</el-button>
<el-button @click="resetShorePowerConnectionQuery">重置</el-button>
</el-form-item>
</el-form>
</div>
<!-- 数据表格 -->
4 weeks ago
<el-table :data="shorePowerConnectionTableData" border stripe style="width: 100%"
v-loading="shorePowerConnectionLoading">
<el-table-column v-for="column in shorePowerConnectionColumns" :key="column.prop" :prop="column.prop"
:label="column.label" :width="column.width" :formatter="column.formatter" />
4 weeks ago
</el-table>
<!-- 分页 -->
<div class="pagination-container">
4 weeks ago
<el-pagination v-model:current-page="shorePowerConnectionQueryParams.pageNo"
v-model:page-size="shorePowerConnectionQueryParams.pageSize" :page-sizes="[10, 20, 50, 100]"
:total="shorePowerConnectionTotal" layout="total, sizes, prev, pager, next, jumper"
@size-change="handleShorePowerConnectionSizeChange"
@current-change="handleShorePowerConnectionCurrentChange" />
4 weeks ago
</div>
</el-tab-pane>
</el-tabs>
<template #footer>
<span class="dialog-footer">
<el-button @click="handleClose">关闭</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { ref, computed, watch } from 'vue'
4 weeks ago
import { MapApi } from "@/api/shorepower/map";
import {
ElDialog,
ElTabs,
ElTabPane,
ElForm,
ElFormItem,
ElInput,
ElDatePicker,
ElButton,
ElTable,
ElTableColumn,
ElPagination
4 weeks ago
} from 'element-plus'
4 weeks ago
import { CARGO_CATEGORY, getOperationTypeLabel, OPERATION_TYPE } from './dictionaryTable';
import { formatDuration, formatTimestamp, showStatus } from './utils';
import { RealtimeDeviceData } from '@/types/shorepower';
4 weeks ago
// 定义组件属性
interface Props {
modelValue: boolean
berthingData?: any[]
4 weeks ago
shipId?: number
4 weeks ago
shorePowerConnectionData?: any[]
4 weeks ago
realtimeDeviceData: RealtimeDeviceData[];
4 weeks ago
}
// 定义事件
const emit = defineEmits<{
(e: 'update:modelValue', value: boolean): void
(e: 'berthing-search', params: any): void
(e: 'shore-power-connection-search', params: any): void
}>()
// 属性定义
const props = withDefaults(defineProps<Props>(), {
modelValue: false,
4 weeks ago
shipId: 0,
4 weeks ago
berthingData: () => [],
shorePowerConnectionData: () => []
})
// 响应式数据
const visible = computed({
get: () => props.modelValue,
set: (val) => emit('update:modelValue', val)
})
const activeTab = ref('shipBerthing')
// 船舶靠泊历史记录相关数据
const berthingQueryParams = ref({
keyword: '',
startTime: '',
endTime: '',
pageNo: 1,
pageSize: 10
})
const berthingDateRange = ref<[string, string]>(['', ''])
const berthingLoading = ref(false)
const berthingTotal = ref(0)
// 船舶靠泊历史记录表格数据
4 weeks ago
const berthingTableData = ref<any[]>([])
4 weeks ago
// 船舶靠泊历史记录表格列
const berthingColumns = ref([
4 weeks ago
{
prop: 'shipBasicInfo',
label: '船舶名称-英文名称',
width: 200,
formatter: (row) => {
const name = row.shipBasicInfo?.name || '';
const nameEn = row.shipBasicInfo?.nameEn || '';
return `${name}${name && nameEn ? '-' : ''}${nameEn}`;
}
},
{ prop: 'shipBasicInfo.length', label: '船长', width: 200 },
{ prop: 'shipBasicInfo.width', label: '船宽', width: 150 },
{ prop: 'shipBasicInfo.tonnage', label: '最大载重', width: 150 },
{ prop: 'shipBasicInfo.voyage', label: '航线', width: 150 },
{ prop: 'applyInfo.departureHarborDistrict', label: '起运港', width: 150 },
{ prop: 'applyInfo.arrivalHarborDistrict', label: '到达港', width: 150 },
{ prop: 'applyInfo.operationType', label: '靠泊类型', width: 150, formatter: (_row, _column, cellValue) => getOperationTypeLabel(cellValue, OPERATION_TYPE) },
{ prop: '', label: '作业内容', width: 180 },
{
prop: 'applyInfo.loadingCargoCategory', label: '货物类型', width: 180,
formatter: (row) => {
if (row.applyInfo.operationType === 1) {
return row.applyInfo.loadingCargoCategory;
} else if (row.applyInfo.operationType === 2) {
return row.applyInfo.unloadingCargoCategory;
} else if (row.applyInfo.operationType === 3) {
return '装' + row.applyInfo.loadingCargoCategory + '-卸' + row.applyInfo.unloadingCargoCategory
}
return '';
}
},
{
prop: 'applyInfo.loadingCargoCategory', label: '货物名称', width: 180,
formatter: (row) => {
if (row.applyInfo.operationType === 1) {
const label = getOperationTypeLabel(row.applyInfo.loadingCargoCategory, CARGO_CATEGORY);
return label;
} else if (row.applyInfo.operationType === 2) {
const label = getOperationTypeLabel(row.applyInfo.unloadingCargoCategory, CARGO_CATEGORY);
return label;
} else if (row.applyInfo.operationType === 3) {
return '装' + getOperationTypeLabel(row.applyInfo.loadingCargoCategory, CARGO_CATEGORY) + '-卸' + getOperationTypeLabel(row.applyInfo.unloadingCargoCategory, CARGO_CATEGORY)
}
return '';
}
},
{
prop: 'applyInfo.loadingCargoCategory', label: '货物吨数', width: 180,
formatter: (row) => {
if (row.applyInfo.operationType === 1) {
return row.applyInfo.loadingCargoTonnage;
} else if (row.applyInfo.operationType === 2) {
return row.applyInfo.unloadingCargoTonnage;
} else if (row.applyInfo.operationType === 3) {
return '装' + row.applyInfo.loadingCargoTonnage + '-卸' + row.applyInfo.unloadingCargoTonnage
}
return '';
}
},
{ prop: 'usageRecordInfo.actualBerthTime', label: '靠泊时间', width: 180, formatter: (row) => formatTimestamp(row.usageRecordInfo.actualBerthTime) },
{ prop: 'usageRecordInfo.actualDepartureTime', label: '离泊时间', width: 180, formatter: (row) => formatTimestamp(row.usageRecordInfo.actualDepartureTime) },
{
prop: 'useStatus.status', label: '岸电使用情况', width: 180,
formatter: (row) => {
const status = showStatus(row, props.realtimeDeviceData);
return status?.status || '';
}
},
4 weeks ago
])
// 船舶连接岸电箱历史记录相关数据
const shorePowerConnectionQueryParams = ref({
keyword: '',
startTime: '',
endTime: '',
pageNo: 1,
pageSize: 10
})
const shorePowerConnectionDateRange = ref<[string, string]>(['', ''])
const shorePowerConnectionLoading = ref(false)
const shorePowerConnectionTotal = ref(0)
// 船舶连接岸电箱历史记录表格数据
const shorePowerConnectionTableData = computed(() => {
// 在实际应用中,这里应该是从服务器获取的数据
// 当前为了演示,我们使用传入的模拟数据
return props.shorePowerConnectionData?.slice(
(shorePowerConnectionQueryParams.value.pageNo - 1) * shorePowerConnectionQueryParams.value.pageSize,
shorePowerConnectionQueryParams.value.pageNo * shorePowerConnectionQueryParams.value.pageSize
) || []
})
// 船舶连接岸电箱历史记录表格列
const shorePowerConnectionColumns = ref([
4 weeks ago
{ prop: 'name', label: 'name', width: 80 },
/* { prop: 'shorePowerName', label: '', width: 150 },
4 weeks ago
{ prop: 'time', label: '连接时间', width: 180 },
{ prop: 'duration', label: '连接时长(小时)', width: 120 },
{ prop: 'powerConsumption', label: '用电量(kWh)', width: 120 },
4 weeks ago
{ prop: 'status', label: '状态', width: 100 } */
4 weeks ago
])
// 处理关闭
const handleClose = () => {
visible.value = false
}
// 船舶靠泊历史记录相关方法
const handleBerthingSearch = () => {
// 发送搜索事件给父组件
emit('berthing-search', { ...berthingQueryParams.value })
}
const resetBerthingQuery = () => {
berthingQueryParams.value.keyword = ''
berthingQueryParams.value.startTime = ''
berthingQueryParams.value.endTime = ''
berthingDateRange.value = ['', '']
berthingQueryParams.value.pageNo = 1
handleBerthingSearch()
}
const handleBerthingDateChange = (val: [string, string] | null) => {
if (val && val[0] && val[1]) {
berthingQueryParams.value.startTime = val[0]
berthingQueryParams.value.endTime = val[1]
} else {
berthingQueryParams.value.startTime = ''
berthingQueryParams.value.endTime = ''
}
}
const handleBerthingSizeChange = (val: number) => {
berthingQueryParams.value.pageSize = val
berthingQueryParams.value.pageNo = 1
handleBerthingSearch()
}
const handleBerthingCurrentChange = (val: number) => {
berthingQueryParams.value.pageNo = val
handleBerthingSearch()
}
// 船舶连接岸电箱历史记录相关方法
const handleShorePowerConnectionSearch = () => {
// 发送搜索事件给父组件
emit('shore-power-connection-search', { ...shorePowerConnectionQueryParams.value })
}
const resetShorePowerConnectionQuery = () => {
shorePowerConnectionQueryParams.value.keyword = ''
shorePowerConnectionQueryParams.value.startTime = ''
shorePowerConnectionQueryParams.value.endTime = ''
shorePowerConnectionDateRange.value = ['', '']
shorePowerConnectionQueryParams.value.pageNo = 1
handleShorePowerConnectionSearch()
}
const handleShorePowerConnectionDateChange = (val: [string, string] | null) => {
if (val && val[0] && val[1]) {
shorePowerConnectionQueryParams.value.startTime = val[0]
shorePowerConnectionQueryParams.value.endTime = val[1]
} else {
shorePowerConnectionQueryParams.value.startTime = ''
shorePowerConnectionQueryParams.value.endTime = ''
}
}
const handleShorePowerConnectionSizeChange = (val: number) => {
shorePowerConnectionQueryParams.value.pageSize = val
shorePowerConnectionQueryParams.value.pageNo = 1
handleShorePowerConnectionSearch()
}
const handleShorePowerConnectionCurrentChange = (val: number) => {
shorePowerConnectionQueryParams.value.pageNo = val
handleShorePowerConnectionSearch()
}
// 监听数据变化并更新总数
watch(
() => props.berthingData,
(newData) => {
berthingTotal.value = newData?.length || 0
},
{ immediate: true }
)
watch(
() => props.shorePowerConnectionData,
(newData) => {
shorePowerConnectionTotal.value = newData?.length || 0
},
{ immediate: true }
)
4 weeks ago
watch(
() => props.shipId,
(newShipId) => {
if (newShipId) {
// 当船舶ID变化时,触发搜索
berthingTableData.value = []
handleGetShipHistortyList(newShipId)
}
}
)
const handleGetShipHistortyList = async (id) => {
console.log('handleGetShipHistortyList', id)
if (!id) return;
// try {
const res = await MapApi.getShipHistoryPage({
shipId: parseInt(id, 10), // 将字符串转换为数字
pageNo: 1,
pageSize: 10,
type: 4,
// ids: [parseInt(id, 10)]
})
console.log(res);
const buildData = await Promise.all(res.list.map(async item => ({
...item,
})))
berthingTableData.value = buildData
}
onMounted(() => {
console.log('页面加载了!')
console.log('props.shipId', props.shipId)
})
4 weeks ago
</script>
<style scoped>
.filter-container {
margin-bottom: 20px;
}
.pagination-container {
margin-top: 20px;
display: flex;
justify-content: flex-end;
}
.dialog-footer {
display: flex;
justify-content: flex-end;
gap: 10px;
}
</style>