feat: init

This commit is contained in:
2025-09-04 11:29:00 +08:00
parent 2c9059ce2f
commit ddbee614e8
89 changed files with 3476 additions and 349 deletions

17
packages/utils/index.ts Normal file
View File

@@ -0,0 +1,17 @@
// //处理音频类
export * from "./src/voice";
// // 验证工具
// export * from './validation';
// // 存储工具
// export * from './storage';
// // 日期工具
// export * from './date';
// // 按模块导出
// export * as format from './format';
// export * as validation from './validation';
// export * as storage from './storage';
// export * as date from './date';

View File

@@ -0,0 +1,19 @@
{
"name": "@workspace/utils",
"version": "1.0.0",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"import": "./index.ts",
"types": "./index.ts"
}
},
"scripts": {
"build": "tsc",
"dev": "tsc --watch",
"lint": "eslint src --ext .ts",
"type-check": "tsc --noEmit",
"clean": "rimraf dist"
}
}

View File

@@ -0,0 +1,3 @@
export function toYuan(num: number) {
return (num / 100).toFixed(2);
}

View File

@@ -0,0 +1,3 @@
export function toKm(m: number): number {
return m / 1000;
}

164
packages/utils/src/voice.ts Normal file
View File

@@ -0,0 +1,164 @@
export const mockTranslateAudio = async (): Promise<string> => {
return new Promise((resolve) => {
setTimeout(() => {
const mockTranslations = [
"汪汪汪!我饿了,想吃东西!🍖",
"喵喵~我想要抱抱!🤗",
"我想出去玩耍!🎾",
"我很开心!😊",
"我有点害怕...😰",
"我想睡觉了~😴",
"主人,陪我玩一会儿吧!🎮",
"我想喝水了💧",
"外面有什么声音?👂",
"我爱你,主人!❤️",
];
const randomTranslation =
mockTranslations[Math.floor(Math.random() * mockTranslations.length)];
resolve(randomTranslation);
}, 2000 + Math.random() * 2000);
});
};
// 创建发送音效 - 清脆的"叮"声
export const createSendSound = () => {
try {
const audioContext = new (window.AudioContext ||
(window as any).webkitAudioContext)();
const oscillator = audioContext.createOscillator();
const gainNode = audioContext.createGain();
oscillator.connect(gainNode);
gainNode.connect(audioContext.destination);
// 设置音调 - 清脆的高音
oscillator.frequency.setValueAtTime(800, audioContext.currentTime);
oscillator.frequency.exponentialRampToValueAtTime(
1200,
audioContext.currentTime + 0.1
);
// 设置音量包络
gainNode.gain.setValueAtTime(0, audioContext.currentTime);
gainNode.gain.linearRampToValueAtTime(0.3, audioContext.currentTime + 0.01);
gainNode.gain.exponentialRampToValueAtTime(
0.01,
audioContext.currentTime + 0.3
);
oscillator.type = "sine";
// 创建音频元素
const audio = new Audio();
// 重写play方法来播放合成音效
audio.play = () => {
return new Promise((resolve) => {
try {
const newOscillator = audioContext.createOscillator();
const newGainNode = audioContext.createGain();
newOscillator.connect(newGainNode);
newGainNode.connect(audioContext.destination);
newOscillator.frequency.setValueAtTime(800, audioContext.currentTime);
newOscillator.frequency.exponentialRampToValueAtTime(
1200,
audioContext.currentTime + 0.1
);
newGainNode.gain.setValueAtTime(0, audioContext.currentTime);
newGainNode.gain.linearRampToValueAtTime(
0.3,
audioContext.currentTime + 0.01
);
newGainNode.gain.exponentialRampToValueAtTime(
0.01,
audioContext.currentTime + 0.3
);
newOscillator.type = "sine";
newOscillator.start(audioContext.currentTime);
newOscillator.stop(audioContext.currentTime + 0.3);
setTimeout(() => resolve(undefined), 300);
} catch (error) {
console.error("播放发送音效失败:", error);
resolve(undefined);
}
});
};
return audio;
} catch (error) {
console.error("创建发送音效失败:", error);
return new Audio(); // 返回空音频对象
}
};
export const createStartRecordSound = () => {
try {
const audio = new Audio();
audio.play = () => {
return new Promise((resolve) => {
try {
const audioContext = new (window.AudioContext ||
(window as any).webkitAudioContext)();
const oscillator = audioContext.createOscillator();
const gainNode = audioContext.createGain();
oscillator.connect(gainNode);
gainNode.connect(audioContext.destination);
// 设置音调 - 低沉的音
oscillator.frequency.setValueAtTime(400, audioContext.currentTime);
// 设置音量包络
gainNode.gain.setValueAtTime(0, audioContext.currentTime);
gainNode.gain.linearRampToValueAtTime(
0.2,
audioContext.currentTime + 0.05
);
gainNode.gain.linearRampToValueAtTime(
0,
audioContext.currentTime + 0.2
);
oscillator.type = "sine";
oscillator.start(audioContext.currentTime);
oscillator.stop(audioContext.currentTime + 0.2);
setTimeout(() => resolve(undefined), 200);
} catch (error) {
console.error("播放录音音效失败:", error);
resolve(undefined);
}
});
};
return audio;
} catch (error) {
console.error("创建录音音效失败:", error);
return new Audio();
}
};
export const getAudioDuration = async (audioBlob: Blob): Promise<number> => {
return new Promise((resolve, reject) => {
const AudioContextClass =
window.AudioContext || (window as any).webkitAudioContext;
const audioContext = new AudioContextClass();
const fileReader = new FileReader();
fileReader.onload = async (e) => {
try {
const arrayBuffer = e.target?.result as ArrayBuffer;
const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
const duration = audioBuffer.duration;
resolve(duration);
} catch (error) {
reject(error);
}
};
fileReader.readAsArrayBuffer(audioBlob);
});
};

View File

@@ -0,0 +1,9 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"composite": true,
"noEmit": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}