feat: add BoatDialog

main
sankeyangshu 2024-12-03 18:09:14 +08:00
parent 580402c132
commit c82c62232e
8 changed files with 278 additions and 24 deletions

View File

@ -8,5 +8,5 @@ NODE_ENV = 'development'
# 本地环境接口地址 # 本地环境接口地址
# 如果没有跨域问题,直接在这里配置即可 # 如果没有跨域问题,直接在这里配置即可
# VITE_APP_BASE_API = 'http://192.168.1.116:8080' # VITE_APP_BASE_API = 'http://192.168.1.116:8080'
VITE_APP_BASE_API = 'http://121.41.36.72:8080' # VITE_APP_BASE_API = 'http://121.41.36.72:8080'
# VITE_APP_BASE_API = 'https://3lp9319797lh.vicp.fun' VITE_APP_BASE_API = 'http://www.cvlip.com'

View File

@ -1,5 +1,5 @@
import { PageRowsResult } from '@/types'; import { PageRowsResult } from '@/types';
import { ManifestPageType, ManifestType } from '@/types/manifest'; import { ManifestListType, ManifestPageType, ManifestType } from '@/types/manifest';
import http from '@/utils/request'; import http from '@/utils/request';
// api接口 // api接口
@ -7,6 +7,7 @@ const api = {
manifestDel: '/cargo/manifest/delete', // 删除 manifestDel: '/cargo/manifest/delete', // 删除
manifestGet: '/cargo/manifest/get', // 获取 manifestGet: '/cargo/manifest/get', // 获取
manifestPage: '/cargo/manifest/subscribe/page', // 我订阅的分页列表 manifestPage: '/cargo/manifest/subscribe/page', // 我订阅的分页列表
manifestList: '/cargo/manifest/subscribe/list', // 我订阅的非分页列表
manifestSave: '/cargo/manifest/save', // 保存 manifestSave: '/cargo/manifest/save', // 保存
manifestImport: '/cargo/manifest/import', // 舱单导入 manifestImport: '/cargo/manifest/import', // 舱单导入
manifestExport: '/cargo/manifest/tmp/export', // 下载模版 manifestExport: '/cargo/manifest/tmp/export', // 下载模版
@ -40,6 +41,15 @@ export function getManifestPageAPI(data: Partial<ManifestPageType>) {
return http.post<PageRowsResult<ManifestType>>(api.manifestPage, data); return http.post<PageRowsResult<ManifestType>>(api.manifestPage, data);
} }
/**
*
* @param {ManifestListType} data
* @return
* */
export function getManifestListAPI(data: ManifestListType) {
return http.postParams<ManifestType[]>(api.manifestList, data);
}
/** /**
* *
* @param {ManifestType} data * @param {ManifestType} data

View File

@ -5,6 +5,8 @@
} }
.el-table .el-table__header th { .el-table .el-table__header th {
background: #005478 !important; background: #005478 !important;
border-right: 1px solid #555 !important;
border-bottom: none !important;
} }
.el-table, .el-table,
.el-table__expanded-cell { .el-table__expanded-cell {

View File

@ -26,6 +26,7 @@ export interface BoatInfoType {
tradeType: string; tradeType: string;
loadPortId: number | string; loadPortId: number | string;
loadPort: PortType; loadPort: PortType;
dischargePort: PortType;
dischargePortId: number | string; dischargePortId: number | string;
ship: ShipType; ship: ShipType;
route: BoatRouteType; route: BoatRouteType;

View File

@ -51,6 +51,14 @@ export interface ManifestPageType extends PageRowsType {
subWharfId: number; subWharfId: number;
} }
/**
*
*/
export interface ManifestListType {
scheduleId: number | string;
desk?: number | string;
}
/** /**
* *
*/ */

View File

@ -0,0 +1,218 @@
<template>
<el-dialog v-model="dialogVisible" width="866px" style="padding: 0" :show-close="false">
<template #header>
<div class="header">船期信息详情</div>
</template>
<div class="content">
<div class="content-left">
<div class="item">
<div class="title">起运港</div>
<div class="text">{{ dialogProps.loadPort?.name }}</div>
</div>
<div class="item">
<div class="title">目的港:</div>
<div class="text">{{ dialogProps.dischargePort?.name }}</div>
</div>
<div class="item">
<div class="title">船名:</div>
<div class="text">{{ dialogProps.ship?.name }}</div>
</div>
<div class="item">
<div class="title">航次:</div>
<div class="text">{{ dialogProps.voyage }}</div>
</div>
<div class="item">
<div class="title">计划装载:</div>
<div class="text">{{ dialogProps.carNumPlan }}()</div>
</div>
<div class="item">
<div class="title">实际装载:</div>
<div class="text">{{ dialogProps.carNumActual }}()</div>
</div>
<div class="item">
<div class="title">计划离港时间:</div>
<div class="text">{{ dialogProps.departureDatePlan }}</div>
</div>
<div class="item">
<div class="title">实际离港时间:</div>
<div class="text">{{ dialogProps.departureDateActual }}</div>
</div>
<div class="item">
<div class="title">当前状态:</div>
<div class="text">{{ dialogProps.shipStatus }}</div>
</div>
</div>
<div class="content-right">
<div class="btn-img">查看船图</div>
<div class="btn-address">查看船位</div>
<div class="info">
<div class="info-item">
<div class="info-title">发布单位</div>
<div class="info-text">{{ userInfo.enterpriseName }}</div>
</div>
<div class="info-item">
<div class="info-title">发布人</div>
<div class="info-text">{{ userInfo.username }}</div>
</div>
<div class="info-item">
<div class="info-title">发布时间</div>
<div class="info-text">{{ dialogProps.createDate }}</div>
</div>
<div class="info-item">
<div class="info-title">更新时间</div>
<div class="info-text">{{ dialogProps.updateDate }}</div>
</div>
<div class="info-item">
<div class="info-title">联系电话</div>
<div class="info-text">暂无</div>
</div>
</div>
</div>
</div>
<template #footer>
<div class="footer">
<div class="btn" @click="dialogVisible = false">确定</div>
</div>
</template>
</el-dialog>
</template>
<script lang="ts" setup>
import { storeToRefs } from 'pinia';
import { ref } from 'vue';
import { useUserStore } from '@/store/modules/user';
import { BoatInfoType } from '@/types/boatInfo';
// dialog
const dialogVisible = ref(false);
//
const dialogProps = ref<Partial<BoatInfoType>>({});
// dialog/
const isShowDialog = (params: BoatInfoType) => {
dialogProps.value = params;
dialogVisible.value = true;
};
//
defineExpose({ isShowDialog });
//
const userState = useUserStore();
const { userInfo } = storeToRefs(userState);
</script>
<style lang="scss" scoped>
.header {
width: 100%;
height: 50px;
font-size: 18px;
line-height: 50px;
color: #fff;
text-align: center;
background-color: #015478;
}
.content {
box-sizing: border-box;
display: flex;
justify-content: space-between;
width: 100%;
padding: 30px 60px;
.content-left {
width: 319px;
height: 342px;
font-size: 21px;
font-weight: 400;
color: #333;
.item {
display: flex;
width: 100%;
line-height: 38px;
.title {
width: 147px;
}
.text {
flex: 1;
color: #027db4;
}
}
}
.content-right {
display: flex;
flex-direction: column;
justify-content: space-between;
width: 238px;
height: 342px;
// margin-left: 160px;
.btn-img {
width: 120px;
height: 40px;
font-size: 15px;
line-height: 40px;
color: #fff;
text-align: center;
background-color: rgb(0 128 128 / 100%);
border-radius: 5px;
}
.btn-address {
width: 120px;
height: 40px;
font-size: 15px;
line-height: 40px;
color: #fff;
text-align: center;
background-color: rgb(22 155 213 / 100%);
border-radius: 5px;
}
.info {
box-sizing: border-box;
width: 238px;
height: 180px;
padding: 15px 20px;
font-family: 'Arial Normal', Arial;
font-size: 15px;
font-style: normal;
font-weight: 400;
line-height: 30px;
color: #333;
background-color: rgb(242 242 242 / 100%);
border-radius: 7px;
.info-item {
display: flex;
width: 100%;
line-height: 30px;
.info-title {
width: 75px;
}
.info-text {
flex: 1;
color: #027db4;
}
}
}
}
}
.footer {
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
padding-bottom: 40px;
background-color: #fff;
.btn {
width: 170px;
height: 55px;
font-size: 18px;
line-height: 55px;
color: #fff;
text-align: center;
background-color: #027db4;
border-radius: 5px;
box-shadow: 5px 5px 5px rgb(0 0 0 / 34.9%);
}
}
</style>

View File

@ -10,6 +10,7 @@
max-height="400px" max-height="400px"
v-el-table-infinite-scroll="tableDataLoad" v-el-table-infinite-scroll="tableDataLoad"
:infinite-scroll-disabled="disabled" :infinite-scroll-disabled="disabled"
@row-click="onClickOpenDetail"
> >
<!-- <el-table-column prop="enterprise.name" label="企业" align="center" width="150" /> --> <!-- <el-table-column prop="enterprise.name" label="企业" align="center" width="150" /> -->
<el-table-column prop="ship.name" label="船名" align="center" width="150" /> <el-table-column prop="ship.name" label="船名" align="center" width="150" />
@ -41,13 +42,13 @@
/> />
<el-table-column prop="tradeType" label="贸易类型" align="center" width="150" /> <el-table-column prop="tradeType" label="贸易类型" align="center" width="150" />
<el-table-column prop="shipStatus" label="当前状态" align="center" width="150" /> <el-table-column prop="shipStatus" label="当前状态" align="center" width="150" />
<el-table-column prop="operator" label="操作" width="200px" align="center" fixed="right"> <!-- <el-table-column prop="operator" label="操作" width="200px" align="center" fixed="right">
<template #default="scope"> <template #default="scope">
<el-button type="primary" size="small" link @click="onClickOpenDetail(scope.row)"> <el-button type="primary" size="small" link @click="onClickOpenDetail(scope.row)">
查看 查看
</el-button> </el-button>
</template> </template>
</el-table-column> </el-table-column> -->
</el-table> </el-table>
</div> </div>
<!-- 分页 --> <!-- 分页 -->
@ -59,6 +60,8 @@
<div class="notice">仅列出最近十日收到的订阅船期信息</div> <div class="notice">仅列出最近十日收到的订阅船期信息</div>
</div> </div>
</div> </div>
<BoatDialog ref="boatDialogRef" />
</div> </div>
</template> </template>
@ -66,17 +69,16 @@
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { ElMessage, ElMessageBox } from 'element-plus'; import { ElMessage, ElMessageBox } from 'element-plus';
import { computed, ref } from 'vue'; import { computed, ref } from 'vue';
import { import { getSailScheduleExportAPI, getSailSchedulePageAPI } from '@/api/Boat/info';
getSailScheduleExportAPI,
getSailScheduleGetAPI,
getSailSchedulePageAPI,
} from '@/api/Boat/info';
import { BoatInfoType } from '@/types/boatInfo'; import { BoatInfoType } from '@/types/boatInfo';
import BoatDialog from './BoatDialog.vue';
const handleTableData = (data: BoatInfoType[]) => { const handleTableData = (data: BoatInfoType[]) => {
for (const item of data) { for (const item of data) {
item.departureDatePlan = dayjs(item.departureDatePlan).format('YYYY-MM-DD HH:mm'); item.departureDatePlan = dayjs(item.departureDatePlan).format('YYYY-MM-DD HH:mm');
item.departureDateActual = dayjs(item.departureDateActual).format('YYYY-MM-DD HH:mm'); item.departureDateActual = dayjs(item.departureDateActual).format('YYYY-MM-DD HH:mm');
item.createDate = dayjs(item.createDate).format('YYYY-MM-DD HH:mm');
item.updateDate = dayjs(item.updateDate).format('YYYY-MM-DD HH:mm');
} }
return data; return data;
}; };
@ -159,9 +161,9 @@ const onClickExport = () => {
}; };
// //
const boatDialogRef = ref<InstanceType<typeof BoatDialog> | null>(null);
const onClickOpenDetail = async (row: BoatInfoType) => { const onClickOpenDetail = async (row: BoatInfoType) => {
const { data } = await getSailScheduleGetAPI({ id: row.id }); boatDialogRef.value?.isShowDialog(row);
console.log('🚀 ~ file: BoatTable.vue:146 ~ onClickOpenDetail ~ data:', data);
}; };
</script> </script>

View File

@ -27,7 +27,7 @@
<div <div
class="deck-btn" class="deck-btn"
v-for="item in 12" v-for="item in 12"
:class="{ 'deck-btn-active': item === Number(searchTableForm.deck) }" :class="{ 'deck-btn-active': item === currentDesk }"
:key="item" :key="item"
@click="onClickOpenDeck(item)" @click="onClickOpenDeck(item)"
> >
@ -57,6 +57,7 @@
:data="tableState.tableData" :data="tableState.tableData"
style="width: 100%; height: 100%" style="width: 100%; height: 100%"
> >
<el-table-column type="index" label="No." width="50" />
<el-table-column prop="schedule.name" label="船期" align="center" width="120" /> <el-table-column prop="schedule.name" label="船期" align="center" width="120" />
<el-table-column prop="deck" label="舱层" align="center" width="80" /> <el-table-column prop="deck" label="舱层" align="center" width="80" />
<el-table-column prop="cabin" label="舱段" align="center" width="80" /> <el-table-column prop="cabin" label="舱段" align="center" width="80" />
@ -100,7 +101,7 @@
<svg-icon icon="Export" className="icon"></svg-icon> <svg-icon icon="Export" className="icon"></svg-icon>
舱单导出 舱单导出
</div> </div>
<div class="pagination"> <div class="pagination" v-if="currentDesk === 0">
<Pagination <Pagination
:pageAble="tableState.pageAble" :pageAble="tableState.pageAble"
:handle-size-change="handleSizeChange" :handle-size-change="handleSizeChange"
@ -117,7 +118,7 @@
import { ElMessage, ElMessageBox, FormInstance } from 'element-plus'; import { ElMessage, ElMessageBox, FormInstance } from 'element-plus';
import { onMounted, reactive, ref } from 'vue'; import { onMounted, reactive, ref } from 'vue';
import { postSaleShipListAPI } from '@/api/Boat/info'; import { postSaleShipListAPI } from '@/api/Boat/info';
import { getManifestFileExportAPI, getManifestPageAPI } from '@/api/Manifest'; import { getManifestFileExportAPI, getManifestListAPI, getManifestPageAPI } from '@/api/Manifest';
import Pagination from '@/components/Pagination/Pagination.vue'; import Pagination from '@/components/Pagination/Pagination.vue';
import RemoteSelect from '@/components/RemoteSelect/index.vue'; import RemoteSelect from '@/components/RemoteSelect/index.vue';
import { useTable } from '@/hooks/useTable'; import { useTable } from '@/hooks/useTable';
@ -149,7 +150,6 @@ const searchTableForm = reactive({
billNo: '', billNo: '',
brandId: '', brandId: '',
goodsStatus: '', goodsStatus: '',
deck: '',
}); });
// //
@ -169,9 +169,26 @@ const onClickSearch = async () => {
await searchTable(); await searchTable();
tableLoading.value = false; tableLoading.value = false;
}; };
const onClickOpenDeck = async (item: number | string) => {
searchTableForm.deck = item as string; //
await onClickSearch(); const currentDesk = ref(0);
//
const onClickOpenDeck = async (item: number) => {
// ID
if (searchTableForm.scheduleId) {
currentDesk.value = item;
const { data } = await getManifestListAPI({
scheduleId: searchTableForm.scheduleId,
desk: item,
});
tableState.value.tableData = data;
} else {
ElMessage({
type: 'warning',
message: '请先选择船舶!',
});
}
}; };
// //
@ -179,7 +196,7 @@ const onClickResetForm = async (formEl: FormInstance | undefined) => {
if (!formEl) return; if (!formEl) return;
await resetTable(); await resetTable();
formEl.resetFields(); formEl.resetFields();
searchTableForm.deck = ''; currentDesk.value = 0;
}; };
// //
@ -447,10 +464,6 @@ const handleCurrentChange = async (val: number) => {
.pagination { .pagination {
position: absolute; position: absolute;
left: 50%; left: 50%;
// width: 265px;
// height: 50px;
transform: translateX(-50%); transform: translateX(-50%);
} }
} }