1
This commit is contained in:
@@ -61,9 +61,8 @@ server {
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $server_name;
|
||||
|
||||
# 请求体相关配置(重要:支持POST请求)
|
||||
proxy_set_header Content-Type $content_type;
|
||||
proxy_set_header Content-Length $content_length;
|
||||
# 勿手动设置 Content-Type / Content-Length:multipart 上传必须原样转发(含 boundary),
|
||||
# 且分块请求时 $content_length 可能为空,会导致后端报「not a multipart request」。
|
||||
proxy_pass_request_headers on;
|
||||
proxy_pass_request_body on;
|
||||
|
||||
@@ -96,9 +95,6 @@ server {
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $server_name;
|
||||
|
||||
# POST请求支持
|
||||
proxy_set_header Content-Type $content_type;
|
||||
proxy_set_header Content-Length $content_length;
|
||||
proxy_pass_request_headers on;
|
||||
proxy_pass_request_body on;
|
||||
|
||||
@@ -124,8 +120,6 @@ server {
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $server_name;
|
||||
|
||||
proxy_set_header Content-Type $content_type;
|
||||
proxy_set_header Content-Length $content_length;
|
||||
proxy_pass_request_headers on;
|
||||
proxy_pass_request_body on;
|
||||
|
||||
@@ -147,9 +141,6 @@ server {
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $server_name;
|
||||
|
||||
# POST请求支持
|
||||
proxy_set_header Content-Type $content_type;
|
||||
proxy_set_header Content-Length $content_length;
|
||||
proxy_pass_request_headers on;
|
||||
proxy_pass_request_body on;
|
||||
|
||||
|
||||
@@ -178,12 +178,18 @@ export function listGroupRebateExcelUploads(query) {
|
||||
})
|
||||
}
|
||||
|
||||
/** 导入跟团返现 Excel(multipart) */
|
||||
export function importGroupRebateExcel(formData) {
|
||||
/** 删除后返表上传记录,并回滚对应订单后返备注(新导入数据) */
|
||||
export function deleteGroupRebateUpload(id) {
|
||||
return request({
|
||||
url: '/system/jdorder/groupRebateUpload/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
function postGroupRebateMultipart(url, formData) {
|
||||
return axios
|
||||
.post(process.env.VUE_APP_BASE_API + '/system/jdorder/importGroupRebateExcel', formData, {
|
||||
.post(process.env.VUE_APP_BASE_API + url, formData, {
|
||||
headers: { Authorization: 'Bearer ' + getToken() },
|
||||
// 全局 axios.defaults 为 application/json,会覆盖 multipart;必须去掉由浏览器自动带 boundary
|
||||
transformRequest: [
|
||||
(data, headers) => {
|
||||
if (data instanceof FormData) {
|
||||
@@ -200,12 +206,22 @@ export function importGroupRebateExcel(formData) {
|
||||
.then((res) => {
|
||||
const d = res.data
|
||||
if (!d || d.code !== 200) {
|
||||
return Promise.reject(new Error((d && d.msg) || '导入失败'))
|
||||
return Promise.reject(new Error((d && d.msg) || '请求失败'))
|
||||
}
|
||||
return d
|
||||
})
|
||||
}
|
||||
|
||||
/** 导入跟团返现 Excel(multipart,单文件) */
|
||||
export function importGroupRebateExcel(formData) {
|
||||
return postGroupRebateMultipart('/system/jdorder/importGroupRebateExcel', formData)
|
||||
}
|
||||
|
||||
/** 批量导入后返表(multipart,多个 files 字段) */
|
||||
export function importGroupRebateExcelBatch(formData) {
|
||||
return postGroupRebateMultipart('/system/jdorder/importGroupRebateExcelBatch', formData)
|
||||
}
|
||||
|
||||
// 手动获取物流信息(用于调试)
|
||||
export function fetchLogisticsManually(data) {
|
||||
return request({
|
||||
|
||||
@@ -130,7 +130,7 @@
|
||||
<el-button type="success" size="small" icon="el-icon-check" @click="handleBatchMarkRebateReceived" :loading="batchMarkLoading" title="批量将赔付金额大于0的订单标记为后返到账(仅执行一次)">批量标记后返到账</el-button>
|
||||
<el-button type="warning" size="small" icon="el-icon-sort" @click="handleReverseSyncThirdPartyOrderNo" :loading="reverseSyncLoading" title="从腾讯文档第850行开始,通过物流链接反向匹配订单,将腾讯文档的单号列值写入到订单的第三方单号字段">反向同步第三方单号</el-button>
|
||||
<el-button v-if="!isMobile" type="primary" size="small" icon="el-icon-document-copy" @click="handleBatchCopyExcelText" :disabled="selectedRows.length === 0" title="批量复制选中订单的录单格式(Excel可粘贴)">批量复制录单格式</el-button>
|
||||
<el-button v-if="!isMobile" type="primary" size="small" icon="el-icon-upload2" @click="rebateImportDialogVisible = true" title="上传跟团返现等 Excel,按单号写入后返备注(可多次导入累加)">导入后返表</el-button>
|
||||
<el-button v-if="!isMobile" type="primary" size="small" icon="el-icon-upload2" @click="rebateImportDialogVisible = true" title="可一次选多个 Excel,提交后由后台依次导入;详情见后返上传记录">导入后返表</el-button>
|
||||
<el-button v-if="!isMobile" type="info" size="small" icon="el-icon-folder-opened" @click="openRebateUploadRecordDialog" title="查看历史上传的后返表原件并可重新下载">后返上传记录</el-button>
|
||||
<el-button v-if="!isMobile" type="success" size="small" icon="el-icon-document-copy" @click="handleBatchCopyRebateText" :disabled="selectedRows.length === 0" title="批量复制选中订单的后返录表格式(Excel可粘贴)">批量复制后返录表</el-button>
|
||||
<el-button v-if="!isMobile" type="info" size="small" icon="el-icon-document-copy" @click="handleBatchCopySichuanCommerceText" :disabled="selectedRows.length === 0" title="批量复制选中订单的四川商贸录表格式(日期 型号 数量 地址 价格 备注 是否安排 物流)">四川商贸录表</el-button>
|
||||
@@ -880,38 +880,48 @@
|
||||
<!-- 分销标识接收人配置 -->
|
||||
<distribution-mark-touser-config v-model="showTouserConfig" @config-updated="handleTouserConfigUpdated" />
|
||||
|
||||
<!-- 导入跟团返现 / 后返 Excel -->
|
||||
<!-- 导入跟团返现 / 后返 Excel(支持多文件,一次提交后台依次处理) -->
|
||||
<el-dialog
|
||||
title="导入后返表(跟团返现等)"
|
||||
:visible.sync="rebateImportDialogVisible"
|
||||
width="520px"
|
||||
append-to-body
|
||||
@closed="rebateImportTitle = ''"
|
||||
@closed="onRebateImportDialogClosed"
|
||||
>
|
||||
<p style="color: #909399; font-size: 13px; margin: 0 0 12px;">
|
||||
表头需包含「单号」或「订单号」、「是否返现」、返现金额列(优先「总共返现」)。按单号匹配系统订单并<strong>追加</strong>一条备注记录,同一订单多次上传会保留历史。
|
||||
表头需包含「单号」或「订单号」、「是否返现」、返现金额列(优先「总共返现」)。可选<strong>多个</strong> Excel,点「提交后台处理」后由服务端依次导入;不弹逐条结果,请到「后返上传记录」查看。
|
||||
</p>
|
||||
<el-form label-width="88px" size="small">
|
||||
<el-form-item label="文档标题">
|
||||
<el-input
|
||||
v-model="rebateImportTitle"
|
||||
placeholder="如:跟团+返现 260316(留空则用文件名)"
|
||||
placeholder="仅选 1 个文件时可用;多文件时各文件用各自文件名"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="Excel">
|
||||
<el-upload
|
||||
ref="rebateExcelUploader"
|
||||
drag
|
||||
multiple
|
||||
:show-file-list="true"
|
||||
:limit="1"
|
||||
:limit="30"
|
||||
:auto-upload="false"
|
||||
accept=".xlsx,.xls"
|
||||
:disabled="rebateImportLoading"
|
||||
:http-request="handleRebateExcelUpload"
|
||||
:on-exceed="onRebateExcelExceed"
|
||||
>
|
||||
<i class="el-icon-upload" />
|
||||
<div class="el-upload__text">拖到此处,或<em>点击上传</em></div>
|
||||
<div slot="tip" class="el-upload__tip">仅解析第一个工作表;未匹配到的单号会在结果中列出</div>
|
||||
<div class="el-upload__text">拖到此处,或<em>点击选择</em>(可多选)</div>
|
||||
<div slot="tip" class="el-upload__tip">单次最多 30 个文件;仅解析每个文件的第一个工作表</div>
|
||||
</el-upload>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
:loading="rebateImportLoading"
|
||||
style="margin-top: 10px"
|
||||
@click="submitRebateExcelBatch"
|
||||
>提交后台处理</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-dialog>
|
||||
@@ -942,7 +952,7 @@
|
||||
<el-table-column label="未匹配" prop="notFoundCount" width="72" align="center" />
|
||||
<el-table-column label="上传人" prop="createBy" width="100" show-overflow-tooltip />
|
||||
<el-table-column label="时间" prop="createTime" width="155" />
|
||||
<el-table-column label="操作" width="100" align="center" fixed="right">
|
||||
<el-table-column label="操作" width="148" align="center" fixed="right">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
type="text"
|
||||
@@ -950,6 +960,11 @@
|
||||
:disabled="!scope.row.filePath"
|
||||
@click="downloadRebateUploadFile(scope.row)"
|
||||
>下载</el-button>
|
||||
<el-button
|
||||
type="text"
|
||||
size="small"
|
||||
@click="confirmDeleteRebateUpload(scope.row)"
|
||||
>删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -965,7 +980,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listJDOrders, updateJDOrder, delJDOrder, fetchLogisticsManually, batchMarkRebateReceived, generateExcelText, importGroupRebateExcel, listGroupRebateExcelUploads } from '@/api/system/jdorder'
|
||||
import { listJDOrders, updateJDOrder, delJDOrder, fetchLogisticsManually, batchMarkRebateReceived, generateExcelText, importGroupRebateExcelBatch, listGroupRebateExcelUploads, deleteGroupRebateUpload } from '@/api/system/jdorder'
|
||||
import { fillLogisticsByOrderNo, getTokenStatus, getTencentDocAuthUrl, testUserInfo, getAutoWriteConfig, reverseSyncThirdPartyOrderNo } from '@/api/jarvis/tendoc'
|
||||
import { mapGetters } from 'vuex'
|
||||
import ListLayout from '@/components/ListLayout'
|
||||
@@ -1311,38 +1326,51 @@ export default {
|
||||
const min = String(d.getMinutes()).padStart(2, '0')
|
||||
return `${y}-${m}-${day} ${h}:${min}`
|
||||
},
|
||||
handleRebateExcelUpload(req) {
|
||||
clearRebateExcelUploaderFiles() {
|
||||
this.$nextTick(() => {
|
||||
const u = this.$refs.rebateExcelUploader
|
||||
if (u && typeof u.clearFiles === 'function') {
|
||||
u.clearFiles()
|
||||
}
|
||||
})
|
||||
},
|
||||
onRebateImportDialogClosed() {
|
||||
this.rebateImportTitle = ''
|
||||
this.clearRebateExcelUploaderFiles()
|
||||
},
|
||||
onRebateExcelExceed() {
|
||||
this.$message.warning('单次最多选择 30 个文件')
|
||||
},
|
||||
submitRebateExcelBatch() {
|
||||
const u = this.$refs.rebateExcelUploader
|
||||
const uploadFiles = (u && u.uploadFiles) ? u.uploadFiles : []
|
||||
const files = uploadFiles.map((f) => f.raw).filter(Boolean)
|
||||
if (!files.length) {
|
||||
this.$message.warning('请先选择 Excel 文件')
|
||||
return
|
||||
}
|
||||
const formData = new FormData()
|
||||
formData.append('file', req.file)
|
||||
files.forEach((file) => formData.append('files', file))
|
||||
const title = (this.rebateImportTitle || '').trim()
|
||||
if (title) {
|
||||
if (files.length === 1 && title) {
|
||||
formData.append('documentTitle', title)
|
||||
}
|
||||
this.rebateImportLoading = true
|
||||
importGroupRebateExcel(formData)
|
||||
importGroupRebateExcelBatch(formData)
|
||||
.then((res) => {
|
||||
const data = res.data || {}
|
||||
const msg = data.message || res.msg || (data.success === false ? '导入未完成' : '导入完成')
|
||||
if (data.success === false) {
|
||||
const msg = data.message || res.msg || '已处理'
|
||||
if (data.failCount > 0) {
|
||||
this.$message.warning(msg)
|
||||
} else {
|
||||
this.$message.success(msg)
|
||||
}
|
||||
const nf = data.notFoundOrderNos
|
||||
if (nf && nf.length) {
|
||||
const sample = nf.slice(0, 30).join(', ')
|
||||
const more = nf.length > 30 ? ` …共 ${nf.length} 个` : ''
|
||||
this.$alert(`以下单号在系统中未找到,未写入:${sample}${more}`, '未匹配单号', { type: 'warning' })
|
||||
}
|
||||
if (data.errors && data.errors.length) {
|
||||
this.$message.warning(`部分行写入失败 ${data.errors.length} 条,详情见控制台`)
|
||||
console.warn('后返表导入错误', data.errors)
|
||||
}
|
||||
this.clearRebateExcelUploaderFiles()
|
||||
this.rebateImportDialogVisible = false
|
||||
this.getList()
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$message.error(e.message || '导入失败')
|
||||
this.$message.error(e.message || '提交失败')
|
||||
})
|
||||
.finally(() => {
|
||||
this.rebateImportLoading = false
|
||||
@@ -1373,6 +1401,26 @@ export default {
|
||||
const name = row.originalFilename || `rebate_upload_${row.id}.xlsx`
|
||||
this.download(`/system/jdorder/groupRebateUpload/download/${row.id}`, {}, name)
|
||||
},
|
||||
confirmDeleteRebateUpload(row) {
|
||||
const title = row.documentTitle || row.originalFilename || ('ID ' + row.id)
|
||||
this.$confirm(
|
||||
`将删除上传记录「${title}」,并尝试从订单中移除本次导入写入的后返备注。历史导入(无上传批次标记)可能无法自动清除订单备注,是否继续?`,
|
||||
'删除后返上传记录',
|
||||
{ type: 'warning', confirmButtonText: '删除', cancelButtonText: '取消' }
|
||||
).then(() => {
|
||||
return deleteGroupRebateUpload(row.id)
|
||||
}).then((res) => {
|
||||
const data = res.data || {}
|
||||
const msg = data.message || res.msg || '已删除'
|
||||
this.$message.success(msg)
|
||||
this.fetchRebateUploadList()
|
||||
this.getList()
|
||||
}).catch((e) => {
|
||||
if (e !== 'cancel') {
|
||||
this.$message.error((e && e.message) || '删除失败')
|
||||
}
|
||||
})
|
||||
},
|
||||
resetQuery() {
|
||||
this.queryParams = {
|
||||
pageNum: 1,
|
||||
|
||||
Reference in New Issue
Block a user