| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836 |
- <template>
- <div class="pilot-plan-container">
- <h2>引航计划管理</h2>
-
- <!-- 查询条件 -->
- <div class="search-section">
- <h3>查询条件</h3>
- <el-form :model="searchForm" class="demo-form">
- <!-- 第一行(默认显示,3个控件 + 按钮) -->
- <div class="search-row" v-if="showAllSearch || row1Visible">
- <el-form-item label="作业时间">
- <el-date-picker
- v-model="searchForm.planTimeRange"
- type="daterange"
- range-separator="至"
- start-placeholder="开始日期"
- end-placeholder="结束日期"
- style="width: 240px"
- ></el-date-picker>
- </el-form-item>
- <el-form-item label="港区作业类型">
- <el-select
- v-model="searchForm.portAreaOperationType"
- placeholder="请选择"
- style="width: 180px"
- >
- <el-option label="全部" value=""></el-option>
- <el-option label="本港计划" value="本港计划"></el-option>
- <el-option label="外港计划" value="外港计划"></el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="港口">
- <el-select
- v-model="searchForm.portId"
- placeholder="请选择"
- style="width: 180px"
- clearable
- >
- <el-option
- v-for="port in portList"
- :key="port.portId"
- :label="port.portName"
- :value="port.portId">
- </el-option>
- </el-select>
- </el-form-item>
- <div class="search-actions">
- <el-button
- v-if="hasExtraRows"
- type="primary"
- @click="toggleSearchForm">
- {{ showAllSearch ? '收起' : '展开' }}
- </el-button>
- <el-button type="primary" @click="getPilotPlans" :loading="loading">查询</el-button>
- <el-button @click="resetSearchForm" :loading="loading">重置</el-button>
- </div>
- </div>
-
- <!-- 第二行(默认隐藏,3个控件) -->
- <div class="search-row" v-if="showAllSearch || row2Visible">
- <el-form-item label="英文船名">
- <el-input
- v-model="searchForm.englishShipName"
- placeholder="请输入英文船名"
- style="width: 180px"
- clearable
- ></el-input>
- </el-form-item>
- <el-form-item label="状态">
- <el-select
- v-model="searchForm.status"
- placeholder="请选择"
- style="width: 180px"
- >
- <el-option label="全部" value=""></el-option>
- <el-option label="未调度" value="未调度"></el-option>
- <el-option label="已调度" value="已调度"></el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="船公司">
- <el-select
- v-model="searchForm.shipownerId"
- placeholder="请选择"
- style="width: 180px"
- clearable
- filterable
- remote
- :remote-method="searchShipCompany"
- :loading="shipCompanyLoading"
- @visible-change="handleShipCompanyVisibleChange"
- @scroll="handleShipCompanyScroll"
- >
- <el-option
- v-for="company in shipCompanyList"
- :key="company.companyId"
- :label="company.companyName"
- :value="company.companyId">
- </el-option>
- </el-select>
- </el-form-item>
- </div>
-
- <!-- 第三行(默认隐藏,3个控件) -->
- <div class="search-row" v-if="showAllSearch || row3Visible">
- <el-form-item label="吃水">
- <div class="input-group">
- <el-input
- v-model="searchForm.deepStart"
- placeholder="最小值"
- style="width: 80px"
- type="number"
- ></el-input>
- <span style="padding: 0 5px">-</span>
- <el-input
- v-model="searchForm.deepEnd"
- placeholder="最大值"
- style="width: 80px"
- type="number"
- ></el-input>
- </div>
- </el-form-item>
- <el-form-item label="交通船">
- <el-input
- v-model="searchForm.trafficboat"
- placeholder="请输入交通船"
- style="width: 180px"
- clearable
- ></el-input>
- </el-form-item>
- </div>
- </el-form>
- </div>
-
- <!-- 操作按钮 -->
- <div class="action-section">
- <el-button type="primary" @click="openImportDialog" v-permission="'010401'">导入引航计划</el-button>
- <el-button type="success" @click="exportPilotPlans" v-permission="'010403'">导出Excel</el-button>
- </div>
-
- <!-- 列表展示 -->
- <div class="list-section">
- <h3>引航计划列表</h3>
- <el-table
- :data="pilotPlans"
- style="width: calc(100vw - 330px); height: calc(100vh - 469px);"
- border
- size="default"
- stripe
- :header-cell-style="{ background: '#f5f7fa', color: '#303133', fontWeight: 'bold' }"
- @sort-change="handleSortChange">
- <el-table-column type="index" label="序号" width="50" fixed align="center"></el-table-column>
- <el-table-column prop="planTime" label="计划时间" width="160" fixed align="center" sortable show-overflow-tooltip>
- <template #default="scope">
- {{ formatDateTime(scope.row.planTime) }}
- </template>
- </el-table-column>
- <el-table-column prop="chineseShipName" label="中文船名" min-width="120" sortable show-overflow-tooltip></el-table-column>
- <el-table-column prop="englishShipName" label="英文船名" min-width="120" sortable show-overflow-tooltip></el-table-column>
- <el-table-column prop="shipCompanyName" label="船公司" min-width="150" sortable show-overflow-tooltip></el-table-column>
- <el-table-column prop="nation" label="国籍" width="100" sortable align="center"></el-table-column>
- <el-table-column prop="shipLength" label="船长" width="80" sortable align="center"></el-table-column>
- <el-table-column prop="deep" label="吃水" width="80" sortable align="center"></el-table-column>
- <el-table-column prop="pilotTypeName" label="动态" width="100" sortable align="center"></el-table-column>
- <el-table-column prop="fromBerthName" label="起点泊位" min-width="100" sortable show-overflow-tooltip></el-table-column>
- <el-table-column prop="toBerthName" label="终点泊位" min-width="100" sortable show-overflow-tooltip></el-table-column>
- <el-table-column prop="mainPilotName" label="主引" width="80" sortable align="center" show-overflow-tooltip></el-table-column>
- <el-table-column prop="trafficboat" label="交通船" width="100" sortable show-overflow-tooltip></el-table-column>
- <el-table-column prop="agencyName" label="代理" min-width="150" sortable show-overflow-tooltip></el-table-column>
- <el-table-column prop="portAreaOperationType" label="港区作业类型" width="120" sortable align="center"></el-table-column>
- <el-table-column prop="waterwayName" label="航道" min-width="100" sortable show-overflow-tooltip></el-table-column>
- <el-table-column prop="status" label="状态" width="80" sortable align="center">
- <template #default="scope">
- <el-tag :type="scope.row.status === '已调度' ? 'success' : 'info'" size="small">
- {{ scope.row.status }}
- </el-tag>
- </template>
- </el-table-column>
- </el-table>
-
- <!-- 分页 -->
- <div class="pagination">
- <el-pagination
- @size-change="handleSizeChange"
- @current-change="handleCurrentChange"
- :current-page="currentPage"
- :page-sizes="[10, 20, 50, 100]"
- :page-size="pageSize"
- layout="total, sizes, prev, pager, next, jumper"
- :total="total"></el-pagination>
- </div>
- </div>
-
- <!-- 导入弹窗 -->
- <el-dialog
- title="导入引航计划"
- v-model="importDialogVisible"
- width="800px"
- >
- <textarea
- v-model="importData"
- placeholder="请粘贴引航计划数据,每行一条记录,字段间用制表符分隔"
- rows="10"
- style="width: 100%; padding: 10px; border: 1px solid #dcdfe6; border-radius: 4px; resize: vertical; font-size: 14px; line-height: 1.5;"
- ></textarea>
- <template #footer>
- <span class="dialog-footer">
- <el-button @click="importDialogVisible = false">取消</el-button>
- <el-button type="primary" @click="parseImportData">解析数据</el-button>
- </span>
- </template>
- </el-dialog>
-
- <!-- 预览弹窗 -->
- <el-dialog
- title="预览引航计划"
- v-model="previewDialogVisible"
- width="90%"
- top="5vh"
- class="preview-dialog"
- >
- <div class="preview-header">
- <span class="preview-count">预览 {{ previewData.length }} 条记录</span>
- <el-input
- v-model="previewSearch"
- placeholder="搜索..."
- size="small"
- style="width: 200px;"
- clearable
- />
- </div>
- <el-table
- :data="filteredPreviewData"
- style="width: 100%"
- height="60vh"
- stripe
- border
- :header-cell-style="{background: '#f5f7fa', color: '#606266'}"
- >
- <el-table-column prop="serialNumber" label="序号" width="60" fixed align="center"></el-table-column>
- <el-table-column label="计划时间" width="154" fixed align="center" sortable show-overflow-tooltip>
- <template #default="scope">
- {{ formatDateTime(scope.row.planTime) }}
- </template>
- </el-table-column>
- <el-table-column prop="chineseShipName" label="中文船名" width="150" sortable show-overflow-tooltip></el-table-column>
- <el-table-column prop="englishShipName" label="英文船名" width="150" sortable show-overflow-tooltip></el-table-column>
- <el-table-column prop="nationality" label="国籍" width="90" sortable align="center"></el-table-column>
- <el-table-column prop="shipLength" label="船长(m)" width="90" sortable align="center"></el-table-column>
- <el-table-column prop="draft" label="吃水(m)" width="90" sortable align="center"></el-table-column>
- <el-table-column prop="dynamic" label="动态" width="90" sortable align="center"></el-table-column>
- <el-table-column prop="startBerth" label="起点泊位" width="130" sortable show-overflow-tooltip></el-table-column>
- <el-table-column prop="endBerth" label="终点泊位" width="130" sortable show-overflow-tooltip></el-table-column>
- <el-table-column prop="cooperationMark" label="合作标记" width="100" sortable align="center"></el-table-column>
- <el-table-column prop="pilotAgency" label="引航机构" width="120" sortable show-overflow-tooltip></el-table-column>
- <el-table-column prop="mainPilot" label="主引" width="100" sortable align="center" show-overflow-tooltip></el-table-column>
- <el-table-column prop="secondaryPilot" label="主引2" width="100" sortable align="center" show-overflow-tooltip></el-table-column>
- <el-table-column prop="deputyPilot" label="副引" width="100" sortable align="center" show-overflow-tooltip></el-table-column>
- <el-table-column prop="otherPilots" label="其它引水" width="100" sortable align="center" show-overflow-tooltip></el-table-column>
- <el-table-column prop="agent" label="代理" width="120" sortable show-overflow-tooltip></el-table-column>
- <el-table-column prop="agentPhone" label="代理电话" width="130" sortable show-overflow-tooltip></el-table-column>
- <el-table-column prop="transportVessel" label="交通船" width="100" sortable show-overflow-tooltip></el-table-column>
- <el-table-column prop="waterway" label="航道" width="120" sortable show-overflow-tooltip></el-table-column>
- <el-table-column prop="thruster" label="侧推" width="200" sortable show-overflow-tooltip></el-table-column>
- <el-table-column prop="remarks" label="备注" width="150" sortable show-overflow-tooltip></el-table-column>
- </el-table>
- <template #footer>
- <span class="dialog-footer">
- <el-button @click="previewDialogVisible = false">取消</el-button>
- <el-button type="primary" @click="confirmImport" :disabled="!previewData.length">
- 确认导入 ({{ previewData.length }} 条)
- </el-button>
- </span>
- </template>
- </el-dialog>
- </div>
- </template>
- <script>
- import { parsePilotPlanData } from '@/utils/pilotPlanParser'
- export default {
- name: 'PilotPlan',
- data() {
- return {
- importData: '',
- importDialogVisible: false,
- previewDialogVisible: false,
- previewData: [],
- previewSearch: '',
- showAllSearch: false,
- searchForm: {
- planTimeRange: [],
- portAreaOperationType: '',
- portId: '',
- englishShipName: '',
- status: '',
- shipownerId: '',
- deepStart: null,
- deepEnd: null,
- trafficboat: ''
- },
- pilotPlans: [],
- portList: [],
- shipCompanyList: [],
- shipCompanyQuery: '',
- shipCompanyPage: 1,
- shipCompanyPageSize: 10,
- shipCompanyLoading: false,
- shipCompanyHasMore: true,
- currentPage: 1,
- pageSize: 20,
- total: 0,
- tableHeight: 600,
- loading: false,
- exportLoading: false,
- importLoading: false,
- sortMap: {},
- sortFieldMap: {
- planTime: 'planTime',
- chineseShipName: 'chineseShipName',
- englishShipName: 'englishShipName',
- shipCompanyName: 'shipCompanyName',
- nation: 'nation',
- shipLength: 'shipLength',
- deep: 'deep',
- pilotTypeName: 'pilotTypeName',
- fromBerthName: 'fromBerthName',
- toBerthName: 'toBerthName',
- mainPilotName: 'mainPilotName',
- trafficboat: 'trafficboat',
- agencyName: 'agencyName',
- portAreaOperationType: 'portAreaOperationType',
- waterwayName: 'waterwayName',
- status: 'status'
- }
- }
- },
- computed: {
- row1Visible() {
- return true;
- },
- row2Visible() {
- return this.showAllSearch;
- },
- row3Visible() {
- return this.showAllSearch;
- },
- hasExtraRows() {
- return true;
- },
- filteredPreviewData() {
- if (!this.previewSearch) {
- return this.previewData;
- }
-
- const searchLower = this.previewSearch.toLowerCase();
- return this.previewData.filter(item => {
- return (
- (item.serialNumber && item.serialNumber.toString().toLowerCase().includes(searchLower)) ||
- (item.planTime && item.planTime.toLowerCase().includes(searchLower)) ||
- (item.chineseShipName && item.chineseShipName.toLowerCase().includes(searchLower)) ||
- (item.englishShipName && item.englishShipName.toLowerCase().includes(searchLower)) ||
- (item.nationality && item.nationality.toLowerCase().includes(searchLower)) ||
- (item.startBerth && item.startBerth.toLowerCase().includes(searchLower)) ||
- (item.endBerth && item.endBerth.toLowerCase().includes(searchLower)) ||
- (item.agent && item.agent.toLowerCase().includes(searchLower)) ||
- (item.remarks && item.remarks.toLowerCase().includes(searchLower))
- );
- });
- }
- },
- mounted() {
- this.getPortList();
- this.getShipCompanyList();
- this.setDefaultTimeRange();
- this.getPilotPlans();
- this.$nextTick(() => {
- this.calculateTableHeight();
- window.addEventListener('resize', this.calculateTableHeight);
- });
- },
- beforeUnmount() {
- window.removeEventListener('resize', this.calculateTableHeight);
- },
- methods: {
- calculateTableHeight() {
- const container = document.querySelector('.pilot-plan-container');
- const searchSection = document.querySelector('.search-section');
- const actionSection = document.querySelector('.action-section');
- const listSection = document.querySelector('.list-section');
-
- if (container && searchSection && actionSection && listSection) {
- const containerRect = container.getBoundingClientRect();
- const searchRect = searchSection.getBoundingClientRect();
- const actionRect = actionSection.getBoundingClientRect();
- const listRect = listSection.getBoundingClientRect();
-
- const remainingHeight = containerRect.height - searchRect.height - actionRect.height - listRect.height;
-
- this.tableHeight = Math.max(remainingHeight, 400);
- }
- },
- getPortList() {
- this.$axios.get('/api/port/list')
- .then(response => {
- this.portList = response.data;
- })
- .catch(error => {
- console.error('获取港口列表失败:', error);
- });
- },
- getShipCompanyList() {
- this.getShipCompanyListByPage('', 1);
- },
- getShipCompanyListByPage(query, page) {
- this.shipCompanyLoading = true;
- this.$axios.get('/api/ship-company/list', {
- params: {
- companyName: query,
- page: page,
- pageSize: this.shipCompanyPageSize
- }
- })
- .then(response => {
- if (page === 1) {
- this.shipCompanyList = response.data.content || [];
- } else {
- this.shipCompanyList = [...this.shipCompanyList, ...(response.data.content || [])];
- }
- this.shipCompanyHasMore = response.data.content && response.data.content.length >= this.shipCompanyPageSize;
- })
- .catch(error => {
- console.error('获取船公司列表失败:', error);
- this.$message.error('获取船公司列表失败,请稍后重试');
- })
- .finally(() => {
- this.shipCompanyLoading = false;
- });
- },
- searchShipCompany(query) {
- this.shipCompanyQuery = query || '';
- this.shipCompanyPage = 1;
- this.getShipCompanyListByPage(this.shipCompanyQuery, this.shipCompanyPage);
- },
- handleShipCompanyVisibleChange(visible) {
- if (visible && !this.shipCompanyQuery) {
- this.shipCompanyPage = 1;
- this.getShipCompanyListByPage('', this.shipCompanyPage);
- }
- },
- handleShipCompanyScroll() {
- if (this.shipCompanyHasMore && !this.shipCompanyLoading) {
- this.shipCompanyPage++;
- this.getShipCompanyListByPage(this.shipCompanyQuery, this.shipCompanyPage);
- }
- },
- getPilotPlans() {
- if (this.loading) return;
-
- this.loading = true;
-
- const planTimeStart = this.searchForm.planTimeRange && this.searchForm.planTimeRange.length > 0
- ? this.formatDate(this.searchForm.planTimeRange[0])
- : '';
- const planTimeEnd = this.searchForm.planTimeRange && this.searchForm.planTimeRange.length > 1
- ? this.formatDate(this.searchForm.planTimeRange[1])
- : '';
-
- const params = {
- planTimeStart: planTimeStart,
- planTimeEnd: planTimeEnd,
- portAreaOperationType: this.searchForm.portAreaOperationType,
- portId: this.searchForm.portId,
- englishShipName: this.searchForm.englishShipName,
- status: this.searchForm.status,
- shipownerId: this.searchForm.shipownerId,
- deepStart: this.searchForm.deepStart,
- deepEnd: this.searchForm.deepEnd,
- trafficboat: this.searchForm.trafficboat,
- page: this.currentPage,
- pageSize: this.pageSize,
- sortBy: this.sortMap.sortBy,
- sortOrder: this.sortMap.sortOrder
- };
-
- this.$axios.get('/api/pilot-plan/list', { params })
- .then(response => {
- this.pilotPlans = response.data.content;
- this.total = response.data.totalElements;
- })
- .catch(error => {
- console.error('获取引航计划失败:', error);
- this.$message.error('获取引航计划失败,请稍后重试');
- })
- .finally(() => {
- this.loading = false;
- });
- },
-
- handleSortChange({ prop, order }) {
- if (prop) {
- const sortBy = this.sortFieldMap[prop] || prop;
- this.sortMap = {
- sortBy: sortBy,
- sortOrder: order === 'ascending' ? 'ASC' : (order === 'descending' ? 'DESC' : null)
- };
- } else {
- this.sortMap = {};
- }
- this.getPilotPlans();
- },
-
- openImportDialog() {
- this.importData = '';
- this.importDialogVisible = true;
- },
-
- parseImportData() {
- if (!this.importData) {
- this.$message.warning('请粘贴引航计划数据');
- return;
- }
-
- try {
- this.previewData = parsePilotPlanData(this.importData);
-
- if (this.previewData.length === 0) {
- this.$message.warning('未解析到有效的引航计划数据,请检查数据格式');
- return;
- }
-
- this.importDialogVisible = false;
- this.previewDialogVisible = true;
- } catch (error) {
- console.error('解析引航计划失败:', error);
- this.$message.error('解析引航计划失败,请稍后重试');
- }
- },
-
- confirmImport() {
- if (this.importLoading) return;
-
- this.importLoading = true;
-
- this.$axios.post('/api/pilot-plan/import', this.previewData)
- .then(response => {
- if (response.data.success) {
- this.$message.success(`导入成功,共导入 ${response.data.importedCount} 条记录`);
- this.importData = '';
- this.previewData = [];
- this.previewDialogVisible = false;
- this.getPilotPlans();
- } else {
- this.$message.error(response.data.message);
- }
- })
- .catch(error => {
- console.error('导入引航计划失败:', error);
- this.$message.error('导入引航计划失败,请稍后重试');
- })
- .finally(() => {
- this.importLoading = false;
- });
- },
-
- async exportPilotPlans() {
- if (this.exportLoading) return;
-
- this.exportLoading = true;
-
- try {
- const planTimeStart = this.searchForm.planTimeRange && this.searchForm.planTimeRange.length > 0
- ? this.formatDate(this.searchForm.planTimeRange[0])
- : '';
- const planTimeEnd = this.searchForm.planTimeRange && this.searchForm.planTimeRange.length > 1
- ? this.formatDate(this.searchForm.planTimeRange[1])
- : '';
-
- const params = {
- planTimeStart: planTimeStart,
- planTimeEnd: planTimeEnd,
- portAreaOperationType: this.searchForm.portAreaOperationType,
- portId: this.searchForm.portId,
- englishShipName: this.searchForm.englishShipName,
- status: this.searchForm.status,
- shipownerId: this.searchForm.shipownerId,
- deepStart: this.searchForm.deepStart,
- deepEnd: this.searchForm.deepEnd,
- trafficboat: this.searchForm.trafficboat
- };
-
- const response = await this.$axios({
- method: 'get',
- url: '/api/pilot-plan/export',
- params: params,
- responseType: 'blob'
- });
-
- // 创建Blob对象
- const blob = new Blob([response.data], {
- type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8'
- });
-
- // 创建下载链接
- const downloadUrl = window.URL.createObjectURL(blob);
- const link = document.createElement('a');
- link.href = downloadUrl;
-
- // 获取文件名,从响应头中提取
- const contentDisposition = response.headers['content-disposition'];
- let filename = '引航计划数据.xlsx';
- if (contentDisposition) {
- const filenameMatch = contentDisposition.match(/filename="(.+)"/);
- if (filenameMatch) {
- filename = filenameMatch[1];
- }
- }
-
- link.download = filename;
- document.body.appendChild(link);
- link.click();
- document.body.removeChild(link);
- window.URL.revokeObjectURL(downloadUrl);
-
- this.$message.success('Excel文件导出成功');
- } catch (error) {
- console.error('导出失败:', error);
- this.$message.error('导出失败,请稍后重试');
- } finally {
- this.exportLoading = false;
- }
- },
-
- resetSearchForm() {
- this.searchForm = {
- planTimeRange: [],
- portAreaOperationType: '',
- portId: '',
- englishShipName: '',
- status: '',
- shipownerId: '',
- deepStart: null,
- deepEnd: null,
- trafficboat: ''
- };
- },
-
- toggleSearchForm() {
- this.showAllSearch = !this.showAllSearch;
- },
-
- handleSizeChange(val) {
- this.pageSize = val;
- this.getPilotPlans();
- },
-
- handleCurrentChange(val) {
- this.currentPage = val;
- this.getPilotPlans();
- },
-
- formatDate(date) {
- if (!date) return '';
- const year = date.getFullYear();
- const month = String(date.getMonth() + 1).padStart(2, '0');
- const day = String(date.getDate()).padStart(2, '0');
- return `${year}-${month}-${day}`;
- },
-
- setDefaultTimeRange() {
- const now = new Date();
- const firstDay = new Date(now.getFullYear(), now.getMonth(), 1);
- const lastDay = new Date(now.getFullYear(), now.getMonth() + 1, 0);
-
- // 设置时间为当天的开始和结束时间
- firstDay.setHours(0, 0, 0, 0);
- lastDay.setHours(23, 59, 59, 999);
-
- this.searchForm.planTimeRange = [firstDay, lastDay];
- },
-
- formatDateTime(date) {
- if (!date) return '';
- if (typeof date === 'string') {
- // 如果是字符串格式的日期,尝试解析
- const parsedDate = new Date(date);
- if (!isNaN(parsedDate.getTime())) {
- const year = parsedDate.getFullYear();
- const month = String(parsedDate.getMonth() + 1).padStart(2, '0');
- const day = String(parsedDate.getDate()).padStart(2, '0');
- const hours = String(parsedDate.getHours()).padStart(2, '0');
- const minutes = String(parsedDate.getMinutes()).padStart(2, '0');
- return `${year}-${month}-${day} ${hours}:${minutes}`;
- }
- return date;
- }
- const year = date.getFullYear();
- const month = String(date.getMonth() + 1).padStart(2, '0');
- const day = String(date.getDate()).padStart(2, '0');
- const hours = String(date.getHours()).padStart(2, '0');
- const minutes = String(date.getMinutes()).padStart(2, '0');
- return `${year}-${month}-${day} ${hours}:${minutes}`;
- }
- }
- }
- </script>
- <style scoped>
- .pilot-plan-container {
- width: 100%;
- min-height: calc(100vh - 64px);
- padding: 15px;
- background-color: #f5f7fa;
- box-sizing: border-box;
- }
- .search-section {
- background-color: white;
- padding: 15px;
- margin-bottom: 15px;
- border-radius: 4px;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
- box-sizing: border-box;
- }
- .action-section {
- margin-bottom: 15px;
- }
- .list-section {
- background-color: white;
- padding: 15px;
- margin-bottom: 15px;
- border-radius: 4px;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
- box-sizing: border-box;
- }
- .pagination {
- margin-top: 15px;
- text-align: right;
- }
- h2 {
- color: #303133;
- margin-bottom: 15px;
- font-size: 18px;
- }
- h3 {
- color: #606266;
- margin-bottom: 12px;
- font-size: 15px;
- }
- .preview-dialog {
- --el-dialog-margin-top: 5vh;
- }
- .preview-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 12px;
- }
- .preview-count {
- font-weight: bold;
- color: #606266;
- font-size: 13px;
- }
- .preview-footer {
- display: flex;
- justify-content: space-between;
- padding-top: 12px;
- border-top: 1px solid #ebeef5;
- margin-top: 12px;
- }
- .table-container {
- width: 100%;
- overflow-x: auto;
- }
- /* 查询条件样式 */
- .demo-form {
- display: flex;
- flex-direction: column;
- gap: 12px;
- }
- .search-row {
- display: flex;
- flex-wrap: wrap;
- gap: 12px;
- align-items: center;
- }
- .search-actions {
- display: flex;
- gap: 8px;
- align-items: center;
- }
- /* 表格样式优化 */
- :deep(.el-table) {
- font-size: 12px;
- }
- :deep(.el-table th.el-table__cell) {
- background-color: #f5f7fa;
- color: #303133;
- font-weight: 600;
- }
- :deep(.el-table .el-table__cell) {
- padding: 6px 0 !important;
- }
- /* 内容截断样式 */
- :deep(.el-table .cell) {
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- }
- /* 表头排序箭头样式 */
- :deep(.el-table .el-table__header th.el-table__cell > .el-table__cell.sortable) {
- cursor: pointer;
- }
- :deep(.el-table .el-table__header th.el-table__cell > .el-table__cell.sortable:hover) {
- background-color: #e6e6e6;
- }
- </style>
|