页面优化

This commit is contained in:
yangy
2026-04-22 14:34:23 +08:00
parent 93375b8b9f
commit cd2e2de6d8
7 changed files with 5 additions and 2705 deletions
+1 -1
View File
@@ -35,7 +35,7 @@ export default function BottomNav() {
return (
<nav
className="fixed bottom-0 left-0 right-0 z-50 lg:hidden"
className="fixed bottom-0 left-0 right-0 z-50"
style={{
background: "rgba(10, 10, 12, 0.96)",
backdropFilter: "blur(40px) saturate(200%)",
-48
View File
@@ -1,48 +0,0 @@
class Coeff{
constructor() {
this.b0 = 0;
this.b1 = 0;
this.b2 = 0;
this.a0 = 0;
this.a1 = 0;
this.a2 = 0;
}
setB0(value){
this.b0 = value;
}
setB1(value){
this.b1 = value;
}
setB2(value){
this.b2 = value;
}
setA0(value){
this.a0 = value;
}
setA1(value){
this.a1 = value;
}
setA2(value){
this.a2 = value;
}
getSectionsMatrix(gain, fc, bw, type, bypass, fs){
const w = 2 * fc / fs;
const q = fc / bw;
const bypassStatus = bypass ? 1 : 0;
const bqtype = type + bypassStatus * 10;
const sA = Math.pow(10, gain / 40);
const sqrt_sA = Math.sqrt(sA);
const sin_w = Math.sin(Math.PI * w);
const cos_w = Math.cos(Math.PI * w);
const alpha = sin_w / (2 * q);
let b0, b1, b2, a0, a1, a2;
}
}
-512
View File
@@ -1,512 +0,0 @@
import * as echarts from 'echarts'
export const TYPE_PEAK = 0;
export const TYPE_LOWSHELF = 1;
export const TYPE_HIGHSHELF = 2;
export const TYPE_LOWPASS = 3;
export const TYPE_HIGHPASS = 4;
export const TYPE_BANDPASS = 5;
export const TYPE_NOTCH = 6;
export const TYPE_ALLPASS = 7;
export const LPF_1ST = 8;
// Audio bean
export class AudioBean {
constructor(gain, fc, fs, type, bypass, q) {
this.gain = gain;
this.fc = fc;
this.fs = fs;
this.type = type;
this.bypass = bypass;
this.q = q;
}
getGain(){return this.gain;}
getFc(){return this.fc;}
getFs(){return this.fs;}
getType(){return this.type;}
getBypass(){return this.bypass;}
getQ(){return this.q;}
setGain(gain){this.gain = gain;}
setFc(fc){this.fc = fc;}
setFs(fs){this.fs = fs;}
setType(type){this.type = type;}
setBypass(bypass){this.bypass = bypass;}
setQ(q){this.q = q;}
toString(){
return "AudioTunningEQ [gain=" + this.gain + ", fc=" + this.fc + ", fs=" + this.fs + ", type=" + this.type + ", bypass=" + this.bypass + ", q=" + this.q + "]";
}
}
//Coeff bean
class Coeff {
constructor(props) {
this.b0 = 0;
this.b1 = 0;
this.b2 = 0;
this.a0 = 0;
this.a1 = 0;
this.a2 = 0;
}
setB0(b0) {this.b0 = b0;}
setB1(b1) {this.b1 = b1;}
setB2(b2) {this.b2 = b2;}
setA0(a0) {this.a0 = a0;}
setA1(a1) {this.a1 = a1;}
setA2(a2) {this.a2 = a2;}
getB0(){return this.b0;}
getB1(){return this.b1;}
getB2(){return this.b2;}
getA0(){return this.a0;}
getA1(){return this.a1;}
getA2(){return this.a2;}
toString() {
}
}
//Complex bean
class Complex {
constructor(real, image) {
this.real = real;
this.image = image;
}
getReal() {return this.real;}
getImage() {return this.image;}
setReal(real) {this.real = real;}
setImage(image) {this.image = image;}
add(a) {
return new Complex(this.real + a.real, this.image + a.image);
}
sub(a) { // 复数相减
return new Complex(this.real - a.real, this.image - a.image);
}
div(a) { // 复数相除
const denominator = a.real * a.real + a.image * a.image;
const newReal = (this.real * a.real + this.image * a.image) / denominator;
const newImage = (this.image * a.real - this.real * a.image) / denominator;
return new Complex(newReal, newImage);
}
mul(a) { // 复数相乘
const newReal = this.real * a.real - this.image * a.image;
const newImage = this.image * a.real + this.real * a.image;
return new Complex(newReal, newImage);
}
mulScalar(a) { // 复数与实数相乘
return new Complex(this.real * a, this.image * a);
}
addScalar(a) { // 复数与实数相加
return new Complex(this.real + a, this.image);
}
}
function getFreqznList(coeffList, fs, f) {
let n = f.length;
let h = new Array(n);
for (let i = 0; i < n; i++) {
let w = 2*Math.PI*(f[i])/fs;
let complex = getFreqwList(coeffList, w);
h[i] = 20*Math.log10(Math.abs(getAmplitude(complex)));
}
return h;
}
function getFreqzn(coeff, fs, f) {
let n = f.length;
let h = new Array(n);
for (let i = 0; i < n; i++) {
let w = 2*Math.PI*(f[i])/fs;
let complex = getFreqw(coeff, w);
h[i] = 20*Math.log10(Math.abs(getAmplitude(complex)));
}
return h;
}
function getAmplitude(complex) {
return Math.sqrt(Math.pow(complex.getReal(),2)+Math.pow(complex.getImage(),2));
}
function getFreqw(coeff, w) {
const complex = new Complex(Math.cos(w), -Math.sin(w));
const b2 = (complex.mul(complex)).mulScalar(coeff.getB2());
const b1 = complex.mulScalar(coeff.getB1());
const hup = b2.add(b1).addScalar(coeff.getB0());
const a2 = (complex.mul(complex)).mulScalar(coeff.getA2());
const a1 = complex.mulScalar(coeff.getA1());
const hdown = a2.add(a1).addScalar(coeff.getA0());
return hup.div(hdown);
}
function getFreqwList(coeffList, w){
let h = getFreqw(coeffList[0], w);
coeffList.slice(1).forEach((item) => {
h = h.mul(getFreqw(item, w));
});
return h;
}
function test(fc, q) {
let w = fc * 2 / (48000*1000);
let down = Math.sqrt(Math.pow((1 - w * w), 2) + w * w / (q * q));
let gain = 1 / down;
let db = 20 * Math.log10(gain);
return db;
}
export function visualizeResponse(coeffList, fs) {
let validCoeffList = []
let n = 349
let startF = 20
let endF = 20000
let logStep = (Math.log10(20000) - Math.log10(20)) / n
let f = new Array(n)
let step = Math.pow(10, logStep)
for (let i = 0; i < n; i++) {
f[i] = startF * Math.pow(step, i)
}
let semilogf = new Array(n)
// 注意:此函数逻辑不能改动,保持与原项目一致,仅计算前 200 个点
for (let i = 0; i < 200; i++) {
semilogf[i] = Math.log10(f[i])
}
let xValues = []
let yValues = []
let titleList = []
coeffList.forEach((coeff, i) => {
if (
!Number.isNaN(coeff.getB0()) &&
!Number.isNaN(coeff.getB1()) &&
!Number.isNaN(coeff.getB2()) &&
!Number.isNaN(coeff.getA0()) &&
!Number.isNaN(coeff.getA1()) &&
!Number.isNaN(coeff.getA2())
) {
validCoeffList.push(coeff)
let h = getFreqzn(coeff, fs, f)
xValues.push(semilogf)
yValues.push(h)
titleList.push('Band' + i)
}
})
if (yValues.length > 1) {
let overall = getFreqznList(validCoeffList, fs, f)
xValues.push(semilogf)
yValues.push(overall)
titleList.push('overall')
}
let testArray = new Array(n)
for (let i = 0; i < f.length; i++) {
testArray[i] = test(f[i], 1)
}
return [xValues[xValues.length - 1], yValues[yValues.length - 1]]
}
export function getSectionsMatrix(gain, fc, q, type, bypass, fs) {
let w = 2*fc/fs;
let bypassStatus = bypass ? 1 : 0;
let bqtype = type + bypassStatus * 10;
const sA = Math.pow(10, gain / 40);
const sqrt_sA = Math.sqrt(sA);
const sin_w = Math.sin(Math.PI * w);
const cos_w = Math.cos(Math.PI * w);
const alpha = sin_w / (2*q);
let b0, b1, b2, a0, a1, a2;
switch (bqtype){
case TYPE_PEAK:
b0 = 1 + alpha * sA;
b1 = -2 * cos_w;
b2 = 1 - alpha * sA;
a0 = 1 + alpha / sA;
a1 = b1;
a2 = 1 - alpha / sA;
break;
case TYPE_LOWSHELF:
b0 = sA * ((sA + 1) - (sA - 1) * cos_w + 2 * sqrt_sA * alpha);
b1 = 2 * sA * ((sA - 1) - (sA + 1) * cos_w);
b2 = sA * ((sA + 1) - (sA - 1) * cos_w - 2 * sqrt_sA * alpha);
a0 = (sA + 1) + (sA - 1) * cos_w + 2 * sqrt_sA * alpha;
a1 = -2 * ((sA - 1) + (sA + 1) * cos_w);
a2 = (sA + 1) + (sA - 1) * cos_w - 2 * sqrt_sA * alpha;
break;
case TYPE_HIGHSHELF:
b0 = sA * ((sA + 1) + (sA - 1) * cos_w + 2 * sqrt_sA * alpha);
b1 = -2 * sA * ((sA - 1) + (sA + 1) * cos_w);
b2 = sA * ((sA + 1) + (sA - 1) * cos_w - 2 * sqrt_sA * alpha);
a0 = (sA + 1) - (sA - 1) * cos_w + 2 * sqrt_sA * alpha;
a1 = 2 * ((sA - 1) - (sA + 1) * cos_w);
a2 = (sA + 1) - (sA - 1) * cos_w - 2 * sqrt_sA * alpha;
break;
case TYPE_LOWPASS:
b0 = (1 - cos_w) / 2;
b1 = 1 - cos_w;
b2 = b0;
a0 = 1 + alpha;
a1 = -2 * cos_w;
a2 = 1 - alpha;
break;
case TYPE_HIGHPASS:
b0 = (1 + cos_w) / 2;
b1 = -(1 + cos_w);
b2 = b0;
a0 = 1 + alpha;
a1 = -2 * cos_w;
a2 = 1 - alpha;
break;
case TYPE_BANDPASS:
b0 = alpha;
b1 = 0;
b2 = -alpha;
a0 = 1 + alpha;
a1 = -2 * cos_w;
a2 = 1 - alpha;
break;
case TYPE_NOTCH:
b0 = 1;
b1 = -2 * cos_w;
b2 = 1;
a0 = 1 + alpha;
a1 = -2 * cos_w;
a2 = 1 - alpha;
break;
case TYPE_ALLPASS:
b0 = 1 - alpha;
b1 = -2 * cos_w;
b2 = 1 + alpha;
a0 = b2;
a1 = b1;
a2 = b0;
break;
case LPF_1ST:
let alpha_1st = sin_w / (cos_w + 1);
b0 = alpha_1st / (1 + alpha_1st);
b1 = b0;
b2 = 0;
a0 = 1;
a1 = (alpha_1st - 1) / (1 + alpha_1st);
a2 = 0;
break;
default:
b0 = 1;
b1 = 0;
b2 = 0;
a0 = 1;
a1 = 0;
a2 = 0;
break;
}
let coeff = new Coeff();
coeff.setB0(b0/a0);
coeff.setB1(b1/a0);
coeff.setB2(b2/a0);
coeff.setA0(a0/a0);
coeff.setA1(a1/a0);
coeff.setA2(a2/a0);
return coeff;
}
export function getFilterShortName(type){
switch (type){
case "LOW_PASS": return "LPF";
case "HIGH_PASS": return "HPF";
case "BAND_PASS": return "BPF";
case "LOW_SHELF": return "LSHELF";
case "HIGH_SHELF": return "HSHELF";
case "ALL_PASS": return "APF";
case "PEAKING": return "PEAK";
default: return type;
}
}
function getFilterTypeName(val){
switch(val){
case TYPE_LOWPASS: return "LPF";
case TYPE_HIGHPASS: return "HPF";
case TYPE_BANDPASS: return "BPF";
case TYPE_NOTCH: return "NOTCH";
case TYPE_PEAK: return "PEAK";
case TYPE_LOWSHELF: return "LSHELF";
case TYPE_HIGHSHELF: return "HSHELF";
case TYPE_ALLPASS: return "APF";
}
}
export function getFilterType(typeName) {
if(typeName === 'LPF' || typeName === 'LOWP_ASS'){
return TYPE_LOWPASS;
}
else if(typeName === 'HPF' || typeName === 'HIGH_PASS'){
return TYPE_HIGHPASS;
}
else if(typeName === 'BPF' || typeName === 'BAND_PASS'){
return TYPE_BANDPASS;
}
else if(typeName === 'NOTCH'){
return TYPE_NOTCH;
}
else if(typeName === 'PEAK' || typeName === 'PEAKING'){
return TYPE_PEAK;
}
else if(typeName === 'LSHELF' || typeName === 'LOW_SHELF'){
return TYPE_LOWSHELF;
}
else if(typeName === 'HSHELF' || typeName === 'HIGH_SHELF'){
return TYPE_HIGHSHELF;
}
else if(typeName === 'APF' || typeName === 'ALL_PASS'){
return TYPE_ALLPASS;
}
}
export function getChartOps(dataSet, yMax, yMin, lineColor) {
//要显示的x轴刻度
const labelsToShow = [0, 43, 85, 116, 160, 200, 233, 281, 320, 348]
return {
xAxis: {
type: 'category',
data: dataSet[0],
axisLabel: {
formatter: function (value, index) {
// 指定只显示 index 在(04793115)的标签
if (labelsToShow.includes(index)) {
switch (index) {
case 0:
return '20'
case 43:
return '50'
case 85:
return '100'
case 116:
return '200'
case 160:
return '500'
case 200:
return '1K'
case 233:
return '2K'
case 281:
return '5K'
case 320:
return '10K'
case 348:
return '20K'
}
}
},
interval: function (index) {
return labelsToShow.includes(index)
},
fontSize: 14,
color: '#999'
},
splitLine: {
show: true,
lineStyle: {
type: 'solid',
color: '#3A4348'
}
},
axisLine: {
lineStyle: {
color: '#3A4348'
}
}
},
yAxis: {
type: 'value',
min: yMin,
max: yMax,
interval: 5,
axisLabel: {
fontSize: 14,
color: '#999'
},
splitLine: {
show: true,
lineStyle: {
type: 'solid',
color: '#3A4348'
}
},
axisLine: {
lineStyle: {
color: '#3A4348'
}
}
},
legend: {
show: true,
top: 15,
data: [
{
name: 'Equalizer',
icon: 'circle',
textStyle: { color: lineColor }, // 单独设置颜色
itemStyle: {
color: lineColor, // 设置图标颜色
borderColor: lineColor // 如果需要边框
}
},
{
name: 'Raw',
icon: 'circle',
textStyle: { color: '#ffffff' },
itemStyle: {
color: '#ffffff', // 设置图标颜色
borderColor: '#ffffff' // 如果需要边框
}
},
{
name: 'Equalized',
icon: 'circle',
textStyle: { color: '#23d2fe' },
itemStyle: {
color: '#23d2fe', // 设置图标颜色
borderColor: '#23d2fe' // 如果需要边框
}
}
],
textStyle: {
fontSize: 13
}
},
series: [
{
name: 'Equalizer',
data: dataSet[1],
type: 'line',
showSymbol: false,
lineStyle: {
color: lineColor
},
areaStyle: {
opacity: 0.3,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#578400' },
{
offset: 1,
color: '#578400'
}
])
}
}
]
}
}
-314
View File
@@ -1,314 +0,0 @@
import axios from 'axios'
import { base64DecodedToString, base64Encoded, PEQAPI, setProperty, UPGRADEPEQ } from '@/api/common.js'
import { ref } from 'vue'
import {
AudioBean,
getChartOps,
getFilterType,
getSectionsMatrix,
visualizeResponse
} from '@/api/audio.js'
import * as echarts from 'echarts'
import { i18n } from '@/main.js'
import { ElMessageBox } from 'element-plus'
export const getPeqData = async () => {
const peqItems = ref([])
const peqSelect = ref(0)
const resp = await axios.get(PEQAPI)
const peqEnable = ref(0)
const msgCount = ref(0);
const data = JSON.parse(base64DecodedToString(resp.data));
console.log('peq 数据=', data);
if(data.peq.length > 0){
data.peq.forEach((item, index) => {
item['index'] = index
item['filters'] = JSON.parse(item.filters)
})
peqItems.value = data.peq
peqSelect.value = data.peqSelect
}
peqEnable.value = data.peqEnable
msgCount.value = data.msgCount
return {
peqItems,
peqSelect,
peqEnable,
msgCount
}
}
export function changePeq(val, peqItems) {
setProperty('peqSelect', val)
const selectedItem = peqItems.find((item) => item.index === val)
if (selectedItem) {
console.log('选中了:' + selectedItem.name + ' filters = ' + selectedItem.filters)
}
return true
}
export const renderCharts = (peq, raw, changeParam) => {
const list = []
const fs = 48000
peq.filters.forEach((item) => {
const bean = new AudioBean(item.gain, item.fc, fs, getFilterType(item.type), false, item.q)
list.push(
getSectionsMatrix(
bean.getGain(),
bean.getFc(),
bean.getQ(),
bean.getType(),
bean.getBypass(),
bean.getFs()
)
)
})
const dataSet = visualizeResponse(list, fs)
const ops = getChartOps(dataSet, 20, -20, '#FFED00')
// 统一获取DOM元素
const chartDom = document.getElementById('main')
// 尝试获取已存在的实例
let myChart = echarts.getInstanceByDom(chartDom)
// 如果实例不存在,则初始化
if (!myChart) {
myChart = echarts.init(chartDom)
}
if (changeParam && myChart) {
// 只有在changeParam为true且图表存在时才获取原始数据
raw = myChart.getOption().series[1].data
}
// 不再重新初始化,直接使用现有的myChart实例
myChart.clear()
if (raw) {
ops.series.push({
name: 'Raw',
data: raw,
type: 'line',
showSymbol: false,
lineStyle: {
color: '#ffffff'
}
})
const equalized_raw = dataSet[1].map((value, index) => value + raw[index])
ops.series.push({
name: 'Equalized',
data: equalized_raw,
type: 'line',
showSymbol: false,
lineStyle: {
color: '#23d2fe',
width: 6,
opacity: 0.7
}
})
}
myChart.setOption(ops, true)
}
/**
* 切换auto开关
* @param peq
*/
export const upgradeAutoPre = (peq, autoPre) => {
const filters = peq.filters.map((item) => ({
type: getFilterVal(item.type),
fc: item.fc,
gain: item.gain,
q: item.q
}))
const data = {
peqChange: {
name: peq.name,
filters: filters,
autoPre: autoPre ? 1 : 0,
preamp: peq.preamp,
canDel: peq.canDel
}
}
upgradePeq(data)
peq.autoPre = autoPre ? 1 : 0
}
//修改总增益
export const upgradePreamp = (peq, preamp) => {
const filters = peq.filters.map((item) => ({
type: getFilterVal(item.type),
fc: item.fc,
gain: item.gain,
q: item.q
}))
const data = {
peqChange: {
name: peq.name,
filters: filters,
autoPre: peq.autoPre,
preamp: preamp,
canDel: peq.canDel
}
}
upgradePeq(data)
peq.preamp = preamp
}
export const upgradeEdit = (peq) => {
const filters = peq.filters.map((item) => ({
type: getFilterVal(item.type),
fc: item.fc,
gain: item.gain,
q: item.q
}))
const data = {
peqChange: {
name: peq.name,
filters: filters,
autoPre: peq.autoPre,
preamp: peq.preamp,
canDel: peq.canDel
}
}
upgradePeq(data)
}
//这里有个问题,当接口超时时,由于代码是同步,所以会一直阻塞等待
export const upgradePeq = async (peq) => {
await axios.post(
UPGRADEPEQ,
{ json: base64Encoded(JSON.stringify(peq)) },
{ headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' } }
)
}
export const getFilterVal = (filterName) => {
let result = -1
if (filterName === 'HIGH_PASS' || filterName === 'HPF') {
result = 1
} else if (filterName === 'BAND_PASS' || filterName === 'BPF') {
result = 2
} else if (filterName === 'NOTCH') {
result = 3
} else if (filterName === 'PEAKING' || filterName === 'PEAK') {
result = 4
} else if (filterName === 'LOW_SHELF' || filterName === 'LSHELF') {
result = 5
} else if (filterName === 'HIGH_SHELF' || filterName === 'HSHELF') {
result = 6
} else if (filterName === 'ALL_PASS' || filterName === 'APF') {
result = 7
} else if (filterName === 'LOW_PASS' || filterName === 'LPF') {
result = 0
}
return result
}
/**
* 改变滤波器的属性(频率,gain,q, 类型)
* @param currentFilter 当前选中的滤波器
* @param val 值
*/
export const changeFilterVal = (currentFilter, val, name, peq) => {
//currentFilter !== undefined 表示当前有某一个滤波器被选中,才需要更新下面的值
if (currentFilter !== undefined) {
if (name === 'freq') {
currentFilter.fc = val
} else if (name === 'gain') {
currentFilter.gain = val
} else if (name === 'q') {
currentFilter.q = val
} else if (name === 'type') {
currentFilter.type = val
}
//调用接口,更新peq
//需要将滤波器类型转换为数字,因为是引用类型,所以这里还需要遍历filters,声明新的filters,将值传过去,不能直接用peq.filters
const filters = peq.filters.map((item) => ({
type: getFilterVal(item.type),
fc: item.fc,
gain: item.gain,
q: item.q
}))
const data = {
peqChange: {
name: peq.name,
filters: filters,
autoPre: peq.autoPre,
preamp: peq.preamp,
canDel: peq.canDel
}
}
upgradePeq(data)
renderCharts(peq)
}
}
/**
* 渲染添加耳机型号窗口数据
*/
export const renderAddHeadPhone = () => {
const menus = [
{ value: 'Brands', label: 'Brands' },
{ value: 'Models', label: 'Models' },
{ value: 'Target', label: 'Target' }
]
const selectedMenu = ref('Brands')
const targetList = ref([
{ name: 'Harman over-ear 2018', bassBoost: { fc: 105, q: 0.7, gain: 6 } , ear: 'over'},
{ name: 'HMS II.3 Harman over-ear 2018', bassBoost: { fc: 105, q: 0.7, gain: 6 }, ear: 'over'},
{ name: 'crinacle EARS + 711 Harman over-ear 2018', bassBoost: { fc: 105, q: 0.7, gain: 6 } , ear: 'over'},
{ name: 'Harman in-ear 2019', bassBoost: { fc: 105, q: 0.7, gain: 9.5 } ,ear: 'in'},
{ name: 'AutoEq in-ear', bassBoost: { fc: 105, q: 0.7, gain: 8 }, ear: 'in'},
{ name: 'HMS II.3 AutoEq in-ear', bassBoost: { fc: 105, q: 0.7, gain: 8 } ,ear: 'in'},
{ name: 'HMS II.3 Harman in-ear 2019', bassBoost: { fc: 105, q: 0.7, gain: 9.5 } ,ear: 'in'},
{ name: 'Diffuse Field 5128 (-1 dB/oct)', bassBoost: { fc: 105, q: 0.7, gain: 0 }, ear: 'over'},
{ name: 'LMG 5128 0.6 without bass', bassBoost: { fc: 105, q: 0.7, gain: 6 } ,ear: 'over'},
{ name: 'JM-1 with Harman filters', bassBoost: { fc: 105, q: 0.7, gain: 6.5 } ,ear: 'all'},
{ name: 'oratory1990 in-ear', bassBoost: { fc: 105, q: 0.7, gain: 9.5 } ,ear: 'in'},
{ name: 'oratory1990 over-ear', bassBoost: { fc: 105, q: 0.7, gain: 6 } ,ear: 'over'},
{ name: 'Harman over-ear 2013', bassBoost: { fc: 105, q: 0.7, gain: 6 } ,ear: 'over'},
{ name: 'Flat', bassBoost: { fc: 105, q: 0.7, gain: 0 } ,ear: 'all'}
]);
return { menus, selectedMenu, targetList }
}
export const getCurve = async (brand, name, target) =>{
const resp = await axios.get('//api.luxsin.com.cn/audio/getCurve?brand='+encodeURIComponent(brand)+'&name='+encodeURIComponent(name)+'&target='+encodeURIComponent(target));
const data = JSON.parse(base64DecodedToString(resp.data));
if(data.hasOwnProperty('parametric_eq')) {
return data.parametric_eq;
}
return null;
};
export const getModelCurve = async (brand, name) => {
const resp = await axios.get(
'//api.luxsin.com.cn/audio/modelCurve?brand=' +
encodeURIComponent(brand) +
'&name=' +
encodeURIComponent(name)
)
const data = JSON.parse(base64DecodedToString(resp.data))
console.log('型号的原始数据:', data)
if (data.hasOwnProperty('fr')) {
return data.fr
}
return null
}
export const msg = (context) => {
ElMessageBox.alert(context, i18n.global.t('prompt.prompt'), {
confirmButtonText: i18n.global.t('prompt.confirm')
})
}
File diff suppressed because it is too large Load Diff
+2
View File
@@ -7,6 +7,7 @@
============================================================ */
import { useDevice } from "@/contexts/DeviceContext";
import { cn } from "@/lib/utils";
import BottomNav from "@/components/BottomNav";
import { ChevronLeft } from "lucide-react";
import { useLocation } from "wouter";
@@ -138,6 +139,7 @@ export default function IOPage() {
</div>
</div>
</div>
<BottomNav />
</div>
);
}
+2
View File
@@ -7,6 +7,7 @@
============================================================ */
import { useDevice } from "@/contexts/DeviceContext";
import { cn } from "@/lib/utils";
import BottomNav from "@/components/BottomNav";
import { Check, ChevronLeft } from "lucide-react";
import { useLocation } from "wouter";
@@ -83,6 +84,7 @@ export default function VUPage() {
);
})}
</div>
<BottomNav />
</div>
);
}