Add initial files for Audio Dashboard Management System

- Created .env.example for environment variable configuration.
- Added docker-compose.yml for service orchestration.
- Implemented frequency response extraction in extract_frequency_response.py and convert_to_frequency_db.py.
- Generated output files: frequency_response_detailed.json, frequency_response_points.json, frequency_response.csv, and frequency_response_curve.png.
- Included sample measurement data for FiiO FA19 in CSV format.
This commit is contained in:
yangy
2026-03-17 14:20:08 +08:00
parent 75b1d16453
commit 90aec37461
25 changed files with 7570 additions and 47 deletions
+13 -8
View File
@@ -29,26 +29,31 @@ export function getModel(id) {
/**
* 创建型号
* @param {Object} data - 型号数据
* @param {Object} data - 型号数据或 FormData
* @param {Object} config - 额外配置
* @param {boolean} config.isFormData - 是否为 FormData 上传
*/
export function createModel(data) {
export function createModel(data, config = {}) {
return request({
url: '/models/',
method: 'post',
data
data,
headers: config.isFormData ? { 'Content-Type': 'multipart/form-data' } : {}
})
}
/**
* 更新型号
* @param {Object} data - 型号数据
* @param {number} data.id - 型号 ID
* @param {Object} data - 型号数据或 FormData
* @param {Object} config - 额外配置
* @param {boolean} config.isFormData - 是否为 FormData 上传
*/
export function updateModel(data) {
export function updateModel(data, config = {}) {
return request({
url: `/models/${data.id}`,
url: `/models/${data.id || data.get('id')}`,
method: 'put',
data
data,
headers: config.isFormData ? { 'Content-Type': 'multipart/form-data' } : {}
})
}
+77 -16
View File
@@ -80,7 +80,7 @@
</template>
</el-table-column>
<el-table-column prop="rig" label="阻抗" width="120" />
<el-table-column prop="eq_key" label="EQ 配置" width="150" show-overflow-tooltip />
<el-table-column prop="source" label="来源" width="150" show-overflow-tooltip />
<el-table-column prop="create_at" label="创建时间" width="180" />
<el-table-column label="操作" width="200" fixed="right">
<template #default="scope">
@@ -177,12 +177,27 @@
maxlength="100"
/>
</el-form-item>
<el-form-item label="EQ 键" prop="eq_key">
<el-input
v-model="formData.eq_key"
placeholder="EQ 配置键值"
maxlength="255"
/>
<el-form-item label="频响文件" prop="measurement_file">
<el-upload
ref="uploadRef"
:auto-upload="false"
:on-change="handleFileChange"
:on-remove="handleFileRemove"
:file-list="fileList"
:limit="1"
accept=".csv,.txt,.json"
drag
>
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
<div class="el-upload__text">
拖拽文件到此处或<em>点击上传</em>
</div>
<template #tip>
<div class="el-upload__tip">
支持 csv/txt/json 格式保留原文件名
</div>
</template>
</el-upload>
</el-form-item>
</el-form>
<template #footer>
@@ -198,7 +213,7 @@
<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Search, Refresh, Plus, Upload } from '@element-plus/icons-vue'
import { Search, Refresh, Plus, Upload, UploadFilled } from '@element-plus/icons-vue'
import { getModels, createModel, updateModel, deleteModel, pushToMeilisearch } from '@/api/model'
import { getBrands } from '@/api/brand'
@@ -208,8 +223,11 @@ const pushLoading = ref(false)
const dialogVisible = ref(false)
const dialogTitle = ref('新型号')
const formRef = ref(null)
const uploadRef = ref(null)
const brandOptions = ref([])
const selectedIds = ref([])
const fileList = ref([])
const uploadedFile = ref(null)
const searchForm = reactive({
brand_name: '',
@@ -244,6 +262,20 @@ const formRules = {
]
}
// 处理文件变化
const handleFileChange = (file) => {
uploadedFile.value = file.raw
fileList.value = [file]
// 自动填写来源为 Eafonyoung
formData.source = 'Eafonyoung'
}
// 处理文件移除
const handleFileRemove = () => {
uploadedFile.value = null
fileList.value = []
}
// 加载品牌列表
const loadBrands = async () => {
try {
@@ -353,15 +385,39 @@ const handleSubmit = async () => {
if (valid) {
submitLoading.value = true
try {
const api = formData.id ? updateModel : createModel
const res = await api(formData)
if (res.code === 1) {
ElMessage.success(formData.id ? '更新成功' : '创建成功')
dialogVisible.value = false
loadData()
// 如果有文件,使用 FormData 上传
if (uploadedFile.value) {
const formDataUpload = new FormData()
formDataUpload.append('brand_name', formData.brand_name)
formDataUpload.append('name', formData.name)
formDataUpload.append('form', formData.form)
formDataUpload.append('rig', formData.rig)
formDataUpload.append('source', formData.source)
formDataUpload.append('eq_key', formData.eq_key || '')
formDataUpload.append('measurement_file', uploadedFile.value)
const api = formData.id ? updateModel : createModel
const res = await api(formDataUpload, { isFormData: true })
if (res.code === 1) {
ElMessage.success(formData.id ? '更新成功' : '创建成功')
dialogVisible.value = false
loadData()
} else {
ElMessage.error(res.msg || '操作失败')
}
} else {
ElMessage.error(res.msg || '操作失败')
// 没有文件,使用普通 JSON 提交
const api = formData.id ? updateModel : createModel
const res = await api(formData)
if (res.code === 1) {
ElMessage.success(formData.id ? '更新成功' : '创建成功')
dialogVisible.value = false
loadData()
} else {
ElMessage.error(res.msg || '操作失败')
}
}
} catch (error) {
console.error('操作失败:', error)
@@ -382,9 +438,14 @@ const handleDialogClose = () => {
formData.rig = ''
formData.source = ''
formData.eq_key = ''
uploadedFile.value = null
fileList.value = []
if (formRef.value) {
formRef.value.resetFields()
}
if (uploadRef.value) {
uploadRef.value.clearFiles()
}
}
// 分页变化