Toggle navigation
Toggle navigation
This project
Loading...
Sign in
Fedex
/
EcomWeb
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Snippets
Network
Create a new issue
Builds
Commits
Issue Boards
Authored by
zhanbo.xu
2026-03-06 19:01:51 +0800
Browse Files
Options
Browse Files
Download
Plain Diff
Commit
81716abf0c9a53030a29ab5824e9f7dcdb7b4b5e
81716abf
2 parents
fc420843
c70bceb0
Merge branch 'release-pdd-cache-v1.0.10' into release-pdd-cache-v1.0.11
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
530 additions
and
44 deletions
src/api/declareData-api.js
src/api/exportList-api.js
src/permission.js
src/store/modules/user.js
src/utils/request.js
src/utils/zipdownload.js
src/views/editReportingData/index.vue
src/views/exportListQuery/index.vue
src/views/reportingData/batchModify.vue
src/views/reportingData/index.vue
src/api/declareData-api.js
View file @
81716ab
...
...
@@ -328,3 +328,29 @@ export function getOperationLogByBillNo(data) {
data
:
data
,
});
}
// 查询导出的任务ID
// POST
// /exportList/submitExportTask
export
function
getSubmitExportTask
(
data
)
{
return
request
({
url
:
"/bus-customer/declareData/submitExportTask"
,
method
:
"post"
,
data
:
data
,
});
}
// /asyncExport/taskStatus/{taskId}
export
function
getTaskStatus
(
data
)
{
return
request
({
url
:
"/bus-customer/asyncExport/taskStatus/"
+
data
.
taskId
,
method
:
"get"
,
});
}
// /asyncExport/download/{taskId}
export
function
getDownload
(
data
)
{
return
request
({
url
:
"/bus-customer/asyncExport/download/"
+
data
.
taskId
,
method
:
"get"
,
});
}
...
...
src/api/exportList-api.js
View file @
81716ab
...
...
@@ -64,3 +64,29 @@ export function getCustomizeExcel(data) {
data
:
data
,
});
}
// 查询导出的任务ID
// POST
// /exportList/submitExportTask
export
function
getSubmitExportTask
(
data
)
{
return
request
({
url
:
"/bus-customer/exportList/submitExportTask"
,
method
:
"post"
,
data
:
data
,
});
}
// /asyncExport/taskStatus/{taskId}
export
function
getTaskStatus
(
data
)
{
return
request
({
url
:
"/bus-customer/asyncExport/taskStatus/"
+
data
.
taskId
,
method
:
"get"
,
});
}
// /asyncExport/download/{taskId}
export
function
getDownload
(
data
)
{
return
request
({
url
:
"/bus-customer/asyncExport/download/"
+
data
.
taskId
,
method
:
"get"
,
});
}
...
...
src/permission.js
View file @
81716ab
...
...
@@ -51,6 +51,7 @@ router.beforeEach((to, from, next) => {
"RETURN_STATUS"
,
"FORWARD_STATUS"
,
"DATA_SOURCE_IMPORT"
,
"DECLARE_TRAFMODE"
,
]);
// 根据roles权限生成可访问的路由表
router
.
addRoutes
(
accessRoutes
);
// 动态添加可访问路由表
...
...
src/store/modules/user.js
View file @
81716ab
...
...
@@ -20,13 +20,13 @@ const user = {
permissions
:
[],
linkList
:
[],
dict
:
{
DECLARE_TRAFMODE
:
[
{
itemCode
:
"DECLARE_TRAFMODE_AVIATION"
,
itemChineseName
:
"航空运输"
,
itemValue
:
"5"
,
},
],
//
DECLARE_TRAFMODE: [
//
{
//
itemCode: "DECLARE_TRAFMODE_AVIATION",
//
itemChineseName: "航空运输",
//
itemValue: "5",
//
},
//
],
},
loading
:
{
type
:
false
,
...
...
src/utils/request.js
View file @
81716ab
This diff is collapsed. Click to expand it.
src/utils/zipdownload.js
View file @
81716ab
...
...
@@ -20,6 +20,8 @@ const apiUrl = {
declareDataModel
:
"/bus-customer/declareData/downloadTemplate"
,
// 清单查询下载
listExport
:
"/bus-customer/exportList/listExport"
,
// 根据id导出
customDownloadXls
:
"/bus-customer/asyncExport/download"
,
};
const
baseUrl
=
process
.
env
.
VUE_APP_BASE_API
;
...
...
@@ -31,6 +33,8 @@ export function downLoadZip(urlStatus, str, filename, type, method, data) {
url
=
baseUrl
+
apiUrl
[
str
];
}
else
if
(
urlStatus
==
"res"
)
{
url
=
str
;
}
else
if
(
urlStatus
==
"task"
)
{
url
=
baseUrl
+
apiUrl
[
str
]
+
"/"
+
data
.
taskId
;
}
console
.
log
(
url
);
...
...
@@ -65,6 +69,7 @@ export function downLoadZip(urlStatus, str, filename, type, method, data) {
},
})
.
then
((
res
)
=>
{
console
.
log
(
res
);
if
(
filename
==
null
)
{
if
(
res
.
headers
[
"content-disposition"
])
{
var
patt
=
new
RegExp
(
"filename=([^;]+\\.[^\\.;]+);*"
);
...
...
@@ -80,8 +85,9 @@ export function downLoadZip(urlStatus, str, filename, type, method, data) {
resolveBlob
(
res
,
mimeMap
[
type
],
filename
);
resolve
();
})
.
catch
(()
=>
{
reject
();
.
catch
((
err
)
=>
{
debugger
;
reject
(
err
);
});
});
}
...
...
src/views/editReportingData/index.vue
View file @
81716ab
...
...
@@ -244,7 +244,7 @@
</el-row>
<el-row :gutter="5">
<!-- 申报状态 -->
<el-col :span="
6
">
<el-col :span="
3
">
<Formitem label="主要货物信息" prop="mainGoodsInfo">
<el-input
type="text"
...
...
@@ -272,9 +272,55 @@
></el-input>
</Formitem>
</el-col>
<!-- 申报日期 -->
<!-- 出口口岸 -->
<el-col :span="3">
<Formitem label="出口口岸" prop="exportPortCode">
<el-input
type="text"
class="inputShadow"
id="inputInner--exportPortCode"
resize="none"
v-model="formData.exportPortCode"
clearable
placeholder=""
></el-input>
</Formitem>
</el-col>
<!-- 运输方式 -->
<el-col :span="3">
<Formitem label="运输方式" prop="transportMode">
<el-select
type="text"
id="inputInner--transportMode"
v-model="formData.transportMode"
clearable
placeholder=""
>
<el-option
v-for="(item, index) in $store.getters.dict.DECLARE_TRAFMODE"
:key="index"
:label="item.itemChineseName"
:value="item.itemValue"
></el-option>
</el-select>
</Formitem>
</el-col>
<!-- 运输工具名称 -->
<el-col :span="3">
<Formitem label="运输工具名称" prop="transportVehicleName">
<el-input
type="text"
class="inputShadow"
id="inputInner--transportVehicleName"
resize="none"
v-model="formData.transportVehicleName"
clearable
placeholder=""
></el-input>
</Formitem>
</el-col>
<el-col :span="3">
<Formitem label="航班号" prop="flightNumber">
<Formitem label="航班
航次
号" prop="flightNumber">
<el-input
type="text"
class="inputShadow"
...
...
@@ -313,6 +359,8 @@
></el-input>
</Formitem>
</el-col>
</el-row>
<el-row :gutter="5">
<el-col :span="3">
<Formitem label="监管场所代码" prop="regulatoryVenueCode">
<el-input
...
...
@@ -339,8 +387,6 @@
></el-input>
</Formitem>
</el-col>
</el-row>
<el-row :gutter="5">
<el-col :span="3">
<Formitem label="运抵国(地区)" prop="destinationCountryRegion">
<el-select
...
...
@@ -445,6 +491,8 @@
></el-input>
</Formitem>
</el-col>
</el-row>
<el-row :gutter="5">
<el-col :span="3">
<Formitem label="保费币制" prop="insuredfeeCurrency">
<el-select
...
...
@@ -482,8 +530,6 @@
</el-select>
</Formitem>
</el-col>
</el-row>
<el-row :gutter="5">
<el-col :span="3">
<Formitem label="包装种类代码" prop="packageTypeCode">
<el-select
...
...
src/views/exportListQuery/index.vue
View file @
81716ab
...
...
@@ -215,6 +215,7 @@
size="small"
icon="el-icon-download"
@click="downloadData"
:loading="isPolling || exportLoading"
>
导出
</el-button>
...
...
@@ -282,9 +283,16 @@
</template>
<script>
import { getAllexportList, getListReceiptData } from "@/api/exportList-api.js";
import {
getAllexportList,
getListReceiptData,
getSubmitExportTask,
getTaskStatus,
} from "@/api/exportList-api.js";
import CustomDialog from "./custom-dialog.vue";
import { formatDateNew } from "../../utils";
import axios from "axios";
import { getToken } from "@/utils/auth";
export default {
name: "ExportListQuery",
...
...
@@ -415,6 +423,12 @@ export default {
formItemconsignmentHeadCode: false,
},
tableMaxheight: null,
exportLoading: false,
pollTimer: null, // 定时器实例
pollInterval: 5000, // 轮询间隔(5秒)
isPolling: false, // 轮询状态标识
currentTaskId: null,
pollCount: 0,
};
},
created() {
...
...
@@ -423,9 +437,13 @@ export default {
mounted() {
this.tableMaxheight = window.innerHeight - 360;
},
beforeDestroy() {
this.stopPolling(); // 组件销毁前清理定时器
},
watch: {
$route() {
this.popoverClose();
this.stopPolling(); // 组件销毁前清理定时器
},
},
methods: {
...
...
@@ -496,6 +514,139 @@ export default {
summaryApplicationStatus: "",
};
},
downLoadZip(retryCount = 0) {
const baseUrl = process.env.VUE_APP_BASE_API;
console.log(this.currentTaskId);
axios({
method: "get",
url: `${baseUrl}/bus-customer/asyncExport/download/${this.currentTaskId}`,
responseType: "blob",
headers: {
Authorization: "Bearer " + getToken(),
Ver: process.env.VUE_APP_APIVERSION,
},
})
.then((res) => {
debugger;
console.log(res);
const mimeType =
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
const aLink = document.createElement("a");
var blob = new Blob([res.data], { type: mimeType });
if (blob.size < 500) {
var reader = new FileReader();
reader.readAsText(blob, "utf-8");
reader.onloadend = () => {
// 获取文本内容并将其转换为JSON格式
if (
reader.result &&
reader.result != null &&
reader.result != ""
) {
if (JSON.parse(reader.result)) {
debugger;
let jsonData = JSON.parse(reader.result);
if (jsonData.code == "10103") {
// 检查重试次数
if (retryCount < 50) {
// 延迟后重试
setTimeout(() => {
this.downLoadZip(retryCount + 1);
}, 5000); // 5秒后重试
} else {
this.alertWarningMsg("导出失败");
this.exportLoading = false;
}
return;
}
this.alertWarningMsg(jsonData.message);
} else {
this.alertWarningMsg("文件无法下载,请重新生成后再试!");
}
} else {
this.alertWarningMsg("文件无法下载,请重新生成后再试!");
}
};
} else {
const fileName = `${formatDateNew(new Date())}.xlsx`;
aLink.href = URL.createObjectURL(blob);
aLink.setAttribute("download", fileName); // 设置下载文件名称
document.body.appendChild(aLink);
aLink.click();
document.body.removeChild(aLink);
this.exportLoading = false;
}
})
.catch((error) => {
console.log("失败", error);
this.exportLoading = false;
});
},
// 查询成功后调用的其他接口
async callOtherApi() {
try {
this.downLoadZip();
// const fileName = `${formatDateNew(new Date())}.xlsx`;
// this.fileDownload
// .downLoadZip("task", "customDownloadXls", fileName, "xlsx", "get", {
// taskId: this.currentTaskId,
// })
// .finally(() => {
// // this.cancelDownload();
// this.exportLoading = false;
// });
} catch (error) {
console.error("后续接口调用失败:", error);
}
},
// 轮询查询状态
async pollStatus() {
try {
const result = await getTaskStatus({ taskId: this.currentTaskId });
if (+result.code === 200) {
// PENDING, PROCESSING, COMPLETED, FAILED
if (result.data.status === "COMPLETED") {
this.stopPolling(); // 停止轮询
await this.callOtherApi(); // 调用其他接口
} else if (result.data.status === "FAILED") {
this.stopPolling();
this.handleFailure();
this.alertWarningMsg(result.data.errorMessage);
} else {
this.startPolling(); // 启动轮询
}
} else {
this.stopPolling();
this.handleFailure();
}
// 其他状态继续轮询
} catch (error) {
console.error("轮询查询失败:", error);
this.stopPolling();
}
},
// 启动轮询
startPolling() {
if (this.isPolling) return;
this.isPolling = true;
this.pollTimer = setInterval(() => {
this.pollStatus();
}, this.pollInterval);
},
// 停止轮询
stopPolling() {
if (this.pollTimer) {
clearInterval(this.pollTimer);
this.pollTimer = null;
}
this.isPolling = false;
this.exportLoading = false;
},
//导出
downloadData() {
let obj = { ...this.sreachFormData };
...
...
@@ -527,13 +678,32 @@ export default {
// // 2. 清单查询
// console.log(res);
// });
const fileName = `${formatDateNew(new Date())}.xlsx`;
this.fileDownload
.downLoadZip("api", "listExport", fileName, "xlsx", "post", {
...obj,
this.exportLoading = true;
this.$confirm(`正在导出中,请稍候!`, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
getSubmitExportTask(obj).then((res) => {
if (+res.code === 200) {
console.log(res);
this.currentTaskId = res.data;
this.startPolling();
}
});
// this.fileDownload
// .downLoadZip("api", "listExport", fileName, "xlsx", "post", {
// ...obj,
// })
// .finally(() => {
// // this.cancelDownload();
// this.exportLoading = false;
// });
})
.
finally
(() => {
this.
cancelDownload()
;
.
catch
(() => {
this.
exportLoading = false
;
});
},
//查询详情
...
...
src/views/reportingData/batchModify.vue
View file @
81716ab
...
...
@@ -31,7 +31,11 @@
></el-option>
</el-select>
</Formitem>
<Formitem label="修改内容" prop="modifyContent">
<Formitem
label="修改内容"
prop="modifyContent"
v-if="batchModifyFormData.modifyData !== 'TRANSPORT_MODE'"
>
<el-input
type="text"
class="inputShadow"
...
...
@@ -41,6 +45,24 @@
placeholder="请输入修改内容"
></el-input>
</Formitem>
<!-- -->
<Formitem label="运输方式" prop="modifyContent" v-else>
<el-select
type="text"
id="inputInner--modifyContent"
v-model="batchModifyFormData.modifyContent"
clearable
placeholder="请选择运输方式"
>
<el-option
v-for="(item, index) in $store.getters.dict.DECLARE_TRAFMODE"
:key="index"
:label="item.itemChineseName"
:value="item.itemValue"
></el-option>
</el-select>
</Formitem>
<!-- -->
</el-form>
</div>
<div class="dialogOption entrySave revokeOperation">
...
...
@@ -81,7 +103,11 @@ export default {
{ required: true, message: "请选择修改数据", trigger: "change" },
],
modifyContent: [
{ required: true, message: "请输入修改内容", trigger: "blur" },
{
required: true,
message: "请输入修改内容",
trigger: "blur",
},
],
},
modifyDataList: [
...
...
@@ -90,6 +116,7 @@ export default {
],
};
},
watch: {
showDialog(val) {
if (val) {
...
...
@@ -98,6 +125,16 @@ export default {
this.batchModifyFormData.modifyContent = "";
}
},
"batchModifyFormData.modifyData"(newVal, oldVal) {
this.$set(this.batchModifyFormRules, "modifyContent", [
{
required: true,
message:
newVal !== "TRANSPORT_MODE" ? "请输入修改内容" : "请选择运输方式",
trigger: "blur",
},
]);
},
},
created() {
this.getModifyDataList();
...
...
src/views/reportingData/index.vue
View file @
81716ab
...
...
@@ -252,7 +252,7 @@
class="entrySaveButton"
size="small"
icon="el-icon-download"
v-loading="loadings.exportDeclareLoading"
v-loading="
isPolling ||
loadings.exportDeclareLoading"
@click="downloadData"
>
导出
...
...
@@ -466,14 +466,35 @@
</el-tooltip>
</template>
</vxe-column>
<vxe-column field="flightNumber" title="航班号" width="80"></vxe-column>
<vxe-column
field="flightNumber"
title="航班航次号"
width="110"
></vxe-column>
<vxe-column
field="exportPortCode"
title="出口口岸"
width="110"
></vxe-column>
<vxe-column
field="transportModeName"
title="运输方式"
width="110"
></vxe-column>
<vxe-column
field="transportVehicleName"
title="运输工具名称"
width="110"
></vxe-column>
<vxe-column
field="regulatoryVenueCode"
title="监管场所代码"
width="110"
></vxe-column>
<vxe-column
field="ecomEntName"
title="电商企业名称"
width="110"
:show-overflow="true"
>
<template #default="{ row }">
...
...
@@ -492,7 +513,11 @@
title="申报业务类型"
width="100"
></vxe-column>
<vxe-column field="createTime" title="创建时间"></vxe-column>
<vxe-column
field="createTime"
title="创建时间"
width="150"
></vxe-column>
<vxe-column
field="orderReceiptStatus"
title="订单回执"
...
...
@@ -921,7 +946,8 @@ import {
getLogisticsReceipt,
getDeclarationLog,
arrivalInReceipt,
exportDeclareData,
getSubmitExportTask,
getTaskStatus,
} from "@/api/declareData-api.js";
import DialogVue from "./dialog.vue";
import RevokeDialog from "./revokeDialog.vue";
...
...
@@ -933,6 +959,9 @@ import DataPreview from "./data-preview.vue";
import WeightAdjust from "./weight-adjust.vue";
import { getCurrUserPortInfo } from "@/api/system/user.js";
import { listStatus, receiptStatus, totalScoreStatus } from "../../utils/dict";
import axios from "axios";
import { getToken } from "@/utils/auth";
import { formatDateNew } from "../../utils";
export default {
name: "ReportingData",
components: {
...
...
@@ -1045,6 +1074,12 @@ export default {
declareId: "",
data: {},
},
//
pollTimer: null, // 定时器实例
pollInterval: 5000, // 轮询间隔(5秒)
isPolling: false, // 轮询状态标识
currentTaskId: null,
pollCount: 0,
};
},
beforeCreate() {},
...
...
@@ -1074,6 +1109,8 @@ export default {
watch: {
$route(val, oldval) {
this.popoverClose();
this.popoverClose();
this.stopPolling(); // 组件销毁前清理定时器
},
},
beforeRouteEnter(to, from, next) {
...
...
@@ -1298,6 +1335,121 @@ export default {
console.log(err);
});
},
callOtherApi(retryCount = 0) {
const baseUrl = process.env.VUE_APP_BASE_API;
console.log(this.currentTaskId);
axios({
method: "get",
url: `${baseUrl}/bus-customer/asyncExport/download/${this.currentTaskId}`,
responseType: "blob",
headers: {
Authorization: "Bearer " + getToken(),
Ver: process.env.VUE_APP_APIVERSION,
},
})
.then((res) => {
debugger;
console.log(res);
const mimeType =
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
const aLink = document.createElement("a");
var blob = new Blob([res.data], { type: mimeType });
if (blob.size < 500) {
var reader = new FileReader();
reader.readAsText(blob, "utf-8");
reader.onloadend = () => {
// 获取文本内容并将其转换为JSON格式
if (
reader.result &&
reader.result != null &&
reader.result != ""
) {
if (JSON.parse(reader.result)) {
debugger;
let jsonData = JSON.parse(reader.result);
if (jsonData.code == "10103") {
// 检查重试次数
if (retryCount < 50) {
// 延迟后重试
setTimeout(() => {
this.callOtherApi(retryCount + 1);
}, 5000); // 5秒后重试
} else {
this.alertWarningMsg("导出失败");
this.loadings.exportDeclareLoading = false;
}
return;
}
this.alertWarningMsg(jsonData.message);
} else {
this.alertWarningMsg("文件无法下载,请重新生成后再试!");
}
} else {
this.alertWarningMsg("文件无法下载,请重新生成后再试!");
}
};
} else {
const fileName = `${formatDateNew(new Date())}.xlsx`;
aLink.href = URL.createObjectURL(blob);
aLink.setAttribute("download", fileName); // 设置下载文件名称
document.body.appendChild(aLink);
aLink.click();
document.body.removeChild(aLink);
this.loadings.exportDeclareLoading = false;
}
})
.catch((error) => {
console.log("失败", error);
this.loadings.exportDeclareLoading = false;
});
},
// 轮询查询状态
async pollStatus() {
try {
const result = await getTaskStatus({ taskId: this.currentTaskId });
if (+result.code === 200) {
// PENDING, PROCESSING, COMPLETED, FAILED
if (result.data.status === "COMPLETED") {
this.stopPolling(); // 停止轮询
await this.callOtherApi(); // 调用其他接口
} else if (result.data.status === "FAILED") {
this.stopPolling();
// this.handleFailure();
this.alertWarningMsg(result.data.errorMessage);
} else {
this.startPolling(); // 启动轮询
}
} else {
this.stopPolling();
// this.handleFailure();
}
// 其他状态继续轮询
} catch (error) {
console.error("轮询查询失败:", error);
this.stopPolling();
}
},
// 启动轮询
startPolling() {
if (this.isPolling) return;
this.isPolling = true;
this.pollTimer = setInterval(() => {
this.pollStatus();
}, this.pollInterval);
},
// 停止轮询
stopPolling() {
if (this.pollTimer) {
clearInterval(this.pollTimer);
this.pollTimer = null;
}
this.isPolling = false;
this.loadings.exportDeclareLoading = false;
},
datasDownload(dataSource) {
let obj = {
...
...
@@ -1314,24 +1466,46 @@ export default {
obj.endCreateTime = obj.createTime[1];
}
obj.declareId = this.selected.map((item) => item.declareId);
exportDeclareData(obj)
.then((res) => {
// if (res.code === "200") {
// // this.alertSuccessMsg(res.message);
// } else {
// console.log(res.message);
// this.alertWarningMsg(res.message);
// }
const _that = this;
_that
.$confirm(`正在导出中,请稍候!`, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.catch((err) => {
console.log(err);
this.alertErrorMsg(err);
.then(() => {
getSubmitExportTask(obj)
.then((res) => {
if (+res.code === 200) {
console.log(res);
_that.currentTaskId = res.data;
_that.datasExportVisible = false;
_that.$refs.exportDialog.datasExportVisible = false;
_that.startPolling();
}
})
.catch((err) => {
console.log(err);
});
})
.
finally((res
) => {
this
.loadings.exportDeclareLoading = false;
this
.datasExportVisible = false;
this
.$refs.exportDialog.datasExportVisible = false;
.
catch((
) => {
_that
.loadings.exportDeclareLoading = false;
_that
.datasExportVisible = false;
_that
.$refs.exportDialog.datasExportVisible = false;
});
// exportDeclareData(obj)
// .then((res) => {})
// .catch((err) => {
// console.log(err);
// this.alertErrorMsg(err);
// })
// .finally((res) => {
// this.loadings.exportDeclareLoading = false;
// this.datasExportVisible = false;
// this.$refs.exportDialog.datasExportVisible = false;
// });
},
//导出
downloadData() {
...
...
Please
register
or
login
to post a comment