修复问题

This commit is contained in:
海龙 2025-09-01 19:19:07 +08:00
parent 08719b2dd8
commit d2dd4e57e4
2 changed files with 67 additions and 82 deletions

View File

@ -7,13 +7,11 @@
- React组件Modal、Form、Button等 - React组件Modal、Form、Button等
- 样式和布局逻辑 - 样式和布局逻辑
- 用户交互事件绑定 - 用户交互事件绑定
- 通过props接收数据和回调函数 - 越是可复用组件,越要小心定义,越要简单,宁可页面中的组件使用多做点,也要组件少做点,因为复用越多,它就可能发生的变化越多,除非你很确定它的变化不会更多了。
**设计原则** **设计原则**
- 不包含业务逻辑 - 不包含业务逻辑
- 不直接操作状态 - 不直接操作状态
- 通过回调函数与上层通信
- 可复用和可测试
### 2. Hook (状态管理层) ### 2. Hook (状态管理层)
**职责**:状态管理、副作用处理、业务逻辑组合 **职责**:状态管理、副作用处理、业务逻辑组合
@ -26,11 +24,29 @@
**设计原则** **设计原则**
- 协调全局状态和本地状态 - 协调全局状态和本地状态
- 处理异步操作和副作用 - 处理异步操作和副作用
- 组合多个UseCase的调用 - 组合封装UseCase的调用让react的方便性和hook思想体现出来
- 提供响应式的数据接口 - 提供响应式的数据接口
### 3. UseCase (业务逻辑层) ### 3. UseCase (业务逻辑层)
**职责**:核心业务规则、业务流程编排、领域逻辑验证 **职责**:核心业务规则、业务流程编排、领域逻辑验证,它里面的流程应该一眼看过去瞬间就知道这个用例中包含的业务是干啥的里面应该是去调用一个个service,并且有注释说明,它是会最经常发生更改的,所以它要足够简单,要足够注释。
```ts
class DemoUseCase {
constructor(private readonly aService: AService, private readonly bService: BService,cStore:Store) {}
async execute(href:string,storedate:any) {
// 获取a数据
const aData = await this.aService.getA(href);
// 处理b请求
const b = await this.bService.getB(aData);
// 更新cStore
this.cStore.update({
...storedate,
b,
});
return b;
}
}
```
**内容** **内容**
- 业务用例类ImageStoryUseCase、ScriptGenerationUseCase等 - 业务用例类ImageStoryUseCase、ScriptGenerationUseCase等
- 完整的业务流程方法 - 完整的业务流程方法
@ -43,11 +59,11 @@
- 协调多个Service的调用 - 协调多个Service的调用
- 返回领域实体,而不是原始数据 - 返回领域实体,而不是原始数据
- 无状态,方法调用间不依赖实例状态 - 无状态,方法调用间不依赖实例状态
- 无关任何react的东西纯粹的TS代码
### 4. Service (外部服务层) ### 4. Service (外部服务层)
**职责**:外部服务集成、技术实现细节、基础设施 **职责**:外部服务集成、技术实现细节、基础设施,它应该是一堆的服务函数,纯函数,输入到输出,没有外部的闭包依赖。不要觉得有时候可以从其它地方直接依赖,就不用参数来接收,它要干净,要是纯函数,要能通过参数判断其全部所需,所以要用接收参数的方式
**内容** **内容**
- 外部API调用服务ImageProcessingService、AIAnalysisService等
- 技术实现细节(图片处理、网络请求等) - 技术实现细节(图片处理、网络请求等)
- 错误处理和重试逻辑 - 错误处理和重试逻辑
- 可以被多个UseCase复用的服务 - 可以被多个UseCase复用的服务
@ -57,58 +73,41 @@
- 处理外部API调用 - 处理外部API调用
- 提供统一的错误处理 - 提供统一的错误处理
- 实现接口隔离原则 - 实现接口隔离原则
- 无关任何react的东西纯粹的TS代码
### 5. Repository (数据访问层) ### 5. Repository (数据访问层)
**职责**:数据持久化、数据查询、数据转换 使用ApiFox去对接好后端的接口文档然后MCP接入cursor,从而直接生成接口请求函数以及类型相对于没有这个东西cursor帮你写的代码将是天差地别的能提高你大约20%的开发效率。当然这要协同后端好好写接口参数和响应的内容。
**内容**
- 数据访问类ImageStoryRepository、CharacterRepository等
- 数据持久化逻辑
- 数据查询和过滤
- 数据转换Entity ↔ Data
**设计原则**
- 封装数据访问细节
- 提供统一的CRUD接口
- 处理数据转换
- 实现数据访问的抽象
## 📊 状态管理策略 ## 📊 状态管理策略
**状态分类与存储位置** **状态分类**
- **业务核心状态** → Zustand StorecurrentStory、storyList等 - **功能业务模块状态** → 微型Store用不同模块功能去拆Store 而非页面,记住要用单例模式处理
- **UI交互状态** → 组件useStateisModalOpen、localInput等 - **纯UI变化状态** → 组件useState跟业务没有任何关系只是UI变化所用的状态。
- **业务流程状态** → UseCase私有状态analysisProgress等 - **业务流程状态** → UseCase私有状态从这里开始就是跟react任何关系都没有了纯TS代码去写的逻辑状态也是纯粹的业务状态一定要在这里忘记react的存在。
- **用户偏好状态** → Zustand StoreselectedCategory、theme等 - **全局状态** → 全局Store跨模块共享比如用户信息、主题色、语言等。
- **临时计算状态** → useMemo/useCallbackfilteredStories等
## 数据流向 ## 数据流向
**状态流转过程** **状态流转过程**
用户操作 → 组件本地状态 → Hook协调 → UseCase业务逻辑 → 全局状态更新 → 组件重新渲染 用户操作 → 组件本地状态 → Store Hook协调 → UseCase业务逻辑 → Store 状态更新 → 组件重新渲染
**具体流程**
1. 用户在组件中触发操作
2. 组件更新本地状态
3. Hook协调多个UseCase调用
4. UseCase执行业务逻辑和规则验证
5. 更新全局状态
6. 组件重新渲染显示结果
## 设计模式应用 ## 设计模式应用
**核心模式** **核心模式**
1. **依赖注入**UseCase通过构造函数注入Service依赖 1. **依赖注入**UseCase通过构造函数注入Service依赖最好的简化useCase的方式。
2. **工厂模式**创建UseCase实例管理依赖关系 2. **策略模式**:要弄清楚,什么是策略,有了这个意识,我们这个项目,很多地方可以用到策略模式,可扩展性将提高一大截
3. **策略模式**可插拔的业务策略如不同的AI分析策略 4. **观察者模式**我们的项目需要跨页面跨组件的复杂通讯采用观察者模式是非常合适的比如chatBox.如果搞不明白这个模式,那就事件总线,这个东西更容易理解,也能实现相同功能。
4. **观察者模式**:状态变化通知,组件响应式更新
## 🧪 测试策略 ## 🧪 测试策略
**分层测试** **分层测试**
- **Component层**:组件渲染和交互测试 - **Component层**:组件渲染和交互测试(目前的前端测试框架,测试这个纯浪费时间,不要为这个层做单元测试)
- **Hook层**:状态管理和副作用测试 - **Hook层**状态管理和副作用测试react的hook系统限制太大不要为这个层做单元测试
- **UseCase层**:业务逻辑和规则验证测试 - **UseCase层**:业务逻辑和规则验证测试(这个层需要做单元测试,最适合的地方就是这个)
- **Service层**:外部服务集成测试 - **Service层**:外部服务集成测试(这个层不需要做单元测试,,因为用例层依赖这个层,如果用例层完备,这个就直接连带测试)
- **Repository层**:数据访问逻辑测试 - **Repository层**数据访问逻辑测试对于前端来说就是接口请求的一堆封装用apifox 的mcp生成接口请求函数就好不用再封装和创建更复杂内容。若测试这个直接apifox
-
>谦卑对象模式Humble Object Pattern是一种设计模式用于将复杂逻辑从难以测试的组件中分离出来以提高代码的可测试性和可维护性。其核心思想是将与用户界面、外部系统或复杂依赖相关的代码难以测试的部分剥离保留一个“谦卑”的对象只包含简单逻辑或直接调用而将主要业务逻辑放入易于测试的独立对象中。
## 错误处理机制 ## 错误处理机制
@ -120,8 +119,8 @@
**错误处理流程** **错误处理流程**
1. Service层捕获原始错误并转换为应用错误 1. Service层捕获原始错误并转换为应用错误
2. UseCase层抛出领域错误 2. UseCase层抛出领域错误
3. Hook层统一捕获和处理错误 3. Hook层将用例的错误,变成错误提示,展示给用户
4. 组件层显示错误信息 4. 组件层显示错误信息(组件层不需要做错误处理,因为组件层是纯展示层,不需要处理错误)
## 性能优化策略 ## 性能优化策略
@ -132,19 +131,5 @@
**业务逻辑优化** **业务逻辑优化**
- UseCase方法设计为无状态避免实例状态维护 - UseCase方法设计为无状态避免实例状态维护
- Service层实现缓存和重试机制 - 应用起多个微型的Store不再让UI组件里面出现一大堆的state,这样可以让我们放心的拆分子组件而状态和函数可以直接使用而不是props传递一大堆回调一大堆注意store只存状态不做任何业务逻辑业务逻辑要写在useCase里面store中的函数是交互事件+状态修改。
- Repository层实现数据分页和懒加载 - 全局定义统一的tailwindcss的一些样式圆角、边框、主题色、阴影。不要再像是现在这样每次都cursor随意发挥
## 📋 开发检查清单
**新增功能时**
- [ ] 是否在正确的层次添加代码?
- [ ] 是否遵循单一职责原则?
- [ ] 是否定义了清晰的接口?
- [ ] 是否处理了错误情况?
- [ ] 是否添加了相应的测试?
**重构代码时**
- [ ] 是否保持了接口的向后兼容?
- [ ] 是否更新了相关的测试?
- [ ] 是否验证了功能完整性?

View File

@ -676,27 +676,27 @@ function HomeModule3() {
></div> ></div>
<Swiper <Swiper
modules={[Autoplay]} modules={[Autoplay]}
direction="vertical" direction="vertical"
loop={true} loop={true}
spaceBetween={16} spaceBetween={0}
slidesPerView={2} slidesPerView={3}
autoplay={{ autoplay={{
delay: 0, delay: 0,
pauseOnMouseEnter: true, pauseOnMouseEnter: true,
disableOnInteraction: false, disableOnInteraction: false,
}} }}
speed={8000} speed={6000}
grabCursor={true} grabCursor={true}
className="w-full h-full" className="w-full h-full"
cssMode={false} cssMode={false}
freeMode={true} freeMode={true}
watchSlidesProgress={false} watchSlidesProgress={false}
style={ style={
{ {
"--swiper-wrapper-transition-timing-function": "linear", "--swiper-wrapper-transition-timing-function": "linear",
} as React.CSSProperties } as React.CSSProperties
} }
> >
{mobileVideoList.map((video, videoIndex) => ( {mobileVideoList.map((video, videoIndex) => (
<SwiperSlide key={videoIndex} className="w-full !h-[12rem]"> <SwiperSlide key={videoIndex} className="w-full !h-[12rem]">