feat: init

This commit is contained in:
2025-09-05 16:44:12 +08:00
parent 85244a451e
commit 242a15c589
27 changed files with 191 additions and 168 deletions

View File

@@ -23,6 +23,7 @@
"antd-mobile-icons": "^0.3.0", "antd-mobile-icons": "^0.3.0",
"axios": "^1.6.2", "axios": "^1.6.2",
"axios-hooks": "^5.0.2", "axios-hooks": "^5.0.2",
"framer-motion": "^12.23.12",
"js-audio-recorder": "^1.0.7", "js-audio-recorder": "^1.0.7",
"jsqr": "^1.4.0", "jsqr": "^1.4.0",
"less": "^4.2.0", "less": "^4.2.0",

View File

@@ -1,5 +1,5 @@
// components/ErrorBoundary/index.tsx // components/ErrorBoundary/index.tsx
import React, { Component, ReactNode } from "react"; import { Component, ReactNode } from "react";
import { Result, Button } from "antd-mobile"; import { Result, Button } from "antd-mobile";
interface Props { interface Props {

View File

@@ -11,7 +11,7 @@
.actions { .actions {
display: flex; display: flex;
gap: 16px; gap: 12px;
margin-top: 24px; margin-top: 24px;
.button { .button {

View File

@@ -1,4 +1,4 @@
import React, { useCallback, useState } from "react"; import React, { useCallback } from "react";
import "./index.less"; import "./index.less";
const VoiceIcon = (props: { isPlaying: boolean; onChange?: () => void }) => { const VoiceIcon = (props: { isPlaying: boolean; onChange?: () => void }) => {
@@ -7,10 +7,7 @@ const VoiceIcon = (props: { isPlaying: boolean; onChange?: () => void }) => {
props.onChange?.(); props.onChange?.();
}, [isPlaying]); }, [isPlaying]);
return ( return (
<div <div className={`voice-icon ${isPlaying ? "playing" : ""}`} onClick={onChange}>
className={`voice-icon ${isPlaying ? "playing" : ""}`}
onClick={onChange}
>
<div className="wave wave1"></div> <div className="wave wave1"></div>
<div className="wave wave2"></div> <div className="wave wave2"></div>
<div className="wave wave3"></div> <div className="wave wave3"></div>

38
pnpm-lock.yaml generated
View File

@@ -41,6 +41,9 @@ importers:
axios-hooks: axios-hooks:
specifier: ^5.0.2 specifier: ^5.0.2
version: 5.1.1(axios@1.11.0)(react@18.3.1) version: 5.1.1(axios@1.11.0)(react@18.3.1)
framer-motion:
specifier: ^12.23.12
version: 12.23.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
js-audio-recorder: js-audio-recorder:
specifier: ^1.0.7 specifier: ^1.0.7
version: 1.0.7 version: 1.0.7
@@ -1481,6 +1484,20 @@ packages:
resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==}
engines: {node: '>= 6'} engines: {node: '>= 6'}
framer-motion@12.23.12:
resolution: {integrity: sha512-6e78rdVtnBvlEVgu6eFEAgG9v3wLnYEboM8I5O5EXvfKC8gxGQB8wXJdhkMy10iVcn05jl6CNw7/HTsTCfwcWg==}
peerDependencies:
'@emotion/is-prop-valid': '*'
react: ^18.0.0 || ^19.0.0
react-dom: ^18.0.0 || ^19.0.0
peerDependenciesMeta:
'@emotion/is-prop-valid':
optional: true
react:
optional: true
react-dom:
optional: true
fs-extra@11.3.1: fs-extra@11.3.1:
resolution: {integrity: sha512-eXvGGwZ5CL17ZSwHWd3bbgk7UUpF6IFHtP57NYYakPvHOs8GDgDe5KJI36jIJzDkJ6eJjuzRA8eBQb6SkKue0g==} resolution: {integrity: sha512-eXvGGwZ5CL17ZSwHWd3bbgk7UUpF6IFHtP57NYYakPvHOs8GDgDe5KJI36jIJzDkJ6eJjuzRA8eBQb6SkKue0g==}
engines: {node: '>=14.14'} engines: {node: '>=14.14'}
@@ -1828,6 +1845,12 @@ packages:
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
engines: {node: '>=16 || 14 >=14.17'} engines: {node: '>=16 || 14 >=14.17'}
motion-dom@12.23.12:
resolution: {integrity: sha512-RcR4fvMCTESQBD/uKQe49D5RUeDOokkGRmz4ceaJKDBgHYtZtntC/s2vLvY38gqGaytinij/yi3hMcWVcEF5Kw==}
motion-utils@12.23.6:
resolution: {integrity: sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ==}
ms@2.0.0: ms@2.0.0:
resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==}
@@ -3984,6 +4007,15 @@ snapshots:
hasown: 2.0.2 hasown: 2.0.2
mime-types: 2.1.35 mime-types: 2.1.35
framer-motion@12.23.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
dependencies:
motion-dom: 12.23.12
motion-utils: 12.23.6
tslib: 2.8.1
optionalDependencies:
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
fs-extra@11.3.1: fs-extra@11.3.1:
dependencies: dependencies:
graceful-fs: 4.2.11 graceful-fs: 4.2.11
@@ -4302,6 +4334,12 @@ snapshots:
dependencies: dependencies:
brace-expansion: 2.0.2 brace-expansion: 2.0.2
motion-dom@12.23.12:
dependencies:
motion-utils: 12.23.6
motion-utils@12.23.6: {}
ms@2.0.0: {} ms@2.0.0: {}
ms@2.1.3: {} ms@2.1.3: {}

View File

@@ -1,28 +1,27 @@
import {useState, useEffect} from 'react'; // import {useState, useEffect} from 'react';
import isEqual from 'lodash.isequal';
function useSessionStorage<T>(key: string, initialValue: T): [T, (value: T) => void] { // function useSessionStorage<T>(key: string, initialValue: T): [T, (value: T) => void] {
// 初始化状态 // // 初始化状态
const [storedValue, setStoredValue] = useState<T>(() => { // const [storedValue, setStoredValue] = useState<T>(() => {
const item = sessionStorage.getItem(key); // const item = sessionStorage.getItem(key);
if (item !== null) { // if (item !== null) {
// 如果 sessionStorage 中有数据,则使用现有数据 // // 如果 sessionStorage 中有数据,则使用现有数据
return JSON.parse(item); // return JSON.parse(item);
} else { // } else {
// 当 sessionStorage 中没有相应的键时,使用 initialValue 初始化,并写入 sessionStorage // // 当 sessionStorage 中没有相应的键时,使用 initialValue 初始化,并写入 sessionStorage
sessionStorage.setItem(key, JSON.stringify(initialValue)); // sessionStorage.setItem(key, JSON.stringify(initialValue));
return initialValue; // return initialValue;
} // }
}); // });
// 监听并保存变化到 sessionStorage // // 监听并保存变化到 sessionStorage
useEffect(() => { // useEffect(() => {
if (!isEqual(JSON.parse(sessionStorage.getItem(key) || 'null'), storedValue)) { // if (!isEqual(JSON.parse(sessionStorage.getItem(key) || 'null'), storedValue)) {
sessionStorage.setItem(key, JSON.stringify(storedValue)); // sessionStorage.setItem(key, JSON.stringify(storedValue));
} // }
}, [key, storedValue]); // }, [key, storedValue]);
return [storedValue, setStoredValue]; // return [storedValue, setStoredValue];
} // }
export default useSessionStorage; // export default useSessionStorage;

View File

@@ -1,5 +1,5 @@
import React from "react"; import React from "react";
import { NavBar, SafeArea, TabBar, Toast } from "antd-mobile"; import { NavBar, SafeArea, Toast } from "antd-mobile";
import { useNavigate, useLocation } from "react-router-dom"; import { useNavigate, useLocation } from "react-router-dom";
import { User, CattleZodiac } from "@icon-park/react"; import { User, CattleZodiac } from "@icon-park/react";
import "./index.less"; import "./index.less";
@@ -13,39 +13,31 @@ interface MainLayoutProps {
const MainLayout: React.FC<MainLayoutProps> = ({ isShowNavBar, children, onLink, title }) => { const MainLayout: React.FC<MainLayoutProps> = ({ isShowNavBar, children, onLink, title }) => {
const navigate = useNavigate(); const navigate = useNavigate();
const location = useLocation(); // const location = useLocation();
const { pathname } = location;
const [activeKey, setActiveKey] = React.useState(pathname);
const setRouteActive = (value: string) => { // const tabs = [
if (value !== "/") { // {
Toast.show("待开发"); // key: "/",
} // title: "宠物翻译",
}; // icon: <CattleZodiac />,
// },
// {
// key: "/set",
// title: "待办",
// icon: <User />,
// },
// {
// key: "/message",
// title: "消息",
// icon: <User />,
// },
// {
// key: "/me",
// title: "我的",
const tabs = [ // icon: <User size="24" />,
{ // },
key: "/", // ];
title: "宠物翻译",
icon: <CattleZodiac />,
},
{
key: "/set",
title: "待办",
icon: <User />,
},
{
key: "/message",
title: "消息",
icon: <User />,
},
{
key: "/me",
title: "我的",
icon: <User size="24" />,
},
];
const goBack = () => { const goBack = () => {
if (onLink) { if (onLink) {

View File

@@ -1,6 +1,5 @@
import React, { useEffect } from "react"; import React, { useEffect } from "react";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { AppRoute } from "./routes";
interface AuthRouteProps { interface AuthRouteProps {
children: React.ReactNode; children: React.ReactNode;

View File

@@ -13,6 +13,7 @@ export interface AppRoute {
const Home = lazy(() => import("@/view/home")); const Home = lazy(() => import("@/view/home"));
const Page404 = lazy(() => import("@/view/error/page404")); const Page404 = lazy(() => import("@/view/error/page404"));
const TranslateDetail = lazy(() => import("@/view/home/detail")); const TranslateDetail = lazy(() => import("@/view/home/detail"));
const TranslateMood = lazy(() => import("@/view/home/mood"));
export const routes: AppRoute[] = [ export const routes: AppRoute[] = [
{ {
path: "/", path: "/",
@@ -31,5 +32,13 @@ export const routes: AppRoute[] = [
}, },
}, },
{ path: "/translate/detail", element: <TranslateDetail />, auth: false }, { path: "/translate/detail", element: <TranslateDetail />, auth: false },
{
path: "/translate/mood",
element: <TranslateMood />,
auth: false,
meta: {
title: "情绪监控",
},
},
{ path: "*", element: <Page404 />, auth: false }, { path: "*", element: <Page404 />, auth: false },
]; ];

View File

@@ -1,4 +1,3 @@
import React from "react";
import { RenderRoutes } from "@/route/render-routes.tsx"; import { RenderRoutes } from "@/route/render-routes.tsx";
import { axiosInstance } from "@/http/axios-instance.ts"; import { axiosInstance } from "@/http/axios-instance.ts";
import { configure } from "axios-hooks"; import { configure } from "axios-hooks";

View File

@@ -0,0 +1,13 @@
// 档案
import MainLayout from "@/layout/main/mainLayout";
import "./index.less";
function Index() {
return (
<MainLayout isShowNavBar={true}>
<div className="archives"></div>
</MainLayout>
);
}
export default Index;

View File

@@ -1,6 +1,23 @@
.home { .home {
height: 100%; height: 100%;
width: 100%;
overflow: hidden; overflow: hidden;
display: flex;
flex-direction: column;
.home-header {
display: flex;
padding: 12px;
position: sticky;
top: 0px;
background: #fff;
justify-content: space-between;
align-items: center;
z-index: 99;
h3 {
font-size: 20px;
font-size: 20px;
}
}
// .adm-tabs { // .adm-tabs {
// display: flex; // display: flex;
// flex-direction: column; // flex-direction: column;
@@ -21,7 +38,7 @@
// .adm-tabs-tab { // .adm-tabs-tab {
// font-size: 20px; // font-size: 20px;
// color: rgba(0, 0, 0, 0.25); // font-size: 20px;
// font-weight: 600; // font-weight: 600;
// &.adm-tabs-tab-active { // &.adm-tabs-tab-active {
// color: #000; // color: #000;
@@ -36,6 +53,7 @@
flex-direction: column; flex-direction: column;
height: 100%; height: 100%;
.header { .header {
padding: 0px 16px;
} }
} }
} }

View File

@@ -1,32 +1,37 @@
import MainLayout from "@/layout/main/mainLayout"; import MainLayout from "@/layout/main/mainLayout";
import { Button, Tabs } from "antd-mobile"; import { useState } from "react";
import Translate from "./translate"; import { Divider, Space } from "antd-mobile";
import Translate from "./translate/index";
import { Electrocardiogram, Filter, GithubOne } from "@icon-park/react";
import { useNavigate } from "react-router-dom";
import "./index.less"; import "./index.less";
function Index() { function Index() {
const handleRecordComplete = (audioData: AudioData): void => { const [visible, setVisible] = useState<boolean>(false);
console.log("录音完成:", audioData); const navigate = useNavigate();
};
const handleError = (error: Error): void => { const onLink = () => {
console.error("录音错误:", error); navigate("/translate/mood");
}; };
return ( return (
<MainLayout> <MainLayout>
<div className="home"> <div className="home">
<div className="header"> <div className="home-header">
<h3></h3> <h3></h3>
<div></div> <Space style={{ fontSize: "20px", "--gap": "16px" }}>
<Filter theme="outline" fill="#333" strokeWidth={3} strokeLinecap="butt" />
<Divider direction="vertical" />
<Electrocardiogram
theme="outline"
fill="#333"
strokeWidth={3}
strokeLinecap="butt"
onClick={onLink}
/>
<GithubOne theme="outline" fill="#333" strokeWidth={3} strokeLinecap="butt" />
</Space>
</div> </div>
{/* <Tabs stretch={false}> <Translate searchVisible={visible} />
<Tabs.Tab title="宠物翻译" key="1">
<Translate />
</Tabs.Tab>
<Tabs.Tab title="宠物档案" key="2">
2
</Tabs.Tab>
</Tabs> */}
</div> </div>
</MainLayout> </MainLayout>
); );

View File

@@ -0,0 +1,3 @@
.mood {
padding: 12px;
}

View File

@@ -0,0 +1,11 @@
import MainLayout from "@/layout/main/mainLayout";
import styles from "./index.module.less";
const Moods = () => {
return (
<MainLayout isShowNavBar={true} title="情绪">
<div className={styles.mood}></div>
</MainLayout>
);
};
export default Moods;

View File

@@ -4,7 +4,7 @@ import { VoiceIcon } from "@workspace/shared";
import dogSvg from "@/assets/translate/dog.svg"; import dogSvg from "@/assets/translate/dog.svg";
import catSvg from "@/assets/translate/cat.svg"; import catSvg from "@/assets/translate/cat.svg";
import pigSvg from "@/assets/translate/pig.svg"; import pigSvg from "@/assets/translate/pig.svg";
import { Message } from "../../types"; import { Message } from "../../../types";
import "./index.less"; import "./index.less";
interface DefinedProps { interface DefinedProps {
@@ -89,44 +89,18 @@ function Index(props: DefinedProps) {
}; };
const renderAvatar = (type?: "pig" | "cat" | "dog") => { const renderAvatar = (type?: "pig" | "cat" | "dog") => {
if (type === "pig") { if (type === "pig") {
<Image <Image src={pigSvg} width={40} height={40} fit="cover" style={{ borderRadius: 32 }} />;
src={pigSvg}
width={40}
height={40}
fit="cover"
style={{ borderRadius: 32 }}
/>;
} }
if (type === "cat") { if (type === "cat") {
return ( return <Image src={catSvg} width={40} height={40} fit="cover" style={{ borderRadius: 32 }} />;
<Image
src={catSvg}
width={40}
height={40}
fit="cover"
style={{ borderRadius: 32 }}
/>
);
} }
return ( return <Image src={dogSvg} width={40} height={40} fit="cover" style={{ borderRadius: 32 }} />;
<Image
src={dogSvg}
width={40}
height={40}
fit="cover"
style={{ borderRadius: 32 }}
/>
);
}; };
return ( return (
<div className="message"> <div className="message">
{data.map((item, index) => ( {data.map((item, index) => (
<div <div className="item" key={index} onClick={() => playAudio(item.id, item.audioUrl)}>
className="item"
key={index}
onClick={() => playAudio(item.id, item.audioUrl)}
>
{renderAvatar(item.type)} {renderAvatar(item.type)}
<div className="rig"> <div className="rig">
<div> <div>
@@ -163,9 +137,7 @@ function Index(props: DefinedProps) {
</div> </div>
<div className="voice-container"> <div className="voice-container">
<VoiceIcon isPlaying={false} /> <VoiceIcon isPlaying={false} />
<div className="tips"> <div className="tips">{isRecording ? "录制中..." : "轻点麦克风录制"}</div>
{isRecording ? "录制中..." : "轻点麦克风录制"}
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -1,21 +1,14 @@
import { DownOne } from "@icon-park/react"; import { Dropdown, type DropdownRef, Radio, SearchBar, Space } from "antd-mobile";
import {
ActionSheet,
Dropdown,
type DropdownRef,
Popup,
Radio,
SearchBar,
Space,
} from "antd-mobile";
import { RadioValue } from "antd-mobile/es/components/radio"; import { RadioValue } from "antd-mobile/es/components/radio";
import { useRef, useState } from "react"; import { useRef, useState } from "react";
interface PropsConfig { interface PropsConfig {
handleAllAni: () => void; handleAllAni: () => void;
value?: string;
} }
const allAni = ["全部宠物", "丑丑", "胖胖", "可可"]; const allAni = ["全部宠物", "丑丑", "胖胖", "可可"];
function SearchCom(props: PropsConfig) { function SearchCom(props: PropsConfig) {
const { value } = props;
const [aniName, setAniName] = useState<string>("全部宠物"); const [aniName, setAniName] = useState<string>("全部宠物");
const animenuRef = useRef<DropdownRef>(null); const animenuRef = useRef<DropdownRef>(null);
const handleAniSelect = (val: RadioValue) => { const handleAniSelect = (val: RadioValue) => {
@@ -32,6 +25,7 @@ function SearchCom(props: PropsConfig) {
"--height": "32px", "--height": "32px",
"--padding-left": "12px", "--padding-left": "12px",
}} }}
defaultValue={value}
/> />
<Dropdown className="all" ref={animenuRef}> <Dropdown className="all" ref={animenuRef}>
<Dropdown.Item key="ani" title={aniName}> <Dropdown.Item key="ani" title={aniName}>

View File

@@ -5,8 +5,6 @@ import microphoneSvg from "@/assets/translate/microphone.svg";
import microphoneDisabledSvg from "@/assets/translate/microphoneDisabledSvg.svg"; import microphoneDisabledSvg from "@/assets/translate/microphoneDisabledSvg.svg";
import { createStartRecordSound, createSendSound } from "@/utils/voice"; import { createStartRecordSound, createSendSound } from "@/utils/voice";
import "./index.less"; import "./index.less";
import { Message } from "../../types";
import { CloseCircleOutline } from "antd-mobile-icons";
interface DefinedProps { interface DefinedProps {
onRecordingComplete: (url: string, finalDuration: number) => void; onRecordingComplete: (url: string, finalDuration: number) => void;
@@ -80,10 +78,7 @@ function Index(props: DefinedProps) {
//正在录音中 //正在录音中
return ( return (
<div onClick={onStopRecording} className="isRecording"> <div onClick={onStopRecording} className="isRecording">
<ProgressCircle <ProgressCircle percent={recordingDuration} style={{ "--size": "80px" }}>
percent={recordingDuration}
style={{ "--size": "80px" }}
>
<div className="recording-dot"> <div className="recording-dot">
<span className="circle"></span> <span className="circle"></span>
</div> </div>
@@ -95,14 +90,7 @@ function Index(props: DefinedProps) {
); );
} else { } else {
//麦克风状态 //麦克风状态
return ( return <Image height={80} width={80} src={microphoneSvg} onClick={onStartRecording} />;
<Image
height={80}
width={80}
src={microphoneSvg}
onClick={onStartRecording}
/>
);
} }
}, [hasPermission, isRecording, recordingDuration]); }, [hasPermission, isRecording, recordingDuration]);
const checkMicrophonePermission = useCallback(async () => { const checkMicrophonePermission = useCallback(async () => {

View File

@@ -3,7 +3,7 @@ import { Image, Toast } from "antd-mobile";
import MessageCom from "./component/message"; import MessageCom from "./component/message";
import VoiceRecord from "./component/voice"; import VoiceRecord from "./component/voice";
import { XPopup, FloatingMenu, type FloatMenuItemConfig } from "@workspace/shared"; import { XPopup, FloatingMenu, type FloatMenuItemConfig } from "@workspace/shared";
import type { Message } from "./types"; import type { Message } from "../types";
import { mockTranslateAudio } from "@/utils/voice"; import { mockTranslateAudio } from "@/utils/voice";
import dogSvg from "@/assets/translate/dog.svg"; import dogSvg from "@/assets/translate/dog.svg";
@@ -11,7 +11,9 @@ import catSvg from "@/assets/translate/cat.svg";
import pigSvg from "@/assets/translate/pig.svg"; import pigSvg from "@/assets/translate/pig.svg";
import { MoreTwo } from "@icon-park/react"; import { MoreTwo } from "@icon-park/react";
import SearchCom from "./component/search"; import SearchCom from "./component/search";
interface DefinedProps {} interface DefinedProps {
searchVisible: boolean;
}
const menuItems: FloatMenuItemConfig[] = [ const menuItems: FloatMenuItemConfig[] = [
{ icon: <Image src={dogSvg} />, type: "dog" }, { icon: <Image src={dogSvg} />, type: "dog" },
{ icon: <Image src={catSvg} />, type: "cat" }, { icon: <Image src={catSvg} />, type: "cat" },
@@ -22,23 +24,11 @@ const menuItems: FloatMenuItemConfig[] = [
}, },
]; ];
function Index(props: DefinedProps) { function Index(props: DefinedProps) {
// const data: Message[] = [ const { searchVisible } = props;
// {
// id: 1,
// audioUrl: "",
// duration: 0,
// translatedText: "",
// isTranslating: true,
// isPlaying: false,
// timestamp: 0,
// },
// ];
const [currentPlayingId, setCurrentPlayingId] = useState<string | null>(null); //当前播放id
const [messages, setMessages] = useState<Message[]>([]); const [messages, setMessages] = useState<Message[]>([]);
const [isRecording, setIsRecording] = useState(false); //是否录音中 const [isRecording, setIsRecording] = useState(false); //是否录音中
const [currentLanguage, setCurrentLanguage] = useState<FloatMenuItemConfig>(); const [currentLanguage, setCurrentLanguage] = useState<FloatMenuItemConfig>();
const [visible, setVisible] = useState<boolean>(false); const [visible, setVisible] = useState<boolean>(false);
useEffect(() => { useEffect(() => {
setCurrentLanguage(menuItems[0]); setCurrentLanguage(menuItems[0]);
}, []); }, []);
@@ -111,9 +101,11 @@ function Index(props: DefinedProps) {
return ( return (
<div className="translate-container"> <div className="translate-container">
<div className="header"> {searchVisible && (
<SearchCom handleAllAni={() => {}} /> <div className="header">
</div> <SearchCom handleAllAni={() => {}} />
</div>
)}
<MessageCom data={messages} isRecording={isRecording}></MessageCom> <MessageCom data={messages} isRecording={isRecording}></MessageCom>
<VoiceRecord <VoiceRecord

View File

@@ -12,14 +12,7 @@ export default defineConfig({
open: true, open: true,
}, },
css: { css: {
modules: { modules: {},
generateScopedName: () => {
if (process.env.NODE_ENV === "production") {
return `[hash:base64:8]`;
}
return `[name]__[local]___[hash:base64:5]`;
},
},
preprocessorOptions: { preprocessorOptions: {
less: { less: {
// 全局变量 // 全局变量