|
|
|
@ -17,7 +17,14 @@
|
|
|
|
</el-button>
|
|
|
|
</el-button>
|
|
|
|
</el-col>
|
|
|
|
</el-col>
|
|
|
|
<el-col :span="8">
|
|
|
|
<el-col :span="8">
|
|
|
|
<el-button type="success" icon="el-icon-upload2" @click="handleImport('stockHighLow')">
|
|
|
|
<el-button type="success" icon="el-icon-upload2" @click="handleBatchImport">
|
|
|
|
|
|
|
|
批量导入每日交易数据
|
|
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
|
|
</el-col>
|
|
|
|
|
|
|
|
</el-row>
|
|
|
|
|
|
|
|
<el-row :gutter="20" style="margin-top: 10px;">
|
|
|
|
|
|
|
|
<el-col :span="8">
|
|
|
|
|
|
|
|
<el-button type="info" icon="el-icon-upload2" @click="handleImport('stockHighLow')">
|
|
|
|
导入新高新低数据
|
|
|
|
导入新高新低数据
|
|
|
|
</el-button>
|
|
|
|
</el-button>
|
|
|
|
</el-col>
|
|
|
|
</el-col>
|
|
|
|
@ -331,6 +338,58 @@
|
|
|
|
<el-button @click="upload.open = false">取 消</el-button>
|
|
|
|
<el-button @click="upload.open = false">取 消</el-button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</el-dialog>
|
|
|
|
</el-dialog>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 批量导入对话框 -->
|
|
|
|
|
|
|
|
<el-dialog title="批量导入每日交易数据" :visible.sync="batchUpload.open" width="600px" append-to-body>
|
|
|
|
|
|
|
|
<el-upload
|
|
|
|
|
|
|
|
ref="batchUploadRef"
|
|
|
|
|
|
|
|
:limit="60"
|
|
|
|
|
|
|
|
multiple
|
|
|
|
|
|
|
|
accept=".xlsx, .xls"
|
|
|
|
|
|
|
|
:headers="uploadHeaders"
|
|
|
|
|
|
|
|
:auto-upload="false"
|
|
|
|
|
|
|
|
:on-change="handleBatchFileChange"
|
|
|
|
|
|
|
|
drag
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<i class="el-icon-upload"></i>
|
|
|
|
|
|
|
|
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
|
|
|
|
|
|
|
<div class="el-upload__tip text-center" slot="tip">
|
|
|
|
|
|
|
|
<span>仅允许导入xlsx、xls格式文件,支持批量选择多个文件</span>
|
|
|
|
|
|
|
|
<br>
|
|
|
|
|
|
|
|
<span>文件名格式:动量原始股(全部A股)_20250424.xlsx,其中20250424为交易日期</span>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</el-upload>
|
|
|
|
|
|
|
|
<el-form :model="batchUpload" style="margin-top: 15px;">
|
|
|
|
|
|
|
|
<el-form-item label="是否更新已存在数据">
|
|
|
|
|
|
|
|
<el-checkbox v-model="batchUpload.updateSupport">更新已存在数据</el-checkbox>
|
|
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
</el-form>
|
|
|
|
|
|
|
|
<div v-if="batchFileList.length > 0" style="margin-top: 15px;">
|
|
|
|
|
|
|
|
<el-divider>已选择文件</el-divider>
|
|
|
|
|
|
|
|
<el-table :data="batchFileList" stripe style="width: 100%;">
|
|
|
|
|
|
|
|
<el-table-column prop="name" label="文件名" min-width="300" />
|
|
|
|
|
|
|
|
<el-table-column prop="tradeDate" label="解析的交易日期" width="150" />
|
|
|
|
|
|
|
|
<el-table-column prop="status" label="状态" width="100">
|
|
|
|
|
|
|
|
<template slot-scope="scope">
|
|
|
|
|
|
|
|
<el-tag v-if="scope.row.status === 'pending'" type="info" size="small">待处理</el-tag>
|
|
|
|
|
|
|
|
<el-tag v-else-if="scope.row.status === 'success'" type="success" size="small">成功</el-tag>
|
|
|
|
|
|
|
|
<el-tag v-else-if="scope.row.status === 'error'" type="danger" size="small">失败</el-tag>
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
|
|
<el-table-column label="操作" width="80">
|
|
|
|
|
|
|
|
<template slot-scope="scope">
|
|
|
|
|
|
|
|
<el-button type="text" size="small" @click="removeBatchFile(scope.$index)">删除</el-button>
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
|
|
</el-table>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div slot="footer" class="dialog-footer">
|
|
|
|
|
|
|
|
<el-button type="primary" @click="submitBatchUpload" :loading="batchUpload.loading">
|
|
|
|
|
|
|
|
{{ batchUpload.loading ? '导入中...' : '开始导入' }}
|
|
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
|
|
<el-button @click="batchUpload.open = false" :disabled="batchUpload.loading">取 消</el-button>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</el-dialog>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
@ -422,6 +481,14 @@ export default {
|
|
|
|
},
|
|
|
|
},
|
|
|
|
fileList: [],
|
|
|
|
fileList: [],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ========================= 批量上传相关 =========================
|
|
|
|
|
|
|
|
batchUpload: {
|
|
|
|
|
|
|
|
open: false,
|
|
|
|
|
|
|
|
updateSupport: false,
|
|
|
|
|
|
|
|
loading: false
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
batchFileList: [],
|
|
|
|
|
|
|
|
|
|
|
|
// ========================= 分析状态相关 =========================
|
|
|
|
// ========================= 分析状态相关 =========================
|
|
|
|
analysisStatus: {
|
|
|
|
analysisStatus: {
|
|
|
|
isAnalyzed: false, // 当前选择日期是否已分析
|
|
|
|
isAnalyzed: false, // 当前选择日期是否已分析
|
|
|
|
@ -817,6 +884,130 @@ export default {
|
|
|
|
} else if (this.upload.type === 'stockHighLow') {
|
|
|
|
} else if (this.upload.type === 'stockHighLow') {
|
|
|
|
this.getStockHighLowList()
|
|
|
|
this.getStockHighLowList()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ========================= 批量导入方法 =========================
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** 打开批量导入对话框 */
|
|
|
|
|
|
|
|
handleBatchImport() {
|
|
|
|
|
|
|
|
this.batchUpload.open = true
|
|
|
|
|
|
|
|
this.batchUpload.updateSupport = false
|
|
|
|
|
|
|
|
this.batchFileList = []
|
|
|
|
|
|
|
|
// 清除已选文件
|
|
|
|
|
|
|
|
this.$nextTick(() => {
|
|
|
|
|
|
|
|
if (this.$refs.batchUploadRef) {
|
|
|
|
|
|
|
|
this.$refs.batchUploadRef.clearFiles()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** 批量文件选择变化 */
|
|
|
|
|
|
|
|
handleBatchFileChange(file, fileList) {
|
|
|
|
|
|
|
|
// 处理文件列表,解析交易日期
|
|
|
|
|
|
|
|
this.batchFileList = fileList.map(item => {
|
|
|
|
|
|
|
|
const tradeDate = this.parseTradeDateFromFileName(item.name)
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
|
|
name: item.name,
|
|
|
|
|
|
|
|
raw: item.raw,
|
|
|
|
|
|
|
|
tradeDate: tradeDate,
|
|
|
|
|
|
|
|
status: 'pending'
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** 从文件名解析交易日期 */
|
|
|
|
|
|
|
|
parseTradeDateFromFileName(fileName) {
|
|
|
|
|
|
|
|
// 匹配文件名中的日期格式,例如:动量原始股(全部A股)_20250424.xlsx
|
|
|
|
|
|
|
|
const match = fileName.match(/_([0-9]{8})\.xlsx?$/i)
|
|
|
|
|
|
|
|
if (match && match[1]) {
|
|
|
|
|
|
|
|
const dateStr = match[1]
|
|
|
|
|
|
|
|
// 格式化日期为 yyyy-MM-dd
|
|
|
|
|
|
|
|
return `${dateStr.substring(0, 4)}-${dateStr.substring(4, 6)}-${dateStr.substring(6, 8)}`
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return '解析失败'
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** 删除批量导入文件 */
|
|
|
|
|
|
|
|
removeBatchFile(index) {
|
|
|
|
|
|
|
|
this.batchFileList.splice(index, 1)
|
|
|
|
|
|
|
|
// 同步更新上传组件的文件列表
|
|
|
|
|
|
|
|
if (this.$refs.batchUploadRef) {
|
|
|
|
|
|
|
|
this.$refs.batchUploadRef.clearFiles()
|
|
|
|
|
|
|
|
// 重新添加剩余文件
|
|
|
|
|
|
|
|
this.batchFileList.forEach(item => {
|
|
|
|
|
|
|
|
this.$refs.batchUploadRef.handleStart({ raw: item.raw, name: item.name })
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** 提交批量上传 */
|
|
|
|
|
|
|
|
submitBatchUpload() {
|
|
|
|
|
|
|
|
if (this.batchFileList.length === 0) {
|
|
|
|
|
|
|
|
this.$message.error('请选择要上传的文件')
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 检查是否有解析失败的文件
|
|
|
|
|
|
|
|
const invalidFiles = this.batchFileList.filter(item => item.tradeDate === '解析失败')
|
|
|
|
|
|
|
|
if (invalidFiles.length > 0) {
|
|
|
|
|
|
|
|
this.$message.error('部分文件的交易日期解析失败,请检查文件名格式')
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.batchUpload.loading = true
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 按顺序处理每个文件
|
|
|
|
|
|
|
|
const processFile = async (index) => {
|
|
|
|
|
|
|
|
if (index >= this.batchFileList.length) {
|
|
|
|
|
|
|
|
// 所有文件处理完成
|
|
|
|
|
|
|
|
this.batchUpload.loading = false
|
|
|
|
|
|
|
|
this.batchUpload.open = false
|
|
|
|
|
|
|
|
this.$message.success('批量导入完成')
|
|
|
|
|
|
|
|
// 刷新数据列表
|
|
|
|
|
|
|
|
this.getDailyTradeList()
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const fileItem = this.batchFileList[index]
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
await this.processBatchFile(fileItem)
|
|
|
|
|
|
|
|
// 处理下一个文件
|
|
|
|
|
|
|
|
processFile(index + 1)
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
|
|
this.batchUpload.loading = false
|
|
|
|
|
|
|
|
this.$message.error('批量导入过程中发生错误:' + (error.message || '未知错误'))
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 开始处理第一个文件
|
|
|
|
|
|
|
|
processFile(0)
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** 处理单个批量文件的导入 */
|
|
|
|
|
|
|
|
processBatchFile(fileItem) {
|
|
|
|
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
|
|
|
const formData = new FormData()
|
|
|
|
|
|
|
|
formData.append('file', fileItem.raw)
|
|
|
|
|
|
|
|
formData.append('updateSupport', this.batchUpload.updateSupport)
|
|
|
|
|
|
|
|
formData.append('tradeDate', fileItem.tradeDate)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
request({
|
|
|
|
|
|
|
|
url: IMPORT_URLS.stockDailyTrade,
|
|
|
|
|
|
|
|
method: 'post',
|
|
|
|
|
|
|
|
data: formData,
|
|
|
|
|
|
|
|
headers: {
|
|
|
|
|
|
|
|
'Content-Type': 'multipart/form-data'
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}).then(response => {
|
|
|
|
|
|
|
|
// 更新文件状态为成功
|
|
|
|
|
|
|
|
fileItem.status = 'success'
|
|
|
|
|
|
|
|
resolve()
|
|
|
|
|
|
|
|
}).catch(error => {
|
|
|
|
|
|
|
|
// 更新文件状态为失败
|
|
|
|
|
|
|
|
fileItem.status = 'error'
|
|
|
|
|
|
|
|
resolve() // 继续处理下一个文件,即使当前文件失败
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|