Files
AIclinicalresearch/docs/00-系统总体设计/06-模块独立部署与单机版方案.md
HaHafeng 1b53ab9d52 feat(aia): Complete AIA V2.0 with universal streaming capabilities
Major Changes:
- Add StreamingService with OpenAI Compatible format
- Upgrade Chat component V2 with Ant Design X integration
- Implement AIA module with 12 intelligent agents
- Update API routes to unified /api/v1 prefix
- Update system documentation

Backend (~1300 lines):
- common/streaming: OpenAI Compatible adapter
- modules/aia: 12 agents, conversation service, streaming integration
- Update route versions (RVW, PKB to v1)

Frontend (~3500 lines):
- modules/aia: AgentHub + ChatWorkspace (100% prototype restoration)
- shared/Chat: AIStreamChat, ThinkingBlock, useAIStream Hook
- Update API endpoints to v1

Documentation:
- AIA module status guide
- Universal capabilities catalog
- System overview updates
- All module documentation sync

Tested: Stream response verified, authentication working
Status: AIA V2.0 core completed (85%)
2026-01-14 19:15:01 +08:00

1567 lines
41 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 璅<E79285><E288AA><EFBFBD><E7A589>函蔡銝𤾸<E98A9D><F0A4BEB8><EFBFBD><E7AE87><EFBFBD>
> **<2A><><EFBFBD><EFB99D>𧋦嚗?* v1.0
> **<2A>𥕦遣<F0A595A6><EFBFBD>嚗?* 2025-11-06
> **<2A><><EFBFBD>擧凒<E693A7><EFBFBD>** 2025-11-06
> **<2A><><EFBFBD><EFBFBD><E59786><EFBFBD>** <20><EFBFBD>霈曇恣
> **雿𡏭<E99BBF><F0A18FAD><EFBFBD>** <20><><EFBFBD>舀沲<E88880><E6B2B2><EFBFBD>
---
## <20><> <20><EFBFBD><E8A9A8><EFBFBD>
1. **憒<><E68692>摰䂿緵瘥譍葵璅<E79285><E288AA><EFBFBD><E7A589>函蔡嚗?*
-<E79285>靘肽<E99D98>撟喳蝱撅<E89DB1><E69285><EFBFBD>𡁶鍂<F0A181B6><EFBFBD><EFBFBD><E69285><EFBFBD><E68692><EFBFBD><EFBFBD>嚗?
-<><E68692><EFBFBD><EFBFBD><E480B9><EFBFBD>鈭批<E988AD><E689B9><EFBFBD><EFBFBD><EFBFBD>
-<><E68692>摰䂿緵<E482BF>砍𧑐<E7A08D><EFBFBD>蝵莎<E89DB5>
2. **憒<><E68692><EFBFBD><E69298><EFBFBD><E7A983><EFBFBD>嚗?*
-<><E68692><EFBFBD>拍鍂Electron獢<6E>沲嚗?
-<><E68692>憭滨鍂<E6BBA8><EFBFBD><EFBFBD><E99A9E>嚗?
- <20><EFBFBD><EFBFBD><E68692>霈曇恣嚗?
---
## <20>㴓 Part 1嚗𡁏芋<F0A1818F>㛖𡠺蝡钅<E89DA1>蝵脫䲮獢?
### <20><EFBFBD><E8A9A8><EFBFBD>艙嚗𡁶𡠺蝡钅<E89DA1>蝵?<3F>?摰<><E691B0>摮斤<E691AE>
**<EFBFBD>喲睸瘣𧼮<EFBFBD>嚗?*
```
<EFBFBD><EFBFBD><EFBFBD>函蔡<EFBFBD><EFBFBD><EFBFBD><EFBFBD>鉄銋㚁<EFBFBD>
<EFBFBD>?<3F>臭誑<E887AD>閧𡠺<E996A7><EFBFBD>
<EFBFBD>?<3F>臭誑<E887AD>閧𡠺餈鞱<E9A488>
<EFBFBD>?<3F>臭誑<E887AD>閧𡠺<E996A7><F0A1A0BA><EFBFBD>?
<EFBFBD>?<3F>臭誑<E887AD>閧𡠺<E996A7><F0A1A0BA>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD>?摰<><E691B0>銝滢<E98A9D>韏硋<E99F8F>隞碶誨<E7A2B6>?
<EFBFBD>?摰<><E691B0>銝滚<E98A9D>鈭怠抅蝖<E68A85>霈暹鴌
```
**蝐餅<E89D90>嚗?*
```
撠勗<EFBFBD><EFBFBD>銝芰𡠺蝡讠<EFBFBD><EFBFBD>𧢲㦤App嚗?
- 摰<><E691B0>韏𡝗<E99F8F>雿𦦵頂蝏<E9A082><E89D8F>Android/iOS嚗?
- 摰<><E691B0>韏𣇉頂蝏鬹PI嚗<49><E59A97><EFBFBD>誩仍<E8AAA9><E4BB8D><EFBFBD>雿滨<E99BBF>嚗?
- 雿<><E99BBF><EFBFBD>臭誑<E887AD><EFBFBD>銝贝蝸<E8B49D><E89DB8><EFBFBD><EFBFBD><E98B86><EFBFBD><EFBFBD>銵䎚<E98AB5><E48E9A>桊頧?
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>函蔡銋<EFBFBD>糓銝<EFBFBD><EFBFBD><EFBFBD>
- 摰<><E691B0>韏硋像<E7A18B><EFBFBD><EFBFBD><EFBFBD>瑁恕霂<E68195><E99C82><EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗?
- 摰<><E691B0>韏㚚<E99F8F>𡁶鍂<F0A181B6><EFBFBD><EFBFBD><E69285>LLM蝵穃<E89DB5><E7A983><EFBFBD><EFBFBD><EFBFBD><E78DA2><EFBFBD><EFBFBD><EFBFBD>嚗?
- 雿<><E99BBF><EFBFBD>臭誑<E887AD><EFBFBD><E7A589><EFBFBD><E69E8F><EFBFBD><EFBFBD>蝵脯<E89DB5><E884AF><EFBFBD><EFBFBD>?
```
---
## <20>𣑐 <20><EFBFBD><EFBFBD>嚗𡁜<E59A97><F0A1819C><EFBFBD><E6B994><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E588BB><EFBFBD><E585B6><EFBFBD>鈭批<E988AD>嚗?
### <20><><EFBFBD>箸艶
- <20>?璅<E79285>雿靝蛹<E99D9D><EFBFBD>鈭批<E988AD><E689B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>恣蝔輻頂蝏<E9A082><E89D8F>
- <20>?摰<E691B0><EFBFBD><E996AC><EFBFBD><E691B0><EFBFBD>砍𧑐<E7A08D><EFBFBD>蝵?
- <20>?銝滢<E98A9D>韏硋<E99F8F>隞𡝗芋<F0A19D97><EFBFBD>撟喳蝱
### <20><EFBFBD><E8A9A8>肽楝
**撠<><E692A0>韏𣇉<E99F8F>撟喳蝱撅<E89DB1><E69285><EFBFBD>𡁶鍂<F0A181B6><EFBFBD><EFBFBD><E69285>韏瑟<E99F8F><E7919F>?*
```
摰∠阮蝟餌<EFBFBD><EFBFBD><EFBFBD>鈭批<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD>𢞖<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
<EFBFBD>? RVW摰∠阮蝟餌<E89D9F><E9A48C><EFBFBD>鈭批<E988AD> <20>?
<EFBFBD>? <20>?
<EFBFBD>? <20>𢞖<EFBFBD><F0A29E96><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>?
<EFBFBD>? <20>? 銝𡁜𦛚璅<E79285>撅? <20>?<3F>?
<EFBFBD>? <20>? RVW嚗<57>阮隞嗅恣<E59785><EFBFBD> <20>?<3F>?
<EFBFBD>? <20><EFBFBD><E5A999><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>?
<EFBFBD>? <20>?
<EFBFBD>? <20>𢞖<EFBFBD><F0A29E96><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>?
<EFBFBD>? <20>? <20>𡁶鍂<F0A181B6><EFBFBD><EFBFBD><E69285><EFBFBD><E695B9><EFBFBD><EFBFBD>嚗? <20>?<3F>?
<EFBFBD>? <20>? - LLM蝵穃<E89DB5> <20>?<3F>?
<EFBFBD>? <20>? - <20><>﹝憭<EFB99D><E686AD>撘閙<E69298> <20>?<3F>?
<EFBFBD>? <20><EFBFBD><E5A999><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>?
<EFBFBD>? <20>?
<EFBFBD>? <20>𢞖<EFBFBD><F0A29E96><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>?
<EFBFBD>? <20>? 撟喳蝱<E596B3><EFBFBD><EFBFBD><E69285><EFBFBD><E695B9><EFBFBD><EFBFBD>嚗? <20>?<3F>?
<EFBFBD>? <20>? - <20><EFBFBD>霈方<E99C88><EFBFBD><E59A97><EFBFBD>𣇉<EFBFBD>嚗? <20>?<3F>?
<EFBFBD>? <20>? - 摮睃<E691AE><E79D83>滚𦛚 <20>?<3F>?
<EFBFBD>? <20>? - <20>烐綉<E78390><EFBFBD> <20>?<3F>?
<EFBFBD>? <20><EFBFBD><E5A999><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>?
<EFBFBD>? <20>?
<EFBFBD>? <20>𢞖<EFBFBD><F0A29E96><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>?
<EFBFBD>? <20>? <20><EFBFBD><E7A589>唳旿摨? <20>?<3F>?
<EFBFBD>? <20>? PostgreSQL嚗㇄ocker嚗? <20>?<3F>?
<EFBFBD>? <20><EFBFBD><E5A999><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>?
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
```
---
### <20><><EFBFBD><EFBFBD><E887AC>?
#### Step 1: 隞<><E99A9E><EFBFBD><E89D8F>嚗㇈onorepo嚗?
```
AIclinicalresearch/
<20><EFBFBD><E98EBF><EFBFBD> packages/ # Monorepo<70><6F><EFBFBD>?
<20>? <20>?
<20>? <20><EFBFBD><E98EBF><EFBFBD> platform-core/ # 撟喳蝱<E596B3><EFBFBD><EFBFBD>虾憭滨鍂嚗?
<20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> auth/ # <20><EFBFBD>霈方<E99C88>
<20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> storage/ # 摮睃<E691AE><E79D83>滚𦛚
<20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> monitoring/ # <20>烐綉<E78390><EFBFBD>
<20>? <20>? <20><EFBFBD><E5A999><EFBFBD> index.ts
<20>? <20>?
<20>? <20><EFBFBD><E98EBF><EFBFBD> capabilities-core/ # <20>𡁶鍂<F0A181B6><EFBFBD><E8B3A2><EFBFBD><EFBFBD>虾憭滨鍂嚗?
<20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> llm-gateway/ # LLM蝵穃<E89DB5>
<20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> document-processor/ # <20><>﹝憭<EFB99D><E686AD>
<20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> rag-engine/ # RAG撘閙<E69298>
<20>? <20>? <20><EFBFBD><E5A999><EFBFBD> index.ts
<20>? <20>?
<20>? <20><EFBFBD><E98EBF><EFBFBD> module-aia/ # AI<41><EFBFBD><E79285>
<20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> backend/
<20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> frontend/
<20>? <20>? <20><EFBFBD><E5A999><EFBFBD> package.json
<20>? <20>?
<20>? <20><EFBFBD><E98EBF><EFBFBD> module-asl/ # AI<41><49>讃璅<E79285>
<20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> backend/
<20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> frontend/
<20>? <20>? <20><EFBFBD><E5A999><EFBFBD> package.json
<20>? <20>?
<20>? <20><EFBFBD><E98EBF><EFBFBD> module-review/ # 摰∠阮蝟餌<E89D9F><E79285>
<20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> backend/
<20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> frontend/
<20>? <20>? <20><EFBFBD><E5A999><EFBFBD> package.json
<20>? <20>?
<20>? <20><EFBFBD><E5A999><EFBFBD> ...
<20>?
<20><EFBFBD><E98EBF><EFBFBD> products/ # <20><EFBFBD>鈭批<E988AD><E689B9><EFBFBD>
<20>? <20>?
<20>? <20><EFBFBD><E98EBF><EFBFBD> review-system/ # 摰∠阮蝟餌<E89D9F><E9A48C><EFBFBD>鈭批<E988AD> 潃?
<20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> docker-compose.yml
<20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> deploy.sh
<20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> README.md
<20>? <20>? <20><EFBFBD><E5A999><EFBFBD> package.json # 靘肽<E99D98><E882BD>喟頂
<20>? <20>?
<20>? <20><EFBFBD><E98EBF><EFBFBD> literature-system/ # AI<41><49><EFBFBD><EFBFBD>鈭批<E988AD> 潃?
<20>? <20>? <20><EFBFBD><E5A999><EFBFBD> ...
<20>? <20>?
<20>? <20><EFBFBD><E5A999><EFBFBD> full-platform/ # 摰峕㟲撟喳蝱
<20>? <20><EFBFBD><E5A999><EFBFBD> ...
<20>?
<20><EFBFBD><E5A999><EFBFBD> ...
```
---
#### Step 2: 靘肽<E99D98>蝞∠<E89D9E>嚗īackage.json嚗?
**摰∠阮蝟餌<E89D9F><E9A48C><EFBFBD>鈭批<E988AD><E689B9><EFBFBD><EFBFBD>韏吔<E99F8F>**
```json
// products/review-system/package.json
{
"name": "@yizhengxun/review-system",
"version": "1.0.0",
"private": true,
"dependencies": {
// 撟喳蝱<E596B3><EFBFBD><EFBFBD><E59A97><EFBFBD><EFBFBD>嚗?
"@yizhengxun/platform-core": "workspace:*",
// <20>𡁶鍂<F0A181B6><EFBFBD><EFBFBD><E59A97><EFBFBD><EFBFBD>嚗?
"@yizhengxun/capabilities-core": "workspace:*",
// 銝𡁜𦛚璅<E79285>
"@yizhengxun/module-review": "workspace:*"
},
"scripts": {
"build": "node build.js",
"deploy": "sh deploy.sh"
}
}
```
**撟喳蝱<E596B3><EFBFBD><E8A9A8><EFBFBD><EFBFBD>㗇𥋘<E39787>批紡<E689B9><EFBFBD>**
```typescript
// packages/platform-core/index.ts
// 摰峕㟲撖澆枂嚗<E69E82>鍂鈭𤾸<E988AD><F0A4BEB8>游像<E6B8B8><EFBFBD>
export * from './auth';
export * from './storage';
export * from './monitoring';
export * from './notification';
// 蝎曄<E89D8E>撖澆枂嚗<E69E82>鍂鈭𡒊𡠺蝡衤漣<E8A1A4><E6BCA3><EFBFBD>
export {
// <20>芸紡<E88AB8><EFBFBD><E7AE8F><EFBFBD><EFBFBD><EFBFBD>恕霂<E68195><E99C82><EFBFBD>?
authMiddleware,
jwtService
} from './auth';
export {
// <20>芸紡<E88AB8><EFBFBD><E7AE8F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E585B8>?
uploadFile,
downloadFile
} from './storage';
export {
// <20>芸紡<E88AB8><EFBFBD><E7AE8F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E689B9>?
logError,
logAudit
} from './monitoring';
```
---
#### Step 3: <20><EFBFBD><E69E8F>𡁏𧋦
**摰∠阮蝟餌<E89D9F><E9A48C><EFBFBD><E7A589><EFBFBD>嚗?*
```javascript
// products/review-system/build.js
const { build } = require('esbuild');
const { dependencies } = require('./package.json');
async function buildReviewSystem() {
console.log('<27><>遣摰∠阮蝟餌<E89D9F><E9A48C><EFBFBD>鈭批<E988AD>...');
// 1. <20><><EFBFBD>𡒊垢
await build({
entryPoints: ['../../packages/module-review/backend/src/index.ts'],
bundle: true,
platform: 'node',
target: 'node18',
outfile: 'dist/backend/index.js',
external: ['pg', 'fastify', 'prisma'], // 銝齿<E98A9D><E9BDBF><EFBFBD><EFBFBD>鈭𥕦之摨?
// <20>芸𢆡<E88AB8><F0A286A1>鉄靘肽<E99D98>
plugins: [
// <20>芸𢆡閫<F0A286A1><E996AB>workspace靘肽<E99D98>
resolveWorkspaceDependencies()
]
});
// 2. <20><><EFBFBD>滨垢
await build({
entryPoints: ['../../packages/module-review/frontend/src/main.tsx'],
bundle: true,
platform: 'browser',
outfile: 'dist/frontend/index.js',
loader: { '.tsx': 'tsx' }
});
// 3. 憭滚<E686AD><EFBFBD><E695B9><EFBFBD><EFBFBD>
copyFiles([
'docker-compose.yml',
'README.md',
'deploy.sh'
]);
console.log('<EFBFBD><EFBFBD>遣摰峕<EFBFBD>?);
}
buildReviewSystem();
```
---
#### Step 4: Docker<65>函蔡<E587BD>滨蔭
**摰∠阮蝟餌<E89D9F><E9A48C><EFBFBD><E7A589>函蔡嚗?*
```yaml
# products/review-system/docker-compose.yml
version: '3.8'
services:
# PostgreSQL<51>唳旿摨橒<E691A8><E6A992><EFBFBD>嚗?
postgres:
image: postgres:15-alpine
container_name: review-system-postgres
environment:
POSTGRES_DB: review_system
POSTGRES_USER: review
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- review-network
# <20>𡒊垢<F0A1928A>滚𦛚嚗<F0A69B9A><E59A97><EFBFBD>怠像<E680A0><EFBFBD><E595A3><EFBFBD>𡁶鍂<F0A181B6><EFBFBD><EFBFBD><E69285>
backend:
build:
context: ./dist/backend
container_name: review-system-backend
environment:
DATABASE_URL: postgresql://review:${DB_PASSWORD}@postgres:5432/review_system
LLM_API_KEY: ${LLM_API_KEY}
depends_on:
- postgres
networks:
- review-network
# <20>滨垢<E6BBA8>滚𦛚
frontend:
build:
context: ./dist/frontend
container_name: review-system-frontend
ports:
- "80:80"
depends_on:
- backend
networks:
- review-network
volumes:
postgres_data:
networks:
review-network:
driver: bridge
```
---
#### Step 5: 銝<><E98A9D><EFBFBD>蝵脰<E89DB5><E884B0>?
```bash
#!/bin/bash
# products/review-system/deploy.sh
echo "======================================"
echo " 摰∠阮蝟餌<E89D9F><E9A48C><EFBFBD><E7A589>函蔡<E587BD>𡁏𧋦"
echo "======================================"
# 1. 璉<><E79289>主ocker
if ! command -v docker &> /dev/null; then
echo "<22>躰秤嚗𡁏𧊋摰㕑<E691B0>Docker"
exit 1
fi
# 2. 霈曄蔭<E69B84><EFBFBD><E887AC><EFBFBD>
read -p "霂瑁<E99C82><E79181>交㺭<E4BAA4><EFBFBD><EFBFBD><E69296>: " DB_PASSWORD
read -p "霂瑁<E99C82><E79181>他LM API撖<49>𤨎: " LLM_API_KEY
export DB_PASSWORD
export LLM_API_KEY
# 3. <20>臬𢆡<E887AC>滚𦛚
docker-compose up -d
# 4. 蝑匧<E89D91><E58CA7>滚𦛚<E6BB9A>臬𢆡
echo "蝑匧<E89D91><E58CA7>滚𦛚<E6BB9A>臬𢆡..."
sleep 10
# 5. <20><EFBFBD><E598A5>𡝗㺭<F0A19D97><EFBFBD>
docker exec review-system-backend npx prisma migrate deploy
# 6. <20>𥕦遣暺䁅恕蝞∠<E89D9E><E288A0>?
docker exec review-system-backend node scripts/create-admin.js
echo "======================================"
echo " <20>函蔡摰峕<E691B0>嚗?
echo " 霈輸䔮<E8BCB8><EFBFBD>嚗冴ttp://localhost"
echo " 蝞∠<E89D9E><E288A0>䁅揭<E48185><EFBFBD>admin@review.com"
echo "<><E69296>嚗惨dmin123嚗<33><EFBFBD>𦠜𧒄靽格㺿嚗?
echo "======================================"
```
---
### <20>喲睸<E596B2><E79DB8><EFBFBD><EFBFBD>
#### 1. 撟喳蝱撅<E89DB1><E69285>蝎曄<E89D8E><E69B84><EFBFBD><E5B1B8><EFBFBD>
**摰峕㟲撟喳蝱<E596B3><E89DB1><EFBFBD>瑁恕霂<E68195><E99C82>憭齿<E686AD>嚗㚁<E59A97>**
```typescript
// 摰峕㟲撟喳蝱
- 𡁶<EFBFBD><EFBFBD>𣈲<EFBFBD>?
- RBAC<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
- SSO<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
- <EFBFBD><EFBFBD>𤏪<EFBFBD><EFBFBD><EFBFBD><EFBFBD>𡁜<EFBFBD>?
- 齿<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
```
**摰∠阮蝟餌<E89D9F><E9A48C><EFBFBD><EFBFBD>瑁恕霂<E68195><E99C82><EFBFBD><E89D9E><EFBFBD>嚗?*
```typescript
// 摰∠阮蝟餌<E89D9F><E9A48C><EFBFBD>鈭批<E988AD>
- <EFBFBD><EFBFBD>𣇉<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<EFBFBD><EFBFBD>?
- <EFBFBD><EFBFBD><EFBFBD>𠧧<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
- <EFBFBD><EFBFBD>JWT<EFBFBD><EFBFBD>oken霈方<EFBFBD>
- <EFBFBD>SO<EFBFBD><EFBFBD><EFBFBD>𡁶<EFBFBD><EFBFBD>?
```
**摰䂿緵<E482BF><EFBFBD>嚗?*
```typescript
// packages/platform-core/auth/simple-auth.ts
// 銝箇𡠺蝡衤漣<E8A1A4><E6BCA3><EFBFBD>靘𤤿<E99D98><F0A4A4BF>𣇉<EFBFBD>霈方<E99C88>
export class SimpleAuthService {
// <20><EFBFBD><E88AAF>蹱瓲敹<E793B2><E695B9><EFBFBD>?
async login(email: string, password: string) { }
async register(email: string, password: string) { }
async verifyToken(token: string) { }
async logout(userId: string) { }
// 蝘駁膄憭齿<E686AD><E9BDBF><EFBFBD>
// <20>?async loginWithWeChat()
// <20>?async setupSSO()
// <20>?async multiTenantCheck()
}
```
---
#### 2. <20>𡁶鍂<F0A181B6><EFBFBD><EFBFBD><E69285>蝎曄<E89D8E><E69B84><EFBFBD><E5B1B8><EFBFBD>
**摰峕㟲撟喳蝱<E596B3><E89DB1>LM蝵穃<E89DB5><EFBFBD><E59A97><EFBFBD><EFBFBD><EFBFBD>嚗?*
```typescript
// 摰峕㟲撟喳蝱
- <EFBFBD><EFBFBD>10+齿<EFBFBD>?
- Feature Flag<EFBFBD><EFBFBD>
- <EFBFBD><EFBFBD><EFBFBD>
- <EFBFBD>𧋦<EFBFBD><EFBFBD><EFBFBD>
- A/B瘚贝<EFBFBD>
```
**摰∠阮蝟餌<E89D9F><E9A48C><EFBFBD>LM蝵穃<E89DB5><EFBFBD><E59A97><EFBFBD><EFBFBD>嚗?*
```typescript
// 摰∠阮蝟餌<E89D9F><E9A48C><EFBFBD>鈭批<E988AD>
- <EFBFBD>𣈲<EFBFBD>?-2齿<EFBFBD><EFBFBD>DeepSeek + Claude嚗?
- <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
- <EFBFBD>eature Flag
- <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
```
**摰䂿緵<E482BF><EFBFBD>嚗?*
```typescript
// packages/capabilities-core/llm-gateway/simple-llm.ts
export class SimpleLLMGateway {
// <20><EFBFBD><E88AAF>蹱瓲敹<E793B2><E695B9><EFBFBD>?
async chat(params: ChatParams) { }
async checkQuota(userId: string) { }
// 蝘駁膄憭齿<E686AD><E9BDBF><EFBFBD>
// <20>?async getCostStats()
// <20>?async selectModelByVersion()
// <20>?async runABTest()
}
```
---
#### 3. <20>唳旿摨梶<E691A8><E6A2B6>𠉛氖
**摰峕㟲撟喳蝱<E596B3><E89DB1><EFBFBD><EFBFBD><EFBFBD><E59A97><EFBFBD><EFBFBD><EFBFBD>嚗?*
```sql
-- 撟喳蝱撅<E89DB1>chema
platform_schema.users
platform_schema.tenants
platform_schema.feature_flags
-- ...
-- <20><><EFBFBD>㗇芋<E39787>𣶷chema
aia_schema.*
asl_schema.*
review_schema.*
-- ...
```
**摰∠阮蝟餌<E89D9F><E9A48C><EFBFBD>鈭批<E988AD><E689B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E59A97><EFBFBD><EFBFBD>嚗?*
```sql
-- <20><EFBFBD><E88AB8><EFBFBD><E680A0><EFBFBD><EFBFBD><EFBFBD>
CREATE DATABASE review_system;
-- 蝞<><E89D9E>𣇉<EFBFBD><F0A38789><EFBFBD>銵?
CREATE TABLE users (
id UUID PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
role VARCHAR(50) NOT NULL, -- admin/editor/reviewer
created_at TIMESTAMP DEFAULT NOW()
);
-- 摰∠阮蝟餌<E89D9F><E9A48C><EFBFBD><EFBFBD><EFBFBD>∟”
CREATE TABLE review_tasks (...);
CREATE TABLE review_journals (...);
CREATE TABLE review_reviewers (...);
-- ...
```
---
### <20><EFBFBD>鈭批<E988AD><E689B9><EFBFBD><EFBFBD><EFBFBD>?
| 隡睃飵 | 霂湔<E99C82> |
|------|------|
| **<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?* | <20>臭誑<E887AD>閧𡠺摰帋遠<E5B88B><E981A0><EFBFBD><EFBFBD><EFBFBD><E7A587>?|
| **<EFBFBD><EFBFBD><EFBFBD>函蔡** | 摰<E691B0><EFBCB8>臭誑<E887AD>砍𧑐<E7A08D><EFBFBD>蝵莎<E89DB5><E88E8E>唳旿摰<E697BF><E691B0><EFBFBD>𠉛氖 |
| **<EFBFBD><EFBFBD><EFBFBD><EFBFBD>漣** | 銝滚蔣<E6BB9A><EFBFBD>隞𡝗芋<F0A19D97>?|
| **頧駁<E9A0A7><E9A781>?* | <20><EFBFBD><E88AB8><EFBFBD><E680A0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E59A97>雿梶妖撠?|
| **摰𡁜<E691B0><F0A1819C>?* | <20>臭誑<E887AD><E8AA91><EFBFBD><EFBFBD><E691B0>摰𡁜<E691B0> |
---
## <20>𣑐 <20><EFBFBD>鈭䕘<E988AD><E49598>曹澈<E69BB9>滚𦛚嚗<F0A69B9A><EFBFBD>鞟鍂鈭𤾸像<F0A4BEB8><EFBFBD><E79285>嚗?
### <20><><EFBFBD>箸艶
- <20>?<3F><EFBFBD><E691B0>韐凋僭憭帋葵璅<E79285>
- <20>?鈭𤑳垢SaaS<61>函蔡
- <20>?璅<E79285>銋钅𡢿<E99285><F0A1A2BF><EFBFBD><E996AC>鈭怎鍂<E6808E><EFBFBD><E79195>唳旿
### <20><EFBFBD><E8A9A8>肽楝
**撟喳蝱撅<E89DB1><E69285><EFBFBD>𡁶鍂<F0A181B6><EFBFBD><EFBFBD><E69285>銝箏<E98A9D>鈭急<E988AD><E680A5>?*
```
摰峕㟲撟喳蝱<EFBFBD><EFBFBD><EFBFBD><EFBFBD>滚𦛚<EFBFBD><EFBFBD><EFBFBD>嚗?
<EFBFBD>𢞖<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
<EFBFBD>? API蝵穃<E89DB5>嚗𠃋ong/Traefik嚗? <20>?
<EFBFBD>? 頝舐眏嚗?aia/* /asl/* /review/* <20>?
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
<20>? <20>? <20>?
<20>? <20>? <20>?
<EFBFBD>𢞖<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>𢞖<EFBFBD><F0A29E96><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>𢞖<EFBFBD><F0A29E96><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
<EFBFBD>?AIA璅<E79285><E288AA>滚𦛚 <20>?<3F>?ASL璅<E79285><E288AA>滚𦛚 <20>?<3F>?RVW璅<E79285><E288AA>滚𦛚 <20>?
<EFBFBD>?(<28><EFBFBD><E7A589>函蔡) <20>?<3F>?(<28><EFBFBD><E7A589>函蔡) <20>?<3F>?(<28><EFBFBD><E7A589>函蔡) <20>?
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F><EFBFBD><E5A999><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F><EFBFBD><E5A999><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
<20>? <20>? <20>?
<20><EFBFBD><E5A999><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E6B0AF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
<20>?
<20>𢞖<EFBFBD><F0A29E96><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
<20>? <20>曹澈<E69BB9>滚𦛚嚗<F0A69B9A><EFBFBD><EFBFBD>嚗? <20>?
<20>? - <20><EFBFBD>霈方<E99C88><E696B9>滚𦛚 <20>?
<20>? - 摮睃<E691AE><E79D83>滚𦛚 <20>?
<20>? - <20>烐綉<E78390>滚𦛚 <20>?
<20><EFBFBD><E5A999><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
<20>?
<20>𢞖<EFBFBD><F0A29E96><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
<20>? <20>曹澈<E69BB9>滚𦛚嚗<F0A69B9A><E59A97>𡁶鍂<F0A181B6><EFBFBD><EFBFBD><E69285> <20>?
<20>? - LLM蝵穃<E89DB5><E7A983>滚𦛚 <20>?
<20>? - <20><>﹝憭<EFB99D><E686AD><EFBFBD>滚𦛚 <20>?
<20>? - RAG撘閙<E69298><E99699>滚𦛚 <20>?
<20><EFBFBD><E5A999><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
<20>?
<20>𢞖<EFBFBD><F0A29E96><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
<20>? <20>曹澈<E69BB9>唳旿摨? <20>?
<20>? - PostgreSQL (憭锭chema) <20>?
<20><EFBFBD><E5A999><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
```
---
### <20><><EFBFBD><EFBFBD><E887AC>?
#### Step 1: <20>滚𦛚<E6BB9A><F0A69B9A><EFBFBD>
**撟喳蝱<E596B3><EFBFBD><E7AE87>滚𦛚嚗<F0A69B9A>𡠺蝡钅<E89DA1>蝵莎<E89DB5>嚗?*
```yaml
# services/platform/docker-compose.yml
services:
# <20><EFBFBD>霈方<E99C88><E696B9>滚𦛚
auth-service:
image: yizhengxun/auth-service:latest
ports:
- "3001:3000"
environment:
DATABASE_URL: ${DATABASE_URL}
JWT_SECRET: ${JWT_SECRET}
# 摮睃<E691AE><E79D83>滚𦛚
storage-service:
image: yizhengxun/storage-service:latest
ports:
- "3002:3000"
environment:
OSS_ENDPOINT: ${OSS_ENDPOINT}
# <20>烐綉<E78390>滚𦛚
monitoring-service:
image: yizhengxun/monitoring-service:latest
ports:
- "3003:3000"
```
**<EFBFBD>𡁶鍂<EFBFBD><EFBFBD><EFBFBD>滚𦛚嚗<EFBFBD>𡠺蝡钅<EFBFBD>蝵莎<EFBFBD>嚗?*
```yaml
# services/capabilities/docker-compose.yml
services:
# LLM蝵穃<E89DB5><E7A983>滚𦛚
llm-gateway:
image: yizhengxun/llm-gateway:latest
ports:
- "3010:3000"
environment:
DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY}
QWEN_API_KEY: ${QWEN_API_KEY}
# <20><>﹝憭<EFB99D><E686AD><EFBFBD>滚𦛚
document-processor:
image: yizhengxun/document-processor:latest
ports:
- "3011:3000"
# RAG撘閙<E69298><E99699>滚𦛚
rag-engine:
image: yizhengxun/rag-engine:latest
ports:
- "3012:3000"
```
**銝𡁜𦛚璅<E79285><E288AA>滚𦛚嚗<F0A69B9A>𡠺蝡钅<E89DA1>蝵莎<E89DB5>嚗?*
```yaml
# services/modules/review-system/docker-compose.yml
services:
review-system:
image: yizhengxun/review-system:latest
ports:
- "4001:3000"
environment:
# 靘肽<E99D98><E882BD>曹澈<E69BB9>滚𦛚
AUTH_SERVICE_URL: http://auth-service:3000
STORAGE_SERVICE_URL: http://storage-service:3000
LLM_GATEWAY_URL: http://llm-gateway:3000
DOCUMENT_PROCESSOR_URL: http://document-processor:3000
# <20>芸楛<E88AB8><E6A59B><EFBFBD><EFBFBD>Schema
DATABASE_URL: postgresql://user:pass@postgres:5432/platform?schema=review_schema
```
---
#### Step 2: API蝵穃<E89DB5><E7A983>滨蔭
**Kong API蝵穃<E89DB5><E7A983>滨蔭嚗?*
```yaml
# api-gateway/kong.yml
_format_version: "3.0"
services:
# <20><EFBFBD>霈方<E99C88><E696B9>滚𦛚
- name: auth-service
url: http://auth-service:3000
routes:
- name: auth-routes
paths:
- /api/auth
# 摰∠阮蝟餌<E89D9F><E79285>
- name: review-system
url: http://review-system:3000
routes:
- name: review-routes
paths:
- /api/review
plugins:
- name: jwt
config:
secret_is_base64: false
key_claim_name: kid
# AI<41><49>讃璅<E79285>
- name: literature-system
url: http://literature-system:3000
routes:
- name: literature-routes
paths:
- /api/literature
plugins:
- name: jwt
```
---
#### Step 3: <20>滚𦛚<E6BB9A><EFBFBD>帋縑
**銝𡁜𦛚璅<E79285><EFBFBD><EFBFBD>曹澈<E69BB9>滚𦛚嚗?*
```typescript
// packages/module-review/backend/src/services/review.service.ts
import { AuthClient } from '@yizhengxun/platform-core/clients';
import { LLMClient } from '@yizhengxun/capabilities-core/clients';
export class ReviewService {
private authClient: AuthClient;
private llmClient: LLMClient;
constructor() {
// 餈墧𦻖<E5A2A7><EFBFBD>鈭急<E988AD><E680A5>?
this.authClient = new AuthClient({
baseURL: process.env.AUTH_SERVICE_URL
});
this.llmClient = new LLMClient({
baseURL: process.env.LLM_GATEWAY_URL
});
}
async createReviewTask(userId: string, file: File) {
// 1. 撉諹<E69289><E8ABB9><EFBFBD><EFBFBD><E59A97><EFBFBD><EFBFBD>鈭怨恕霂<E68195><E99C82><EFBFBD><EFBFBD>
const user = await this.authClient.verifyUser(userId);
// 2. 銝𠹺<E98A9D><F0A0B9BA><EFBFBD>辣嚗<E8BEA3><E59A97><EFBFBD><EFBFBD>鈭怠<E988AD><E680A0><EFBFBD><E586BD><EFBFBD>
const fileUrl = await this.storageClient.upload(file);
// 3. AI<41><49><EFBFBD><EFBFBD><E59A97><EFBFBD><EFBFBD>鈭俠LM蝵穃<E89DB5>嚗?
const analysis = await this.llmClient.chat({
messages: [{ role: 'user', content: `<EFBFBD><EFBFBD><EFBFBD>餈嗵<EFBFBD>蝔蹂辣: ${fileUrl}` }]
});
// 4. 靽嘥<E99DBD><E598A5>啗䌊撌梁<E6928C><E6A281>唳旿摨?
const task = await prisma.reviewTask.create({
data: {
userId,
fileUrl,
analysis: analysis.content
}
});
return task;
}
}
```
---
### 璅<E79285><E288AA><EFBFBD><E7A589>函蔡<E587BD><E894A1>郊撉?
**1. <20>函蔡<E587BD>曹澈<E69BB9>滚𦛚嚗<F0A69B9A><E59A97>甈⊥<E79488><EFBFBD>嚗?*
```bash
# <20>函蔡撟喳蝱<E596B3><EFBFBD><E7AE87>滚𦛚
cd services/platform
docker-compose up -d
# <20>函蔡<E587BD>𡁶鍂<F0A181B6><EFBFBD><E8B3A2>滚𦛚
cd services/capabilities
docker-compose up -d
# <20>函蔡API蝵穃<E89DB5>
cd services/api-gateway
docker-compose up -d
```
**2. <20>函蔡銝𡁜𦛚璅<E79285><EFBFBD><E59A97><EFBFBD><EFBFBD>嚗㚁<E59A97>**
```bash
# <20><EFBFBD>蝵脣恣蝔輻頂蝏<E9A082><EFBFBD>?
cd services/modules/review-system
docker-compose up -d
# 摰<E691B0>A韐凋僭鈭<E583AD>恣蝔輻頂蝏<E9A082><E89D8F><EFBFBD><EFBFBD><E88AB7>函蔡餈嗘<E9A488>銝芣芋<E88AA3>?
# <20><EFBFBD><E79285>銝漤<E98A9D><EFBFBD><E996AC>蝵?
```
**3. <20>啣恥<E595A3>瑁揚銋啣<E98A8B>隞𡝗芋<F0A19D97><EFBFBD>**
```bash
# 摰<E691B0>B韐凋僭鈭<E583AD>I<EFBFBD><49>讃璅<E79285><EFBFBD><E59A97><EFBFBD>函蔡餈嗘葵璅<E79285>
cd services/modules/literature-system
docker-compose up -d
# <20>曹澈<E69BB9>滚𦛚撌脩<E6928C><E884A9>函蔡嚗䔶<E59A97><E494B6><EFBFBD><EFBFBD><E996AC>憭漤<E686AD>蝵?
# <20><EFBFBD>憓𧼮<E68693><F0A7BCAE><EFBFBD>銝𡁜𦛚璅<E79285>
```
---
## <20>棅儭?Part 2嚗鍃lectron<6F>閙㦤<E99699><E3A6A4>䲮獢?
### 銝箔<E98A9D><EFBFBD><E98A8B><EFBFBD><E996AC><EFBFBD><EFBFBD>嚗?
**<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>**
1. **<EFBFBD>唳旿<EFBFBD><EFBFBD>**嚗𡁜龫<F0A1819C>煺葵鈭箸㺭<E7AEB8><EFBFBD><E6A190><EFBFBD>隡牐<E99AA1>蝡?
2. **蝳餌瑪雿輻鍂**嚗𡁏<E59A97><F0A1818F><EFBFBD>蝵𤑳<E89DB5>餈墧𦻖
3. **靘踵𡉼<E8B8B5>?*嚗𡁜虾隞亙銁隞颱<E99A9E><E9A2B1><EFBFBD>銝𠰴<E98A9D><EFBFBD><EFBFBD>?
4. **<EFBFBD><EFBFBD>餈鞱<EFBFBD>**嚗帋<E59A97>靘肽<E99D98>憭㚚<E686AD><E39A9A>滚𦛚<E6BB9A>?
**<EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗?*
- 銝芯犖<E88AAF><EFBFBD>
- <20>唳旿<E594B3>𤩺<EFBFBD><F0A4A9BA><EFBFBD><EFBFBD>蝛嗉<E89D9B>?
- <20><EFBFBD>蝏𦦵㴓憓<E3B493><E68693><EFBFBD>箸艶
---
### Electron<6F><EFBFBD>銝𡒊緵<F0A1928A>劐誨<E58A90><E8AAA8><EFBFBD>撖孵<E69296><E5ADB5>喟頂
#### <20><EFBFBD><E594B3><EFBFBD><EFBFBD><E59A97>蝡舐<E89DA1>嚗?
```
<EFBFBD>𢞖<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
<EFBFBD>? 瘚讛<E7989A><E8AE9B>?(Chrome) <20>?
<EFBFBD>? <20>𢞖<EFBFBD><F0A29E96><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <20>?
<EFBFBD>? <20>? <20>滨垢 (React + Vite) <20>? <20>?
<EFBFBD>? <20>? http://localhost:5173 <20>? <20>?
<EFBFBD>? <20><EFBFBD><E5A999><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <20>?
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
<20>?HTTP霂瑟<E99C82>
<EFBFBD>𢞖<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
<EFBFBD>? <20>𡒊垢 (Node.js + Fastify) <20>?
<EFBFBD>? http://localhost:3001 <20>?
<EFBFBD>? <20>𢞖<EFBFBD><F0A29E96><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <20>?
<EFBFBD>? <20>? API頝舐眏<E88890><E79C8F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E9A489><EFBFBD>risma ORM <20>? <20>?
<EFBFBD>? <20><EFBFBD><E5A999><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <20>?
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
<20>?
<EFBFBD>𢞖<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
<EFBFBD>? PostgreSQL (Docker) <20>?
<EFBFBD>? localhost:5432 <20>?
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
```
---
#### Electron<6F><EFBFBD><EFBFBD><E59A97><EFBFBD><EFBFBD>嚗?
```
<EFBFBD>𢞖<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
<EFBFBD>? Electron 摨𠉛鍂 <20>?
<EFBFBD>? <20>?
<EFBFBD>? <20>𢞖<EFBFBD><F0A29E96><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <20>?
<EFBFBD>? <20>? 皜脫<E79A9C>餈𤤿<E9A488> (Chromium) <20>? <20>?
<EFBFBD>? <20>? <20>𢞖<EFBFBD><F0A29E96><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <20>? <20>?
<EFBFBD>? <20>? <20>? <20>滨垢 (React) 潃?憭滨鍂<E6BBA8><EFBFBD><EFBFBD><E99A9E> <20>? <20>? <20>?
<EFBFBD>? <20>? <20>? file://app/index.html <20>? <20>? <20>?
<EFBFBD>? <20>? <20><EFBFBD><E5A999><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <20>? <20>?
<EFBFBD>? <20><EFBFBD><E5A999><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <20>?
<EFBFBD>? <20>?IPC<50>帋縑 <20>?
<EFBFBD>? <20>𢞖<EFBFBD><F0A29E96><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <20>?
<EFBFBD>? <20>? 銝餉<E98A9D>蝔?(Node.js) <20>? <20>?
<EFBFBD>? <20>? <20>𢞖<EFBFBD><F0A29E96><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <20>? <20>?
<EFBFBD>? <20>? <20>? API<50><EFBFBD><E9A489><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 潃?憭滨鍂<E6BBA8><EFBFBD><EFBFBD><E99A9E> <20>? <20>? <20>?
<EFBFBD>? <20>? <20>? Prisma ORM<52><4D>𧋦<EFBFBD><EFBFBD>隞嗥頂蝏? <20>? <20>? <20>?
<EFBFBD>? <20>? <20><EFBFBD><E5A999><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <20>? <20>?
<EFBFBD>? <20><EFBFBD><E5A999><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <20>?
<EFBFBD>? <20>? <20>?
<EFBFBD>? <20>𢞖<EFBFBD><F0A29E96><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <20>?
<EFBFBD>? <20>? SQLite (撋<><E6928B>撘𤩺㺭<F0A4A9BA><EFBFBD>) <20>? <20>?
<EFBFBD>? <20>? ~/Documents/YizhengxunData/app.db <20>? <20>?
<EFBFBD>? <20><EFBFBD><E5A999><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <20>?
<EFBFBD>? <20>?
<EFBFBD>? <20>𢞖<EFBFBD><F0A29E96><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <20>?
<EFBFBD>? <20>? 摮鞱<E691AE>蝔?(Python/R) <20>? <20>?
<EFBFBD>? <20>? <20><><EFBFBD>𣂼<EFBFBD><F0A382BC><EFBFBD><EFBFBD><EFBFBD><E6A180>? <20>? <20>?
<EFBFBD>? <20><EFBFBD><E5A999><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <20>?
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
```
---
### <20><EFBFBD><E8A9A8><EFBFBD><EFBFBD>舀䲮獢?
#### 1. <20>滨垢隞<E59EA2><E99A9E>憭滨鍂嚗?0%+ 憭滨鍂嚗?
**<EFBFBD><EFBFBD><EFBFBD>滨垢隞<EFBFBD><EFBFBD>嚗Áeb<EFBFBD><EFBFBD><EFBFBD>嚗?*
```typescript
// frontend/src/api/client.ts
const API_BASE_URL = 'http://localhost:3001';
export const apiClient = {
async get(url: string) {
return fetch(`${API_BASE_URL}${url}`);
},
async post(url: string, data: any) {
return fetch(`${API_BASE_URL}${url}`, {
method: 'POST',
body: JSON.stringify(data)
});
}
};
```
**Electron<6F><6E><EFBFBD>蝡荔<E89DA1>靽格㺿API靚<49><EFBFBD><EFBFBD>嚗㚁<E59A97>**
```typescript
// electron-frontend/src/api/client.ts
// 雿輻鍂Electron<6F><6E>PC<50>帋縑嚗諹<E59A97><EFBFBD><E494B6>浹TTP
const { ipcRenderer } = window.require('electron');
export const apiClient = {
async get(url: string) {
// <20><EFBFBD>IPC<50><EFBFBD><E785BE><EFBFBD>銝餉<E98A9D>蝔?
return ipcRenderer.invoke('api-request', {
method: 'GET',
url
});
},
async post(url: string, data: any) {
return ipcRenderer.invoke('api-request', {
method: 'POST',
url,
data
});
}
};
```
**React蝏<74>辣摰<E8BEA3><E691B0>銝漤<E98A9D><EFBFBD>㺿嚗?*
```typescript
// 銝𡁜𦛚蝏<F0A69B9A>辣摰<E8BEA3><E691B0>銝滚<E98A9D> <20>?
function UserList() {
const [users, setUsers] = useState([]);
useEffect(() => {
// API靚<49><EFBFBD><EFBFBD>銝滚<E98A9D><EFBFBD><E59A97><EFBFBD><EFBFBD><EFBFBD><E588B8><EFBFBD>
apiClient.get('/api/users').then(setUsers);
}, []);
return <div>{/* ... */}</div>;
}
```
**憭滨鍂<E6BBA8><E98D82><EFBFBD>90%+ <20>?*
- <20>?<3F><><EFBFBD>兴eact蝏<74>
- <20>?<3F><><EFBFBD>务I摨橒<E691A8>Ant Design嚗?
- <20>?<3F><><EFBFBD>厩𠶖<E58EA9><F0A0B696><EFBFBD><E681A3><EFBFBD>Zustand嚗?
- <20>?<3F><><EFBFBD>㕑楝<E39591><EFBFBD>React Router嚗?
- <20>𩤃<EFBFBD> <20><EFBFBD>靽格㺿API靚<49>鍂撅<E98D82><E69285>1銝芣<E98A9D>隞塚<E99A9E>
---
#### 2. <20>𡒊垢隞<E59EA2><E99A9E>憭滨鍂嚗?0%+ 憭滨鍂嚗?
**<EFBFBD><EFBFBD><EFBFBD>𡒊垢隞<EFBFBD><EFBFBD>嚗Áeb<EFBFBD><EFBFBD><EFBFBD>嚗?*
```typescript
// backend/src/routes/users.ts
import { FastifyInstance } from 'fastify';
export async function userRoutes(fastify: FastifyInstance) {
// GET /api/users
fastify.get('/api/users', async (request, reply) => {
const users = await prisma.user.findMany();
return users;
});
// POST /api/users
fastify.post('/api/users', async (request, reply) => {
const user = await prisma.user.create({
data: request.body
});
return user;
});
}
```
**Electron<6F><6E><EFBFBD>蝡荔<E89DA1>銝餉<E98A9D>蝔页<E89D94>嚗?*
```typescript
// electron-backend/src/ipc-handlers.ts
import { ipcMain } from 'electron';
import { prisma } from './prisma-client';
// 憭滨鍂銝𡁜𦛚<F0A1819C><EFBFBD> 潃?
import { UserService } from '../../../backend/src/services/user.service';
export function setupIpcHandlers() {
const userService = new UserService(prisma);
// 撠<>TTP頝舐眏頧祆揢銝截PC Handler
ipcMain.handle('api-request', async (event, { method, url, data }) => {
// 頝舐眏<E88890><E79C8F><EFBFBD><EFBFBD><E59A97><EFBFBD>𣇉<EFBFBD><F0A38789><EFBFBD>astify嚗?
if (url === '/api/users' && method === 'GET') {
return userService.findAll();
}
if (url === '/api/users' && method === 'POST') {
return userService.create(data);
}
// ... <20><EFBFBD>頝舐眏
});
}
```
**<EFBFBD><EFBFBD>銝𡁜𦛚<EFBFBD><EFBFBD><EFBFBD><EFBFBD>憭滨鍂嚗?*
```typescript
// backend/src/services/user.service.ts
// 餈嗘葵<E59798><E891B5><EFBFBD>汾eb<65><62><EFBFBD>Electron<6F><6E><EFBFBD><EFBFBD><EFBFBD>鈭?<3F>?
export class UserService {
constructor(private prisma: PrismaClient) {}
async findAll() {
return this.prisma.user.findMany();
}
async create(data: CreateUserDto) {
// 銝𡁜𦛚<F0A1819C><EFBFBD>
const hashedPassword = await bcrypt.hash(data.password, 10);
return this.prisma.user.create({
data: {
...data,
password: hashedPassword
}
});
}
}
```
**憭滨鍂<E6BBA8><E98D82><EFBFBD>80%+ <20>?*
- <20>?<3F><><EFBFBD>农ervice撅<65><E69285>銝𡁜𦛚<F0A1819C><EFBFBD>嚗?
- <20>?<3F><><EFBFBD>侨risma Model<65>峕䰻霂?
- <20>?<3F><><EFBFBD>匧極<E58CA7>瑕遆<E79195>?
- <20>𩤃<EFBFBD> <20><><EFBFBD><E996AC><EFBFBD><EFBFBD>嚗䥅TTP頝舐眏 <20>?IPC Handler
- <20>𩤃<EFBFBD> <20><><EFBFBD>𤜯<EFBFBD><EFBFBD>PostgreSQL <20>?SQLite
---
#### 3. <20>唳旿摨㯄<E691A8><E3AF84><EFBFBD>嚗㇊ostgreSQL <20>?SQLite嚗?
**Prisma Schema靽格㺿嚗<E3BABF><E59A97>撠𤩺㺿<F0A4A9BA><EFBFBD>嚗?*
```prisma
// electron-backend/prisma/schema.prisma
datasource db {
// Web<65><62><EFBFBD>PostgreSQL
// provider = "postgresql"
// url = env("DATABASE_URL")
// Electron<6F><6E><EFBFBD>SQLite 潃?
provider = "sqlite"
url = "file:./app.db"
}
// Model摰帋<E691B0><EFBFBD><E691B0>銝滚<E98A9D> <20>?
model User {
id String @id @default(uuid())
email String @unique
password String
name String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@map("users")
}
```
**瘜冽<E7989C>鈭钅★嚗?*
```typescript
// SQLite銝齿𣈲<E9BDBF><F0A388B2><EFBFBD>鈭𢏺ostgreSQL<51><EFBFBD>?
// <20>?PostgreSQL<51><EFBFBD>嚗玺QLite銝齿𣈲<E9BDBF><F0A388B2><EFBFBD>
- JSON<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>TEXT摮睃<EFBFBD>?
- 齿<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
- <EFBFBD>𣂷<EFBFBD><EFBFBD>𡁜<EFBFBD><EFBFBD>
// <20>?閫<><E996AB><EFBFBD><EFBFBD>嚗?
// 1. <20>汽EXT摮睃<E691AE>JSON嚗<4E><E59A97><EFBFBD><EFBFBD><E585B8><EFBFBD>嚗?
model Config {
id String @id
data String // JSON.stringify(data)
}
// 2. 蝞<><E89D9E>𡝗䰻霂<E99C82><EFBD87><EFBFBD>憭齿<E686AD>SQL嚗?
// 3. <20><EFBFBD><E585B8><EFBFBD>摰䂿緵<E482BF>𣂷<EFBFBD><F0A382B7><EFBFBD>
```
---
### 摰峕㟲憿寧𤌍蝏𤘪<E89D8F>
```
AIclinicalresearch/
<20><EFBFBD><E98EBF><EFBFBD> packages/ # <20>曹澈隞<E6BE88><E99A9E>嚗㇈onorepo嚗?
<20>? <20><EFBFBD><E98EBF><EFBFBD> frontend-core/ # <20>滨垢<E6BBA8><EFBFBD>嚗Áeb + Electron憭滨鍂嚗?
<20>? <20><EFBFBD><E98EBF><EFBFBD> backend-core/ # <20>𡒊垢<F0A1928A><EFBFBD>嚗Áeb + Electron憭滨鍂嚗?
<20>? <20><EFBFBD><E5A999><EFBFBD> shared-types/ # <20>曹澈蝐餃<E89D90>摰帋<E691B0>
<20>?
<20><EFBFBD><E98EBF><EFBFBD> apps/
<20>? <20><EFBFBD><E98EBF><EFBFBD> web/ # Web<65><62><EFBFBD>敶枏<E695B6>嚗?
<20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> frontend/
<20>? <20>? <20><EFBFBD><E5A999><EFBFBD> backend/
<20>? <20>?
<20>? <20><EFBFBD><E5A999><EFBFBD> electron/ # Electron<6F>?潃?
<20>? <20><EFBFBD><E98EBF><EFBFBD> main/ # 銝餉<E98A9D>蝔页<E89D94>Node.js<6A>𡒊垢嚗?
<20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> src/
<20>? <20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> main.ts # Electron<6F>亙藁
<20>? <20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> ipc-handlers.ts # IPC憭<43><E686AD><EFBFBD>?
<20>? <20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> services/ # 憭滨鍂backend-core
<20>? <20>? <20>? <20><EFBFBD><E5A999><EFBFBD> prisma/
<20>? <20>? <20>? <20><EFBFBD><E5A999><EFBFBD> schema.prisma # SQLite<74><65>𧋦
<20>? <20>? <20><EFBFBD><E5A999><EFBFBD> package.json
<20>? <20>?
<20>? <20><EFBFBD><E98EBF><EFBFBD> renderer/ # 皜脫<E79A9C>餈𤤿<E9A488>嚗㇌eact<63>滨垢嚗?
<20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> src/
<20>? <20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> main.tsx
<20>? <20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> api/ # IPC摰<E691B0>蝡?
<20>? <20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> pages/ # 憭滨鍂frontend-core
<20>? <20>? <20>? <20><EFBFBD><E5A999><EFBFBD> components/ # 憭滨鍂frontend-core
<20>? <20>? <20><EFBFBD><E5A999><EFBFBD> package.json
<20>? <20>?
<20>? <20><EFBFBD><E98EBF><EFBFBD> resources/ # <20><EFBFBD><EFBFBD><E99F8F>
<20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> python/ # Python餈鞱<E9A488><E99EB1>?
<20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> r/ # R餈鞱<E9A488><E99EB1><EFBFBD><EFBFBD><E68692><EFBFBD><E996AC>
<20>? <20>? <20><EFBFBD><E5A999><EFBFBD> assets/
<20>? <20>?
<20>? <20><EFBFBD><E5A999><EFBFBD> electron-builder.yml # <20><EFBFBD><E69E8F>滨蔭
<20>?
<20><EFBFBD><E5A999><EFBFBD> ...
```
---
### <20>喲睸摰䂿緵蝏<E7B7B5><E89D8F>
#### 1. Electron銝餉<E98A9D>蝔页<E89D94>main.ts嚗?
```typescript
// apps/electron/main/src/main.ts
import { app, BrowserWindow, ipcMain } from 'electron';
import path from 'path';
import { setupIpcHandlers } from './ipc-handlers';
import { initDatabase } from './database';
import { startPythonService } from './python-service';
let mainWindow: BrowserWindow | null = null;
async function createWindow() {
// 1. <20>𥕦遣瘚讛<E7989A><E8AE9B><EFBFBD><E587BD>?
mainWindow = new BrowserWindow({
width: 1200,
height: 800,
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
preload: path.join(__dirname, 'preload.js') // 摰匧<E691B0><E58CA7><EFBFBD>PC獢交𦻖
}
});
// 2. <20>㰘蝸<E3B098>滨垢嚗<E59EA2><E59A97>鈭抒㴓憓<E3B493><E68693>
if (app.isPackaged) {
mainWindow.loadFile(path.join(__dirname, '../renderer/index.html'));
} else {
// 撘<><E69298>𤑳㴓憓<E3B493><E68693>餈墧𦻖<E5A2A7>訓ite撘<65><E69298><EFBFBD><E78390>
mainWindow.loadURL('http://localhost:5173');
}
// 3. <20><EFBFBD><E598A5>𡝗㺭<F0A19D97><EFBFBD>
await initDatabase();
// 4. <20>臬𢆡Python<6F><6E>﹝憭<EFB99D><E686AD><EFBFBD>滚𦛚
await startPythonService();
// 5. 霈曄蔭IPC憭<43><E686AD><EFBFBD>?
setupIpcHandlers();
}
// Electron<6F>笔𦶢<E7AC94><EFBFBD>
app.whenReady().then(createWindow);
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
```
---
#### 2. IPC憭<43><E686AD><EFBFBD><EFBFBD>ipc-handlers.ts嚗?
```typescript
// apps/electron/main/src/ipc-handlers.ts
import { ipcMain } from 'electron';
import { prisma } from './prisma-client';
// 憭滨鍂銝𡁜𦛚<F0A1819C><EFBFBD> 潃?
import { UserService } from '@yizhengxun/backend-core/services';
import { ProjectService } from '@yizhengxun/backend-core/services';
import { ConversationService } from '@yizhengxun/backend-core/services';
export function setupIpcHandlers() {
// <20><EFBFBD><E598A5>𡝗<EFBFBD><F0A19D97>?
const userService = new UserService(prisma);
const projectService = new ProjectService(prisma);
const conversationService = new ConversationService(prisma);
// <20><EFBFBD><E586BD><EFBFBD>API
ipcMain.handle('api:users:list', async () => {
return userService.findAll();
});
ipcMain.handle('api:users:create', async (event, data) => {
return userService.create(data);
});
// 憿寧𤌍<E5AFA7><EFBFBD>API
ipcMain.handle('api:projects:list', async (event, userId) => {
return projectService.findByUser(userId);
});
ipcMain.handle('api:projects:create', async (event, data) => {
return projectService.create(data);
});
// 撖寡<E69296><E5AFA1><EFBFBD>API
ipcMain.handle('api:conversations:create', async (event, data) => {
return conversationService.create(data);
});
ipcMain.handle('api:conversations:chat', async (event, data) => {
// 靚<>鍂LLM嚗<4D>𧋦<EFBFBD><EFBFBD>鈭𤑳垢API嚗?
return conversationService.chat(data);
});
// <20><><EFBFBD><EFBFBD>
ipcMain.handle('api:files:upload', async (event, file) => {
// 靽嘥<E99DBD><E598A5>唳𧋦<E594B3><EFBFBD>隞嗥頂蝏?
const filePath = await saveFile(file);
return { url: filePath };
});
}
```
---
#### 3. <20>滨垢IPC摰<E691B0>蝡荔<E89DA1>api-client.ts嚗?
```typescript
// apps/electron/renderer/src/api/client.ts
const { ipcRenderer } = window.require('electron');
export const apiClient = {
// <20><EFBFBD>API
users: {
async list() {
return ipcRenderer.invoke('api:users:list');
},
async create(data: any) {
return ipcRenderer.invoke('api:users:create', data);
}
},
// 憿寧𤌍API
projects: {
async list(userId: string) {
return ipcRenderer.invoke('api:projects:list', userId);
},
async create(data: any) {
return ipcRenderer.invoke('api:projects:create', data);
}
},
// 撖寡<E69296>API
conversations: {
async create(data: any) {
return ipcRenderer.invoke('api:conversations:create', data);
},
async chat(data: any) {
return ipcRenderer.invoke('api:conversations:chat', data);
}
},
// <20><>辣銝𠹺<E98A9D>
files: {
async upload(file: File) {
// 撠<>ile頧祆揢銝慷uffer
const buffer = await file.arrayBuffer();
return ipcRenderer.invoke('api:files:upload', {
name: file.name,
data: Buffer.from(buffer)
});
}
}
};
```
---
#### 4. Python摮鞱<E691AE>蝔讠恣<E8AEA0>?
```typescript
// apps/electron/main/src/python-service.ts
import { spawn, ChildProcess } from 'child_process';
import path from 'path';
import { app } from 'electron';
let pythonProcess: ChildProcess | null = null;
export async function startPythonService(): Promise<void> {
return new Promise((resolve, reject) => {
// Python餈鞱<E9A488><E99EB1>嗉楝敺<E6A59D><E695BA><EFBFBD><EFBFBD><E69E8F><EFBFBD><E59785><EFBFBD>
const pythonPath = app.isPackaged
? path.join(process.resourcesPath, 'python', 'python.exe')
: 'python'; // 撘<><E69298>𤑳㴓憓<E3B493><EFBFBD>函頂蝏𡼏ython
// Python<6F>𡁏𧋦頝臬<E9A09D>
const scriptPath = app.isPackaged
? path.join(process.resourcesPath, 'python', 'extraction_service', 'main.py')
: path.join(__dirname, '../../../../extraction_service/main.py');
// <20>臬𢆡Python餈𤤿<E9A488>
pythonProcess = spawn(pythonPath, [
'-m', 'uvicorn',
'main:app',
'--host', '127.0.0.1',
'--port', '8000'
], {
cwd: path.dirname(scriptPath),
stdio: 'pipe'
});
// <20>穃𨯬颲枏枂
pythonProcess.stdout?.on('data', (data) => {
console.log(`Python: ${data}`);
if (data.toString().includes('Application startup complete')) {
resolve();
}
});
pythonProcess.stderr?.on('data', (data) => {
console.error(`Python Error: ${data}`);
});
pythonProcess.on('error', reject);
});
}
export function stopPythonService(): void {
if (pythonProcess) {
pythonProcess.kill();
pythonProcess = null;
}
}
// 摨𠉛鍂<F0A0899B><E98D82><EFBFBD>箸𧒄<E7AEB8>喲𡡒Python<6F>滚𦛚
app.on('will-quit', stopPythonService);
```
---
#### 5. <20><EFBFBD><E69E8F>滨蔭嚗Ềlectron-builder.yml嚗?
```yaml
# apps/electron/electron-builder.yml
appId: com.yizhengxun.aiclinical
productName: 憯寡<EFBFBD>敺服I蝘𤑳<EFBFBD><EFBFBD><EFBFBD>
# <20><EFBFBD><E69E8F><EFBFBD>
directories:
output: dist
buildResources: resources
# Windows<77>滨蔭
win:
target:
- nsis
- portable
icon: resources/icon.ico
# NSIS摰㕑<E691B0>蝔见<E89D94><E8A781>滨蔭
nsis:
oneClick: false
allowToChangeInstallationDirectory: true
createDesktopShortcut: always
createStartMenuShortcut: true
# Mac<61>滨蔭
mac:
target:
- dmg
- zip
icon: resources/icon.icns
category: public.app-category.productivity
# <20><EFBFBD><E69E8F><EFBFBD><EFBFBD><E98984><EFBFBD>隞?
files:
- "main/**/*"
- "renderer/**/*"
- "!**/*.ts"
- "!**/*.map"
# 憸嘥<E686B8><EFBFBD><E99F8F>嚗㇊ython餈鞱<E9A488><E99EB1><EFBFBD>嚗?
extraResources:
- from: resources/python
to: python
- from: ../../../../extraction_service
to: python/extraction_service
# <20><EFBFBD><E69E8F>𤾸之撠?
asar: true
asarUnpack:
- "**/*.node"
- "resources/**/*"
```
---
### <20>閙㦤<E99699><E3A6A4><EFBFBD><EFBFBD>喲睸<E596B2><E79DB8><EFBFBD><EFBFBD><E88880>?
#### <20><EFBFBD>1嚗𡁏<E59A97><F0A1818F><EFBFBD><EFBFBD>蝘荔<E89D98>500MB+嚗?
**<EFBFBD><EFBFBD><EFBFBD><EFBFBD>捆嚗?*
```
摰㕑<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
- Electron獢<6E>沲嚗鰺100MB
- Node.js餈鞱<E9A488><E99EB1><EFBFBD><E5A19A><EFBFBD><EFBFBD>汞lectron銝?
- <20>滨垢隞<E59EA2><E99A9E><EFBFBD><E59A97>霂穃<E99C82>嚗㚁<E59A97>~10MB
- <20>𡒊垢隞<E59EA2><E99A9E><EFBFBD><E59A97>霂穃<E99C82>嚗㚁<E59A97>~5MB
- SQLite<74>唳旿摨橒<E691A8>~5MB嚗<42>征摨橒<E691A8>
- Python餈鞱<E9A488><E99EB1><EFBFBD>~150MB
- Python靘肽<E99D98>嚗鰺100MB
- R餈鞱<E9A488><E99EB1><EFBFBD><E5A19A><EFBFBD><EFBFBD>嚗鰺200MB
- R靘肽<E99D98><EFBFBD><EFBFBD><EFBFBD>嚗鰺100MB
<EFBFBD>餉恣嚗?00-700MB
```
**隡睃<E99AA1><E79D83><EFBFBD>嚗?*
1. <20>?雿輻鍂ASAR<41>讠憬嚗𠄌lectron暺䁅恕嚗?
2. <20>?銝滚<E98A9D><E6BB9A>俘餈鞱<E9A488><E99EB1><EFBFBD><EFBFBD><E99A9E>蝡舐<E89DA1><E88890><EFBFBD><EFBFBD><E996AC>
3. <20>?Python靘肽<E99D98>蝎曄<E89D8E><EFBFBD><EFBFBD><E898A8>鉄敹<E98984><E695B9><EFBFBD><EFBFBD><EFBFBD>嚗?
4. <20>?憓鮋<E68693><E9AE8B>湔鰵嚗<E9B0B5>蘨銝贝蝸<E8B49D><EFBFBD><E79D83><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
---
#### <20><EFBFBD>2嚗朞楊撟喳蝱<E596B3>澆捆<E6BE86>?
**<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>**
- Windows x64
- Windows ARM64嚗𠄎urface蝑㕑挽憭<E68CBD><E686AD>
- macOS x64
- macOS ARM64嚗㇁pple Silicon嚗?
- Linux x64
**瘚贝<E7989A>撌乩<E6928C><E4B9A9>𧶏<EFBFBD>**
- 瘥譍葵撟喳蝱<E596B3><EFBFBD><EFBFBD>𡠺蝡𧢲<E89DA1>霂?
- 摰㕑<E691B0><E39591><EFBFBD><EFBFBD>蝥扼<E89DA5><E689BC>桊頧賣<E9A0A7>蝔?
- <20><><EFBFBD><EFBFBD><EFBFBD><E6A185><EFBFBD><EFBFBD>隞嗉楝敺<E6A59D>䔮憸?
---
#### <20><EFBFBD>3嚗朞䌊<E69C9E>冽凒<E586BD>?
**electron-updater<65>滨蔭嚗?*
```typescript
// apps/electron/main/src/updater.ts
import { autoUpdater } from 'electron-updater';
import { dialog } from 'electron';
export function setupAutoUpdater() {
// <20>滨蔭<E6BBA8>湔鰵<E6B994>滚𦛚<E6BB9A>?
autoUpdater.setFeedURL({
provider: 'generic',
url: 'https://releases.yizhengxun.com'
});
// 璉<><E79289>交凒<E4BAA4>?
autoUpdater.checkForUpdatesAndNotify();
// <20>𤑳緵<F0A491B3><EFBFBD><E59581>?
autoUpdater.on('update-available', () => {
dialog.showMessageBox({
type: 'info',
title: '<27>𤑳緵<F0A491B3><EFBFBD><E59581>?,
message: '<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>穿<EFBFBD><EFBFBD>?,
buttons: ['<27>?, '<EFBFBD>?]
}).then((result) => {
if (result.response === 0) {
autoUpdater.downloadUpdate();
}
});
});
// 銝贝蝸摰峕<E691B0>
autoUpdater.on('update-downloaded', () => {
dialog.showMessageBox({
type: 'info',
title: '<27>湔鰵撌脣停蝏?,
message: '<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>',
buttons: ['<EFBFBD>', '<EFBFBD>']
}).then((result) => {
if (result.response === 0) {
autoUpdater.quitAndInstall();
}
});
});
}
```
---
## <20><> <20><EFBFBD>撖寞<E69296>
### 銝厩<E98A9D><E58EA9>函蔡<E587BD><EFBFBD>撖寞<E69296>
| 蝏游漲 | 鈭𤑳垢SaaS | <20><EFBFBD>鈭批<E988AD><E689B9>?| Electron<6F>閙㦤<E99699>?|
|------|---------|----------|---------------|
| **<EFBFBD>函蔡<EFBFBD><EFBFBD>** | 鈭𤑳垢<F0A491B3>滚𦛚<E6BB9A>?| Docker摰孵膥 | <20>砍𧑐摰㕑<E691B0> |
| **<EFBFBD>唳旿摮睃<EFBFBD>** | 鈭𤑳垢PostgreSQL | <20>砍𧑐PostgreSQL | <20>砍𧑐SQLite |
| **蝵𤑳<E89DB5><F0A491B3><EFBFBD>瘙?* | 敹<><EFBFBD>𠉛<EFBFBD> | <20>舐氖蝥選<E89DA5>LLM<4C><EFBFBD>嚗?| 摰<><E691B0>蝳餌瑪 |
| **<EFBFBD>湔鰵<EFBFBD><EFBFBD>** | <20><EFBFBD><E4ADBE>交凒<E4BAA4>?| Docker<65>𨅯<EFBFBD><F0A885AF>湔鰵 | 摨𠉛鍂<F0A0899B><E98D82><EFBFBD>?|
| **摰㕑<E691B0><E39591>曉漲** | <20>𣳇<EFBFBD>摰㕑<E691B0> | Docker<65>函蔡 | 銝<><E98A9D><EFBFBD>鋆?|
| **隞<><E99A9E>憭滨鍂** | 100% | 80%嚗<>移蝞<E7A7BB><E89D9E><EFBFBD><EFBFBD> | 90% |
| **<EFBFBD><EFBFBD>鍂摰<EFBFBD>** | 銝芯犖<E88AAF><E78A96><EFBFBD><EFBFBD><EFBFBD> | <20>駁堺<E9A781><E5A0BA><EFBFBD><EFBFBD> | 銝芯犖<E88AAF><EFBFBD> |
| **<EFBFBD><EFBFBD><EFBFBD><EFBFBD>** | 霈<E99C88><EFBD81>?| 銝<>甈⊥<E79488>兵icense | 銝<>甈⊥<E79488>扯揚銋?|
| **蝏湔擪<E6B994>鞉𧋦** | 雿?| 銝?| 擃?|
---
## <20><20><><EFBFBD>遣霈?
### <20><>𧫴畾萄<E795BE><E89084>?
**<EFBFBD>嗆挾銝<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?6銝芣<E98A9D>嚗㚁<E59A97>**
- <20>?銝𤘪釣鈭𤑳垢SaaS<61>?
- <20>?摰<><E691B0>7銝芯<E98A9D><E88AAF>⊥芋<E28AA5>?
- <20>?撱箇<E692B1>Monorepo<70><EFBFBD><EFBFBD><EFBFBD>芣䔉<E88AA3>枏抅蝖<E68A85>嚗?
**<EFBFBD>嗆挾鈭䕘<EFBFBD>6-12銝芣<E98A9D>嚗㚁<E59A97>**
- <20>?撘<><E69298>𤑳𡠺蝡衤漣<E8A1A4><E6BCA3><EFBFBD><EFBFBD>恣蝔輻頂蝏麄<E89D8F><E9BA84>I<EFBFBD><49>讃嚗?
- <20>?<3F><EFBFBD>Docker<65>砍𧑐<E7A08D><EFBFBD>蝵?
- <20>?撉諹<E69289><E8ABB9><EFBFBD><EFBFBD><E79285>
**<EFBFBD>嗆挾銝㚁<EFBFBD>12-18銝芣<E98A9D>嚗㚁<E59A97>**
- <20>?撘<><E69298>䫿lectron<6F>閙㦤<E99699><E3A6A4><EFBFBD><EFBFBD><E68692><EFBFBD><EFBFBD><EFBFBD><E79899>
- <20>?<3F><EFBFBD><EFBFBD><E691B0>蝳餌瑪雿輻鍂
- <20>?<3F><EFBFBD>銝芯犖<E88AAF><EFBFBD><EFBFBD>
---
**<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>亙𪑛銝芣䲮獢<EFBFBD><EFBFBD>**
1.<E79285><E288AA><EFBFBD><E7A589>函蔡<E587BD><E894A1>祕蝏<E7A595><E89D8F><EFBFBD><EFBFBD>
2. Electron<6F>閙㦤<E99699><E3A6A4><EFBFBD><EFBFBD><E69298>𤏸恣<F0A48FB8>𡜐<EFBFBD>
3. Monorepo<70><EFBFBD><E59786><EFBFBD>挽霈∴<E99C88>