上传修改

This commit is contained in:
Your Name 2026-07-24 11:22:41 +08:00
parent 1bf691bb7f
commit dda0165459
25 changed files with 258 additions and 73 deletions

8
.editorconfig Normal file
View File

@ -0,0 +1,8 @@
[*.{js,jsx,mjs,cjs,ts,tsx,mts,cts,vue,css,scss,sass,less,styl}]
charset = utf-8
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
end_of_line = lf
max_line_length = 100

View File

@ -1,5 +1,5 @@
# 页面标题 # 页面标题
VITE_APP_TITLE = 管理系统 VITE_APP_TITLE =
# 生产环境配置 # 生产环境配置
VITE_APP_ENV = 'production' VITE_APP_ENV = 'production'

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
* text=auto eol=lf

6
.prettierrc.json Normal file
View File

@ -0,0 +1,6 @@
{
"$schema": "https://json.schemastore.org/prettierrc",
"semi": false,
"singleQuote": true,
"printWidth": 100
}

1
RuoYi-Vue3 Submodule

@ -0,0 +1 @@
Subproject commit b8019c9f8e64c181a40bae5e98977c0270b58a98

BIN
dist (3).zip Normal file

Binary file not shown.

BIN
dist.zip Normal file

Binary file not shown.

26
eslint.config.js Normal file
View File

@ -0,0 +1,26 @@
import { defineConfig, globalIgnores } from 'eslint/config'
import globals from 'globals'
import js from '@eslint/js'
import pluginVue from 'eslint-plugin-vue'
import skipFormatting from '@vue/eslint-config-prettier/skip-formatting'
export default defineConfig([
{
name: 'app/files-to-lint',
files: ['**/*.{js,mjs,jsx,vue}'],
},
globalIgnores(['**/dist/**', '**/dist-ssr/**', '**/coverage/**']),
{
languageOptions: {
globals: {
...globals.browser,
},
},
},
js.configs.recommended,
...pluginVue.configs['flat/essential'],
skipFormatting,
])

8
jsconfig.json Normal file
View File

@ -0,0 +1,8 @@
{
"compilerOptions": {
"paths": {
"@/*": ["./src/*"]
}
},
"exclude": ["node_modules", "dist"]
}

1
openapi.json Normal file

File diff suppressed because one or more lines are too long

View File

@ -35,7 +35,8 @@
"vue-cropper": "1.1.1", "vue-cropper": "1.1.1",
"vue-router": "4.5.1", "vue-router": "4.5.1",
"vuedraggable": "4.1.0", "vuedraggable": "4.1.0",
"wind-core": "^1.1.8" "wind-core": "^1.1.8",
"yarn": "^1.22.22"
}, },
"devDependencies": { "devDependencies": {
"@vitejs/plugin-vue": "5.2.4", "@vitejs/plugin-vue": "5.2.4",

View File

@ -134,14 +134,16 @@ export function download(url, params, filename, config) {
const isBlob = blobValidate(data) const isBlob = blobValidate(data)
if (isBlob) { if (isBlob) {
const blob = new Blob([data]) const blob = new Blob([data])
// 先关闭遮罩再触发下载,避免全屏 loading 阻塞浏览器下载行为
downloadLoadingInstance.close()
saveAs(blob, filename) saveAs(blob, filename)
} else { } else {
const resText = await data.text() const resText = await data.text()
const rspObj = JSON.parse(resText) const rspObj = JSON.parse(resText)
const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default'] const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
ElMessage.error(errMsg) ElMessage.error(errMsg)
}
downloadLoadingInstance.close() downloadLoadingInstance.close()
}
}).catch((r) => { }).catch((r) => {
console.error(r) console.error(r)
ElMessage.error('下载文件出现错误,请联系管理员!') ElMessage.error('下载文件出现错误,请联系管理员!')

View File

@ -57,11 +57,11 @@
<el-form-item label=""> <el-form-item label="">
<el-button type="primary" style="background-color: #7393b7; border-color: #7393b7; border-radius: 0" <el-button type="primary" style="background-color: #7393b7; border-color: #7393b7; border-radius: 0"
@click="onSearch"> @click="onSearch" :disabled="isTraining" :loading="isTraining">
<img src="@/assets/images/play.png" alt="" class="icon" />Start training <img src="@/assets/images/play.png" alt="" class="icon" />Start training
</el-button> </el-button>
<el-button type="primary" style="background-color: #7393b7; border-color: #7393b7; border-radius: 0" <el-button type="primary" style="background-color: #7393b7; border-color: #7393b7; border-radius: 0"
@click="onEnd"> @click="onEnd" :disabled="!isTraining">
<img src="@/assets/images/end.png" alt="" class="icon" />End training <img src="@/assets/images/end.png" alt="" class="icon" />End training
</el-button> </el-button>
</el-form-item> </el-form-item>
@ -192,8 +192,13 @@ export default {
label: 'RF', label: 'RF',
}, },
], ],
isTraining: false,
caseNo: '', caseNo: '',
timer: null, timer: null,
trainingStartTime: null,
maxTrainingDuration: 1800000, // 30
pollErrorCount: 0,
maxPollErrors: 5, //
chartData: { chartData: {
xAxisData: [], xAxisData: [],
seriesData: [] seriesData: []
@ -206,46 +211,82 @@ export default {
this.chart() this.chart()
this.getDataset() this.getDataset()
}, },
beforeUnmount() {
if (this.timer) {
clearInterval(this.timer)
this.timer = null
}
},
methods: { methods: {
getDataset() { getDataset() {
this.$axios.get(window.CONFIG.baseUrl + '/train-oneday/query_train_datasets', { params: { page: 1, size: 100 } }).then((res) => { // this.$axios.get(window.CONFIG.baseUrl + '/train-oneday/query_train_datasets', { params: { page: 1, size: 100 } }).then((res) => {
this.$axios.get(window.CONFIG.baseUrl + '/python-api/train-oneday/query_train_datasets', { params: { page: 1, size: 100 } }).then((res) => {
this.datasetIdOptions = res.data.items this.datasetIdOptions = res.data.items
}) })
}, },
onSearch() { onSearch() {
if (this.isTraining) return
this.isTraining = true
this.pollErrorCount = 0
this.trainingStartTime = Date.now()
if (this.myChart) { if (this.myChart) {
this.myChart.dispose() this.myChart.dispose()
this.chart() this.chart()
} }
this.getTrainingTime() this.getTrainingTime()
this.loading = true // this.$axios.post(window.CONFIG.baseUrl + '/train-oneday/train_models', this.queryParams, {
this.$axios.post(window.CONFIG.baseUrl + '/train-oneday/train_models', this.queryParams, { this.$axios.post(window.CONFIG.baseUrl + '/python-api/train-oneday/train_models', this.queryParams, {
timeout: this.maxTrainingDuration,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' } headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}).then((res) => { }).then((res) => {
if (res.case_no) { if (res.case_no) {
this.caseNo = res.case_no this.caseNo = res.case_no
} }
this.queryModalProcess() this.queryModalProcess()
}).finally(() => { }).catch(() => {
this.loading = false this.isTraining = false
}) })
}, },
onEnd() { onEnd() {
if (!this.isTraining) return
clearInterval(this.timer) clearInterval(this.timer)
this.timer = null
this.isTraining = false
this.trainingStartTime = null
}, },
// //
async getTrainingTime() { async getTrainingTime() {
const res = await this.$axios.get(window.CONFIG.baseUrl + '/train-oneday/query_training_time', { params: { dataset_id: this.queryParams.dataset_id, model_type: this.queryParams.model_types } }) // const res = await this.$axios.get(window.CONFIG.baseUrl + '/train-oneday/query_training_time', { params: { dataset_id: this.queryParams.dataset_id, model_type: this.queryParams.model_types } })
const res = await this.$axios.get(window.CONFIG.baseUrl + '/python-api/train-oneday/query_training_time', { params: { dataset_id: this.queryParams.dataset_id, model_type: this.queryParams.model_types } })
debugger debugger
}, },
queryModalProcess() { queryModalProcess() {
this.timer = setInterval(async () => { this.timer = setInterval(async () => {
// const res = await this.$axios.get(window.CONFIG.baseUrl + '/train-oneday/get_available_models', { params: { case_no: this.caseNo } }) //
const res = await this.$axios.get(window.CONFIG.baseUrl + '/train-oneday/query_train_cases', { params: { /*dataset_id: this.queryParams.dataset_id, model_type: this.queryParams.model_types,*/ case_no: this.caseNo, page: 1, size: 30 } }) if (this.trainingStartTime && (Date.now() - this.trainingStartTime > this.maxTrainingDuration)) {
clearInterval(this.timer)
this.timer = null
this.isTraining = false
this.trainingStartTime = null
this.$message.warning('训练已超过最大时长(30分钟),自动终止')
return
}
try {
// const res = await this.$axios.get(window.CONFIG.baseUrl + '/train-oneday/query_train_cases', {
const res = await this.$axios.get(window.CONFIG.baseUrl + '/python-api/train-oneday/query_train_cases', {
timeout: 30000,
params: { case_no: this.caseNo, page: 1, size: 30 }
})
this.pollErrorCount = 0
res.data.items.forEach((item, index) => { res.data.items.forEach((item, index) => {
if (item.model_type === 'CNN') { if (item.model_type === 'CNN') {
if (item.end_time) { if (item.end_time) {
clearInterval(this.timer) clearInterval(this.timer)
this.timer = null
this.isTraining = false
this.trainingStartTime = null
} }
if (item.loss) { if (item.loss) {
this.chartData.xAxisData.push(new Date().toLocaleString().replaceAll('/', '-')) this.chartData.xAxisData.push(new Date().toLocaleString().replaceAll('/', '-'))
@ -265,6 +306,17 @@ export default {
} }
] ]
}) })
} catch (err) {
this.pollErrorCount++
console.error('轮询训练状态失败:', err)
if (this.pollErrorCount >= this.maxPollErrors) {
clearInterval(this.timer)
this.timer = null
this.isTraining = false
this.trainingStartTime = null
this.$message.warning('连续多次查询训练状态失败,已自动终止')
}
}
}, 3000) }, 3000)
}, },
chart() { chart() {

View File

@ -76,7 +76,8 @@ export default {
methods: { methods: {
onSearch () { onSearch () {
this.loading = true this.loading = true
this.$axios.get(window.CONFIG.baseUrl + '/nuclide/query_samples', { params: this.queryParams }).then((res) => { // this.$axios.get(window.CONFIG.baseUrl + '/nuclide/query_samples', { params: this.queryParams }).then((res) => {
this.$axios.get(window.CONFIG.baseUrl + '/python-api/nuclide/query_samples', { params: this.queryParams }).then((res) => {
this.tableData = res.data.items this.tableData = res.data.items
this.total = res.data.pagination.total_count this.total = res.data.pagination.total_count
}).finally(() => { }).finally(() => {
@ -95,7 +96,8 @@ export default {
this.typeData[item.sample_id] = item.ev_type this.typeData[item.sample_id] = item.ev_type
} }
}) })
const res = await this.$axios.post(window.CONFIG.baseUrl + '/nuclide/batch_mark_samples', this.typeData) // const res = await this.$axios.post(window.CONFIG.baseUrl + '/nuclide/batch_mark_samples', this.typeData)
const res = await this.$axios.post(window.CONFIG.baseUrl + '/python-api/nuclide/batch_mark_samples', this.typeData)
this.$message.info(res.message) this.$message.info(res.message)
}, },
}, },

View File

@ -65,7 +65,8 @@ export default {
methods: { methods: {
onSearch () { onSearch () {
this.loading = true this.loading = true
this.$axios.get(window.CONFIG.baseUrl + '/nuclide/query_latest_samples').then((res) => { // this.$axios.get(window.CONFIG.baseUrl + '/nuclide/query_latest_samples').then((res) => {
this.$axios.get(window.CONFIG.baseUrl + '/python-api/nuclide/query_latest_samples').then((res) => {
debugger debugger
this.tableData = res.data.items this.tableData = res.data.items
this.total = res.data.pagination.total_count this.total = res.data.pagination.total_count

View File

@ -71,13 +71,15 @@ export default {
}, },
computed: { computed: {
uploadUrl () { uploadUrl () {
return window.CONFIG.baseUrl + '/train-oneday/upload_train_dataset' // return window.CONFIG.baseUrl + '/train-oneday/upload_train_dataset'
return window.CONFIG.baseUrl + '/python-api/train-oneday/upload_train_dataset'
} }
}, },
methods: { methods: {
onSearch () { onSearch () {
this.loading = true this.loading = true
this.$axios.get(window.CONFIG.baseUrl + '/train-oneday/query_train_datasets', { params: this.queryParams }).then((res) => { // this.$axios.get(window.CONFIG.baseUrl + '/train-oneday/query_train_datasets', { params: this.queryParams }).then((res) => {
this.$axios.get(window.CONFIG.baseUrl + '/python-api/train-oneday/query_train_datasets', { params: this.queryParams }).then((res) => {
this.tableData = res.data.items this.tableData = res.data.items
this.total = res.data.pagination.total_count this.total = res.data.pagination.total_count
}).finally(() => { }).finally(() => {
@ -111,7 +113,8 @@ export default {
// 使 axios // 使 axios
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this.$axios.post(window.CONFIG.baseUrl + '/train-oneday/upload_train_dataset', formData, { // this.$axios.post(window.CONFIG.baseUrl + '/train-oneday/upload_train_dataset', formData, {
this.$axios.post(window.CONFIG.baseUrl + '/python-api/train-oneday/upload_train_dataset', formData, {
headers: { headers: {
'Content-Type': 'multipart/form-data' 'Content-Type': 'multipart/form-data'
}, },

View File

@ -85,13 +85,15 @@ export default {
}, },
computed: { computed: {
uploadUrl () { uploadUrl () {
return window.CONFIG.baseUrl + '/nuclide/upload_nuclide_excel' // return window.CONFIG.baseUrl + '/nuclide/upload_nuclide_excel'
return window.CONFIG.baseUrl + '/python-api/nuclide/upload_nuclide_excel'
} }
}, },
methods: { methods: {
onSearch () { onSearch () {
this.loading = true this.loading = true
this.$axios.get(window.CONFIG.baseUrl + '/nuclide/query_samples', { params: this.queryParams }).then((res) => { // this.$axios.get(window.CONFIG.baseUrl + '/nuclide/query_samples', { params: this.queryParams }).then((res) => {
this.$axios.get(window.CONFIG.baseUrl + '/python-api/nuclide/query_samples', { params: this.queryParams }).then((res) => {
this.tableData = res.data.items this.tableData = res.data.items
this.total = res.data.pagination.total_count this.total = res.data.pagination.total_count
}).finally(() => { }).finally(() => {

View File

@ -411,7 +411,8 @@ export default {
}, },
methods: { methods: {
getData() { getData() {
this.$axios.get(window.CONFIG.baseUrl + '/nuclide/query_pollution_data', { params: { loc_id: 86 } }).then((res) => { // this.$axios.get(window.CONFIG.baseUrl + '/nuclide/query_pollution_data', { params: { loc_id: 86 } }).then((res) => {
this.$axios.get(window.CONFIG.baseUrl + '/python-api/nuclide/query_pollution_data', { params: { loc_id: 86 } }).then((res) => {
this.imgData.nrl = [] this.imgData.nrl = []
this.imgData.nuclearFacilities = [] this.imgData.nuclearFacilities = []
this.imgData.groudMonitoringStation = [] this.imgData.groudMonitoringStation = []

View File

@ -36,9 +36,27 @@
</div> </div>
<div class="chart-wrap" style="display: flex; gap: 10px; height: calc(100% - 50px);"> <div class="chart-wrap" style="display: flex; gap: 10px; height: calc(100% - 50px);">
<!-- 调整图表容器布局避免高度重叠 --> <!-- 调整图表容器布局避免高度重叠 -->
<div ref="chartDom" style="flex: 1; height: 100%"></div> <div style="flex: 1; display: flex; flex-direction: column; height: 100%;">
<div ref="chartDom2" style="flex: 1; height: 100%"></div> <div ref="chartDom" style="flex: 1;"></div>
<div ref="chartDom3" style="flex: 1; height: 100%"></div> <div style="text-align: center; padding: 6px 0;">
<el-button size="small" type="primary" icon="Download" @click="downloadChartData(1)"
style="background-color: #7393b7; border-color: #7393b7;">下载数据</el-button>
</div>
</div>
<div style="flex: 1; display: flex; flex-direction: column; height: 100%;">
<div ref="chartDom2" style="flex: 1;"></div>
<div style="text-align: center; padding: 6px 0;">
<el-button size="small" type="primary" icon="Download" @click="downloadChartData(2)"
style="background-color: #7393b7; border-color: #7393b7;">下载数据</el-button>
</div>
</div>
<div style="flex: 1; display: flex; flex-direction: column; height: 100%;">
<div ref="chartDom3" style="flex: 1;"></div>
<div style="text-align: center; padding: 6px 0;">
<el-button size="small" type="primary" icon="Download" @click="downloadChartData(3)"
style="background-color: #7393b7; border-color: #7393b7;">下载数据</el-button>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -108,7 +126,8 @@ export default {
}, },
methods: { methods: {
getDataset() { getDataset() {
this.$axios.get(window.CONFIG.baseUrl + '/train-oneday/query_train_datasets', { params: { page: 1, size: 100 } }) // this.$axios.get(window.CONFIG.baseUrl + '/train-oneday/query_train_datasets', { params: { page: 1, size: 100 } })
this.$axios.get(window.CONFIG.baseUrl + '/python-api/train-oneday/query_train_datasets', { params: { page: 1, size: 100 } })
.then((res) => { .then((res) => {
this.datasetIdOptions = res.data.items || [] this.datasetIdOptions = res.data.items || []
}) })
@ -116,7 +135,8 @@ export default {
}, },
async getCaseData(datasetId) { async getCaseData(datasetId) {
try { try {
const res = await this.$axios.get(window.CONFIG.baseUrl + '/train-oneday/query_train_cases', { // const res = await this.$axios.get(window.CONFIG.baseUrl + '/train-oneday/query_train_cases', {
const res = await this.$axios.get(window.CONFIG.baseUrl + '/python-api/train-oneday/query_train_cases', {
params: { dataset_id: datasetId, model_type: '', case_no: '', page: 1, size: 100 } params: { dataset_id: datasetId, model_type: '', case_no: '', page: 1, size: 100 }
}) })
this.caseOptions = this.removeDuplicatesByMap(res.data.items || []) this.caseOptions = this.removeDuplicatesByMap(res.data.items || [])
@ -160,7 +180,8 @@ export default {
// + // +
return { return {
legendName: item, legendName: item,
request: this.$axios.get(window.CONFIG.baseUrl + '/download', { params: { path: path } }) // request: this.$axios.get(window.CONFIG.baseUrl + '/download', { params: { path: path } })
request: this.$axios.get(window.CONFIG.baseUrl + '/python-api/download', { params: { path: path } })
} }
}) })
@ -295,6 +316,28 @@ export default {
this.myChart3 = this.$echarts.init(this.$refs.chartDom3) this.myChart3 = this.$echarts.init(this.$refs.chartDom3)
this.myChart3.setOption(this.initChartOption()) this.myChart3.setOption(this.initChartOption())
}, },
downloadChartData(chartIndex) {
const dataMap = {
1: this.chartData.seriesData,
2: this.chartData.seriesData2,
3: this.chartData.seriesData3
}
const data = dataMap[chartIndex]
if (!data || data.length === 0) {
this.$message.warning('暂无数据可下载')
return
}
const json = JSON.stringify(data, null, 2)
const blob = new Blob([json], { type: 'application/json' })
const url = URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = `chart${chartIndex}_data.json`
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
URL.revokeObjectURL(url)
},
} }
} }
</script> </script>

View File

@ -38,16 +38,16 @@
<el-upload ref="upload" v-model:file-list="fileList" class="upload-demo" :auto-upload="false" :limit="1" <el-upload ref="upload" v-model:file-list="fileList" class="upload-demo" :auto-upload="false" :limit="1"
:multiple="false" :show-file-list="false" :on-change="handleChange" :multiple="false" :show-file-list="false" :on-change="handleChange"
style="height: 32px; margin-left: 12px;"> style="height: 32px; margin-left: 12px;">
<el-button type="primary" icon="upload" <el-button type="primary" icon="upload" :disabled="loading"
style="background-color: #7393b7; border-color: #7393b7; border-radius: 0;">Upload</el-button> style="background-color: #7393b7; border-color: #7393b7; border-radius: 0;">Upload</el-button>
</el-upload> </el-upload>
<el-button type="primary" icon="search" <el-button type="primary" icon="search" :disabled="loading"
style="background-color: #7393b7; border-color: #7393b7; border-radius: 0; margin-left: 12px;" style="background-color: #7393b7; border-color: #7393b7; border-radius: 0; margin-left: 12px;"
@click="onSearch"> @click="onSearch">
<span v-if="!loading">Select</span> <span v-if="!loading">Select</span>
<span v-else>识别中...</span> <span v-else>识别中...</span>
</el-button> </el-button>
<el-button type="primary" icon="document" <el-button type="primary" icon="document" :disabled="loading"
style="background-color: #7393b7; border-color: #7393b7; border-radius: 0; margin-left: 12px;" style="background-color: #7393b7; border-color: #7393b7; border-radius: 0; margin-left: 12px;"
@click="onDownload">Download</el-button> @click="onDownload">Download</el-button>
</el-form-item> </el-form-item>
@ -124,7 +124,8 @@ export default {
formData.append("case_no", this.queryParams.case_no) formData.append("case_no", this.queryParams.case_no)
formData.append("model_types", this.queryParams.model_types) formData.append("model_types", this.queryParams.model_types)
// this.$axios.post(window.CONFIG.baseUrl + '/train-oneday/predict', formData, { headers: { "Content-Type": "multipart/form-data" } }).then((res) => { // this.$axios.post(window.CONFIG.baseUrl + '/train-oneday/predict', formData, { headers: { "Content-Type": "multipart/form-data" } }).then((res) => {
this.$axios.post(window.CONFIG.baseUrl + '/train-oneday/predict', formData, { timeout: 1800000, headers: { "Content-Type": "multipart/form-data" } }).then((res) => { // this.$axios.post(window.CONFIG.baseUrl + '/train-oneday/predict', formData, { timeout: 1800000, headers: { "Content-Type": "multipart/form-data" } }).then((res) => {
this.$axios.post(window.CONFIG.baseUrl + '/python-api/train-oneday/predict', formData, { timeout: 1800000, headers: { "Content-Type": "multipart/form-data" } }).then((res) => {
// this.chartData.dataset = res.echart_data // this.chartData.dataset = res.echart_data
// this.myChart.setOption({ // this.myChart.setOption({
// dataset: { // dataset: {
@ -133,17 +134,23 @@ export default {
// }) // })
console.log('Predict_output_path', res.output_path) console.log('Predict_output_path', res.output_path)
this.output_path = res?.output_path this.output_path = res?.output_path
this.$message.success('预测成功')
}).catch((err) => {
this.$message.error('请求失败:' + err.message)
console.error('接口错误:', err)
}).finally(() => { }).finally(() => {
this.loading = false this.loading = false
}) })
}, },
getDataset() { getDataset() {
this.$axios.get(window.CONFIG.baseUrl + '/train-oneday/query_train_datasets', { params: { page: 1, size: 100 } }).then((res) => { // this.$axios.get(window.CONFIG.baseUrl + '/train-oneday/query_train_datasets', { params: { page: 1, size: 100 } }).then((res) => {
this.$axios.get(window.CONFIG.baseUrl + '/python-api/train-oneday/query_train_datasets', { params: { page: 1, size: 100 } }).then((res) => {
this.datasetIdOptions = res.data.items this.datasetIdOptions = res.data.items
}) })
}, },
async getCaseData(datasetId) { async getCaseData(datasetId) {
const res = await this.$axios.get(window.CONFIG.baseUrl + '/train-oneday/query_train_cases', { params: { dataset_id: datasetId, model_type: '', case_no: '', page: 1, size: 100 } }) // const res = await this.$axios.get(window.CONFIG.baseUrl + '/train-oneday/query_train_cases', { params: { dataset_id: datasetId, model_type: '', case_no: '', page: 1, size: 100 } })
const res = await this.$axios.get(window.CONFIG.baseUrl + '/python-api/train-oneday/query_train_cases', { params: { dataset_id: datasetId, model_type: '', case_no: '', page: 1, size: 100 } })
this.caseOptions = this.removeDuplicatesByMap(res.data.items) this.caseOptions = this.removeDuplicatesByMap(res.data.items)
}, },
removeDuplicatesByMap(arr) { removeDuplicatesByMap(arr) {
@ -165,6 +172,7 @@ export default {
handleChange(file, fileList) { handleChange(file, fileList) {
if (file) { if (file) {
this.currentFile = file.raw || file this.currentFile = file.raw || file
this.$message.success('文件选择成功:' + (file.name || ''))
} else { } else {
this.currentFile = null this.currentFile = null
} }
@ -185,16 +193,24 @@ export default {
this.$message.warning('暂无下载文件!'); this.$message.warning('暂无下载文件!');
return false return false
} }
this.$axios.get(window.CONFIG.baseUrl + '/download', { params: { path: this.output_path }, responseType: 'blob', }).then(res => { // this.$axios.get(window.CONFIG.baseUrl + '/download', { params: { path: this.output_path }, responseType: 'blob', }).then(res => {
this.$axios.get(window.CONFIG.baseUrl + '/python-api/download', { params: { path: this.output_path }, responseType: 'blob', }).then(res => {
const downLoadName = 'pred.xlsx' const downLoadName = 'pred.xlsx'
// a // a
const a = document.createElement('a') const a = document.createElement('a')
a.href = URL.createObjectURL(res) const blobUrl = URL.createObjectURL(res)
a.href = blobUrl
// adownload // adownload
a.setAttribute('download', downLoadName) a.setAttribute('download', downLoadName)
document.body.appendChild(a) document.body.appendChild(a)
a.click() a.click()
// ablob URL
setTimeout(() => {
document.body.removeChild(a) document.body.removeChild(a)
URL.revokeObjectURL(blobUrl)
}, 200)
}).catch(err => {
this.$message.error('下载失败:' + (err.message || '未知错误'))
}) })
}, },
chart() { chart() {

View File

@ -31,16 +31,16 @@
<el-upload ref="upload" v-model:file-list="fileList" class="upload-demo" :auto-upload="false" :limit="1" <el-upload ref="upload" v-model:file-list="fileList" class="upload-demo" :auto-upload="false" :limit="1"
:multiple="false" :show-file-list="false" :on-change="handleChange" :multiple="false" :show-file-list="false" :on-change="handleChange"
style="height: 32px; margin-left: 12px;"> style="height: 32px; margin-left: 12px;">
<el-button type="primary" icon="upload" <el-button type="primary" icon="upload" :disabled="loading"
style="background-color: #7393b7; border-color: #7393b7; border-radius: 0;">Upload</el-button> style="background-color: #7393b7; border-color: #7393b7; border-radius: 0;">Upload</el-button>
</el-upload> </el-upload>
<el-button type="primary" icon="search" <el-button type="primary" icon="search" :disabled="loading"
style="background-color: #7393b7; border-color: #7393b7; border-radius: 0; margin-left: 12px;" style="background-color: #7393b7; border-color: #7393b7; border-radius: 0; margin-left: 12px;"
@click="onSearch"> @click="onSearch">
<span v-if="!loading">Select</span> <span v-if="!loading">Select</span>
<span v-else>识别中...</span> <span v-else>识别中...</span>
</el-button> </el-button>
<el-button type="primary" icon="document" <el-button type="primary" icon="document" :disabled="loading"
style="background-color: #7393b7; border-color: #7393b7; border-radius: 0; margin-left: 12px;" style="background-color: #7393b7; border-color: #7393b7; border-radius: 0; margin-left: 12px;"
@click="onDownload">Download</el-button> @click="onDownload">Download</el-button>
</el-form-item> </el-form-item>
@ -117,7 +117,7 @@ export default {
formData.append("model_types", this.queryParams.model_types) formData.append("model_types", this.queryParams.model_types)
this.$axios.post( this.$axios.post(
window.CONFIG.baseUrl + '/train-oneday/predict_with_label', window.CONFIG.baseUrl + '/python-api/train-oneday/predict_with_label',
formData, formData,
{ timeout: 1800000, headers: { "Content-Type": "multipart/form-data" } } { timeout: 1800000, headers: { "Content-Type": "multipart/form-data" } }
).then((res) => { ).then((res) => {
@ -125,6 +125,7 @@ export default {
this.output_path = res?.output_path this.output_path = res?.output_path
// 1. // 1.
this.chartData.datasetSource = res.echart_data || [] this.chartData.datasetSource = res.echart_data || []
this.$message.success('上传成功')
}).catch((err) => { }).catch((err) => {
this.$message.error('请求失败:' + err.message) this.$message.error('请求失败:' + err.message)
console.error('接口错误:', err) console.error('接口错误:', err)
@ -133,7 +134,7 @@ export default {
}) })
}, },
getDataset() { getDataset() {
this.$axios.get(window.CONFIG.baseUrl + '/train-oneday/query_train_datasets', { params: { page: 1, size: 100 } }) this.$axios.get(window.CONFIG.baseUrl + '/python-api/train-oneday/query_train_datasets', { params: { page: 1, size: 100 } })
.then((res) => { .then((res) => {
this.datasetIdOptions = res.data.items || [] this.datasetIdOptions = res.data.items || []
}).catch(err => { }).catch(err => {
@ -143,7 +144,7 @@ export default {
async getCaseData(datasetId) { async getCaseData(datasetId) {
try { try {
const res = await this.$axios.get( const res = await this.$axios.get(
window.CONFIG.baseUrl + '/train-oneday/query_train_cases', window.CONFIG.baseUrl + '/python-api/train-oneday/query_train_cases',
{ params: { dataset_id: datasetId, model_type: '', case_no: '', page: 1, size: 100 } } { params: { dataset_id: datasetId, model_type: '', case_no: '', page: 1, size: 100 } }
) )
this.caseOptions = this.removeDuplicatesByMap(res.data.items || []) this.caseOptions = this.removeDuplicatesByMap(res.data.items || [])
@ -169,6 +170,7 @@ export default {
handleChange(file, fileList) { handleChange(file, fileList) {
if (file) { if (file) {
this.currentFile = file.raw || file this.currentFile = file.raw || file
this.$message.success('文件选择成功:' + (file.name || ''))
} else { } else {
this.currentFile = null this.currentFile = null
} }
@ -182,17 +184,21 @@ export default {
return false return false
} }
this.$axios.get( this.$axios.get(
window.CONFIG.baseUrl + '/download', window.CONFIG.baseUrl + '/python-api/download',
{ params: { path: this.output_path }, responseType: 'blob' } { params: { path: this.output_path }, responseType: 'blob' }
).then(res => { ).then(res => {
const downLoadName = 'test.xlsx' const downLoadName = 'test.xlsx'
const a = document.createElement('a') const a = document.createElement('a')
a.href = URL.createObjectURL(res) // res.datablob const blobUrl = URL.createObjectURL(res)
a.href = blobUrl
a.setAttribute('download', downLoadName) a.setAttribute('download', downLoadName)
document.body.appendChild(a) document.body.appendChild(a)
a.click() a.click()
// ablob URL
setTimeout(() => {
document.body.removeChild(a) document.body.removeChild(a)
URL.revokeObjectURL(a.href) // URL URL.revokeObjectURL(blobUrl)
}, 200)
}).catch(err => { }).catch(err => {
this.$message.error('下载失败:' + err.message) this.$message.error('下载失败:' + err.message)
}) })

View File

@ -67,13 +67,15 @@ export default {
}, },
computed: { computed: {
uploadUrl () { uploadUrl () {
return window.CONFIG.baseUrl + '/weather/upload_grib_files' // return window.CONFIG.baseUrl + '/weather/upload_grib_files'
return window.CONFIG.baseUrl + '/python-api/weather/upload_grib_files'
} }
}, },
methods: { methods: {
onSearch () { onSearch () {
this.loading = true this.loading = true
this.$axios.get(window.CONFIG.baseUrl + '/weather/list_grib_files', { params: this.queryParams }).then((res) => { // this.$axios.get(window.CONFIG.baseUrl + '/weather/list_grib_files', { params: this.queryParams }).then((res) => {
this.$axios.get(window.CONFIG.baseUrl + '/python-api/weather/list_grib_files', { params: this.queryParams }).then((res) => {
this.tableData = res.files this.tableData = res.files
// this.total = res.data.pagination.total_count // this.total = res.data.pagination.total_count
}).finally(() => { }).finally(() => {

View File

@ -49,7 +49,8 @@ export default {
grid_halfwidth_deg: this.gridHalfwidthDeg grid_halfwidth_deg: this.gridHalfwidthDeg
} }
this.loading = true this.loading = true
const res = await this.$axios.post(window.CONFIG.baseUrl + '/nuclide-sim/calculate_atmospheric_stability', params, { // const res = await this.$axios.post(window.CONFIG.baseUrl + '/nuclide-sim/calculate_atmospheric_stability', params, {
const res = await this.$axios.post(window.CONFIG.baseUrl + '/python-api/nuclide-sim/calculate_atmospheric_stability', params, {
headers: { 'Content-Type': 'application/x-www-form-urlencoded' } headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}) })
this.loading = false this.loading = false
@ -66,7 +67,8 @@ export default {
} }
try { try {
this.loading = true this.loading = true
const res = await this.$axios.post(window.CONFIG.baseUrl + '/nuclide-sim/get_wind_temperature_pressure_data', params, { // const res = await this.$axios.post(window.CONFIG.baseUrl + '/nuclide-sim/get_wind_temperature_pressure_data', params, {
const res = await this.$axios.post(window.CONFIG.baseUrl + '/python-api/nuclide-sim/get_wind_temperature_pressure_data', params, {
headers: { 'Content-Type': 'application/x-www-form-urlencoded' } headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}) })
this.loading = false this.loading = false

1
test Normal file
View File

@ -0,0 +1 @@
_psycopg.cpython-311-x86_64-linux-gnu.so: undefined symbol: lo_truncate64

View File

@ -43,7 +43,7 @@ export default defineConfig(({ mode, command }) => {
}, },
// vite 相关配置 // vite 相关配置
server: { server: {
port: 80, port: 90,
host: '0.0.0.0', host: '0.0.0.0',
open: false, open: false,
proxy: { proxy: {