|
|
@@ -525,6 +525,82 @@
|
|
|
<el-button @click="uploadStatus.open = false">取 消</el-button>
|
|
|
</div>
|
|
|
</el-dialog>
|
|
|
+
|
|
|
+ <!-- 导入结果对话框 -->
|
|
|
+ <el-dialog
|
|
|
+ title="导入结果"
|
|
|
+ :visible.sync="importResultDialog.open"
|
|
|
+ width="80%"
|
|
|
+ append-to-body
|
|
|
+ :close-on-click-modal="false"
|
|
|
+ >
|
|
|
+ <div class="import-result-summary">
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="8">
|
|
|
+ <div class="summary-item success">
|
|
|
+ <div class="summary-label">成功</div>
|
|
|
+ <div class="summary-value">{{ importResult.successNum || 0 }}</div>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <div class="summary-item failure">
|
|
|
+ <div class="summary-label">失败</div>
|
|
|
+ <div class="summary-value">{{ importResult.failureNum || 0 }}</div>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <div class="summary-item total">
|
|
|
+ <div class="summary-label">总计</div>
|
|
|
+ <div class="summary-value">{{ (importResult.successNum || 0) + (importResult.failureNum || 0) }}</div>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <el-tabs v-model="importResultTab" type="card">
|
|
|
+ <el-tab-pane label="成功列表" name="success">
|
|
|
+ <el-table
|
|
|
+ :data="displayedSuccessList"
|
|
|
+ border
|
|
|
+ stripe
|
|
|
+ height="400"
|
|
|
+ style="width: 100%"
|
|
|
+ v-loading="successListLoading"
|
|
|
+ @scroll="handleSuccessListScroll"
|
|
|
+ >
|
|
|
+ <el-table-column type="index" label="序号" width="60" align="center" />
|
|
|
+ <el-table-column prop="rowNum" label="Excel行号" width="120" align="center" />
|
|
|
+ <el-table-column prop="orderCode" label="订单号" align="center" />
|
|
|
+ </el-table>
|
|
|
+ <div v-if="displayedSuccessList.length < importResult.successList.length" class="load-more-tip">
|
|
|
+ 已加载 {{ displayedSuccessList.length }} / {{ importResult.successList.length }} 条,滚动加载更多...
|
|
|
+ </div>
|
|
|
+ </el-tab-pane>
|
|
|
+ <el-tab-pane label="失败列表" name="failure">
|
|
|
+ <el-table
|
|
|
+ :data="displayedFailureList"
|
|
|
+ border
|
|
|
+ stripe
|
|
|
+ height="400"
|
|
|
+ style="width: 100%"
|
|
|
+ v-loading="failureListLoading"
|
|
|
+ @scroll="handleFailureListScroll"
|
|
|
+ >
|
|
|
+ <el-table-column type="index" label="序号" width="60" align="center" />
|
|
|
+ <el-table-column prop="rowNum" label="Excel行号" width="120" align="center" />
|
|
|
+ <el-table-column prop="orderCode" label="订单号" align="center" />
|
|
|
+ <el-table-column prop="errorMessage" label="错误信息" align="center" show-overflow-tooltip />
|
|
|
+ </el-table>
|
|
|
+ <div v-if="displayedFailureList.length < importResult.failureList.length" class="load-more-tip">
|
|
|
+ 已加载 {{ displayedFailureList.length }} / {{ importResult.failureList.length }} 条,滚动加载更多...
|
|
|
+ </div>
|
|
|
+ </el-tab-pane>
|
|
|
+ </el-tabs>
|
|
|
+
|
|
|
+ <div slot="footer" class="dialog-footer">
|
|
|
+ <el-button type="primary" @click="importResultDialog.open = false">关 闭</el-button>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
@@ -663,6 +739,28 @@ export default {
|
|
|
// 上传的地址
|
|
|
url: process.env.VUE_APP_BASE_API + "/his/integralOrder/importOrderStatusData"
|
|
|
},
|
|
|
+ // 导入结果对话框
|
|
|
+ importResultDialog: {
|
|
|
+ open: false
|
|
|
+ },
|
|
|
+ // 导入结果数据
|
|
|
+ importResult: {
|
|
|
+ successNum: 0,
|
|
|
+ failureNum: 0,
|
|
|
+ successList: [],
|
|
|
+ failureList: []
|
|
|
+ },
|
|
|
+ // 导入结果标签页
|
|
|
+ importResultTab: "success",
|
|
|
+ // 分片加载相关
|
|
|
+ displayedSuccessList: [],
|
|
|
+ displayedFailureList: [],
|
|
|
+ successListPageSize: 50,
|
|
|
+ failureListPageSize: 50,
|
|
|
+ successListCurrentPage: 1,
|
|
|
+ failureListCurrentPage: 1,
|
|
|
+ successListLoading: false,
|
|
|
+ failureListLoading: false,
|
|
|
};
|
|
|
},
|
|
|
created() {
|
|
|
@@ -687,13 +785,121 @@ export default {
|
|
|
this.uploadStatus.isUploading = true;
|
|
|
},
|
|
|
// 文件上传成功处理
|
|
|
- handleFileSuccessOrder(response, file, fileList) {
|
|
|
- this.uploadStatus.open = false;
|
|
|
- this.uploadStatus.isUploading = false;
|
|
|
- this.$refs.uploadStatus.clearFiles();
|
|
|
- this.$alert(response.msg, "导入结果", { dangerouslyUseHTMLString: true });
|
|
|
- this.getList();
|
|
|
- },
|
|
|
+ handleFileSuccessOrder(response, file, fileList) {
|
|
|
+ this.uploadStatus.open = false;
|
|
|
+ this.uploadStatus.isUploading = false;
|
|
|
+ this.$refs.uploadStatus.clearFiles();
|
|
|
+
|
|
|
+ // 处理新的返回结果格式
|
|
|
+ if (response.code === 200 && response.data) {
|
|
|
+ this.importResult = response.data;
|
|
|
+ // 初始化显示列表
|
|
|
+ this.displayedSuccessList = [];
|
|
|
+ this.displayedFailureList = [];
|
|
|
+ this.successListCurrentPage = 1;
|
|
|
+ this.failureListCurrentPage = 1;
|
|
|
+
|
|
|
+ // 加载第一页数据
|
|
|
+ this.loadSuccessListPage(1);
|
|
|
+ this.loadFailureListPage(1);
|
|
|
+
|
|
|
+ // 显示结果对话框
|
|
|
+ this.importResultDialog.open = true;
|
|
|
+ this.importResultTab = this.importResult.failureNum > 0 ? "failure" : "success";
|
|
|
+ } else {
|
|
|
+ this.$alert(response.msg || "导入失败", "导入结果", { dangerouslyUseHTMLString: true });
|
|
|
+ }
|
|
|
+
|
|
|
+ this.getList();
|
|
|
+ },
|
|
|
+ // 加载成功列表分页数据
|
|
|
+ loadSuccessListPage(page) {
|
|
|
+ if (this.successListLoading) return;
|
|
|
+ this.successListLoading = true;
|
|
|
+
|
|
|
+ const start = (page - 1) * this.successListPageSize;
|
|
|
+ const end = start + this.successListPageSize;
|
|
|
+ const pageData = this.importResult.successList.slice(start, end);
|
|
|
+
|
|
|
+ this.displayedSuccessList = this.displayedSuccessList.concat(pageData);
|
|
|
+ this.successListCurrentPage = page;
|
|
|
+
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.successListLoading = false;
|
|
|
+ // 绑定滚动事件
|
|
|
+ if (page === 1) {
|
|
|
+ this.bindScrollEvents();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 加载失败列表分页数据
|
|
|
+ loadFailureListPage(page) {
|
|
|
+ if (this.failureListLoading) return;
|
|
|
+ this.failureListLoading = true;
|
|
|
+
|
|
|
+ const start = (page - 1) * this.failureListPageSize;
|
|
|
+ const end = start + this.failureListPageSize;
|
|
|
+ const pageData = this.importResult.failureList.slice(start, end);
|
|
|
+
|
|
|
+ this.displayedFailureList = this.displayedFailureList.concat(pageData);
|
|
|
+ this.failureListCurrentPage = page;
|
|
|
+
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.failureListLoading = false;
|
|
|
+ // 绑定滚动事件
|
|
|
+ if (page === 1) {
|
|
|
+ this.bindScrollEvents();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 绑定滚动事件
|
|
|
+ bindScrollEvents() {
|
|
|
+ this.$nextTick(() => {
|
|
|
+ // 成功列表滚动
|
|
|
+ const successTableBody = document.querySelector('.el-dialog__body .el-tabs__content .el-tab-pane:first-child .el-table__body-wrapper');
|
|
|
+ if (successTableBody) {
|
|
|
+ successTableBody.removeEventListener('scroll', this.handleSuccessListScroll);
|
|
|
+ successTableBody.addEventListener('scroll', this.handleSuccessListScroll);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 失败列表滚动
|
|
|
+ const failureTableBody = document.querySelector('.el-dialog__body .el-tabs__content .el-tab-pane:last-child .el-table__body-wrapper');
|
|
|
+ if (failureTableBody) {
|
|
|
+ failureTableBody.removeEventListener('scroll', this.handleFailureListScroll);
|
|
|
+ failureTableBody.addEventListener('scroll', this.handleFailureListScroll);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 成功列表滚动加载
|
|
|
+ handleSuccessListScroll(event) {
|
|
|
+ const container = event.target;
|
|
|
+ const scrollTop = container.scrollTop;
|
|
|
+ const scrollHeight = container.scrollHeight;
|
|
|
+ const clientHeight = container.clientHeight;
|
|
|
+
|
|
|
+ // 距离底部50px时加载下一页
|
|
|
+ if (scrollHeight - scrollTop - clientHeight < 50) {
|
|
|
+ const totalPages = Math.ceil(this.importResult.successList.length / this.successListPageSize);
|
|
|
+ if (this.successListCurrentPage < totalPages && !this.successListLoading) {
|
|
|
+ this.loadSuccessListPage(this.successListCurrentPage + 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 失败列表滚动加载
|
|
|
+ handleFailureListScroll(event) {
|
|
|
+ const container = event.target;
|
|
|
+ const scrollTop = container.scrollTop;
|
|
|
+ const scrollHeight = container.scrollHeight;
|
|
|
+ const clientHeight = container.clientHeight;
|
|
|
+
|
|
|
+ // 距离底部50px时加载下一页
|
|
|
+ if (scrollHeight - scrollTop - clientHeight < 50) {
|
|
|
+ const totalPages = Math.ceil(this.importResult.failureList.length / this.failureListPageSize);
|
|
|
+ if (this.failureListCurrentPage < totalPages && !this.failureListLoading) {
|
|
|
+ this.loadFailureListPage(this.failureListCurrentPage + 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
importUpdateOrderTemplate(){
|
|
|
getIntegralTemplate().then(response => {
|
|
|
this.download(response.msg);
|
|
|
@@ -1371,4 +1577,63 @@ export default {
|
|
|
align-items: center;
|
|
|
gap: 8px;
|
|
|
}
|
|
|
+
|
|
|
+/* 导入结果样式 */
|
|
|
+.import-result-summary {
|
|
|
+ margin-bottom: 20px;
|
|
|
+ padding: 20px;
|
|
|
+ background-color: #f5f7fa;
|
|
|
+ border-radius: 4px;
|
|
|
+}
|
|
|
+
|
|
|
+.summary-item {
|
|
|
+ text-align: center;
|
|
|
+ padding: 15px;
|
|
|
+ border-radius: 4px;
|
|
|
+}
|
|
|
+
|
|
|
+.summary-item.success {
|
|
|
+ background-color: #f0f9ff;
|
|
|
+ border: 1px solid #b3d8ff;
|
|
|
+}
|
|
|
+
|
|
|
+.summary-item.failure {
|
|
|
+ background-color: #fef0f0;
|
|
|
+ border: 1px solid #fbc4c4;
|
|
|
+}
|
|
|
+
|
|
|
+.summary-item.total {
|
|
|
+ background-color: #f4f4f5;
|
|
|
+ border: 1px solid #d3d4d6;
|
|
|
+}
|
|
|
+
|
|
|
+.summary-label {
|
|
|
+ font-size: 14px;
|
|
|
+ color: #606266;
|
|
|
+ margin-bottom: 8px;
|
|
|
+}
|
|
|
+
|
|
|
+.summary-value {
|
|
|
+ font-size: 24px;
|
|
|
+ font-weight: bold;
|
|
|
+}
|
|
|
+
|
|
|
+.summary-item.success .summary-value {
|
|
|
+ color: #67c23a;
|
|
|
+}
|
|
|
+
|
|
|
+.summary-item.failure .summary-value {
|
|
|
+ color: #f56c6c;
|
|
|
+}
|
|
|
+
|
|
|
+.summary-item.total .summary-value {
|
|
|
+ color: #909399;
|
|
|
+}
|
|
|
+
|
|
|
+.load-more-tip {
|
|
|
+ text-align: center;
|
|
|
+ padding: 10px;
|
|
|
+ color: #909399;
|
|
|
+ font-size: 12px;
|
|
|
+}
|
|
|
</style>
|