yb hace 3 semanas
padre
commit
b484c2bc8c

+ 18 - 6
.obsidian/workspace.json

@@ -13,11 +13,11 @@
             "state": {
               "type": "canvas",
               "state": {
-                "file": "tg-live-game/architecture-v1.canvas",
+                "file": "pwtk-admin-web/architecture-v1.canvas",
                 "viewState": {
-                  "x": -260,
-                  "y": -442.6384996374541,
-                  "zoom": -1.1358366315472972
+                  "x": 882.8236981256205,
+                  "y": -3825.245116722238,
+                  "zoom": -0.8743896484374999
                 }
               },
               "icon": "lucide-layout-dashboard",
@@ -81,7 +81,7 @@
       }
     ],
     "direction": "horizontal",
-    "width": 200
+    "width": 305.5
   },
   "right": {
     "id": "93884d0cec98b8d0",
@@ -188,9 +188,21 @@
   },
   "active": "f3b74f1abf7620d8",
   "lastOpenFiles": [
-    "tg-live-game/discuss-2024-12-31.md",
+    "pwtk-admin-web/discuss-2025-01-02.md",
+    "pwtk-admin-web/architecture-v1.canvas",
     "tg-live-game/architecture-v1.canvas",
+    "tg-live-game-hono/auth-system.canvas",
+    "tg-live-game-hono/README.md",
+    "tg-live-game-hono/d1-database.canvas",
+    "tg-live-game-hono/architecture.canvas",
+    "tg-live-game-hono/README.md.tmp.4959.1767332108780",
+    "tg-live-game-hono",
+    "tg-live-game/discuss-2024-12-31.md",
+    "pwtk-admin-web/architecture-v1.canvas.tmp.2064.1767331486716",
     "tg-live-game/rtsp-cloudflare-stream.canvas",
+    "pwtk-admin-web/architecture-v1.canvas.tmp.2064.1767329530729",
+    "未命名.md",
+    "pwtk-admin-web",
     "tg-live-game",
     "architecture.canvas",
     "CODE_OF_CONDUCT.md",

+ 106 - 0
pwtk-admin-web/architecture-v1.canvas

@@ -0,0 +1,106 @@
+{
+	"nodes":[
+		{"id":"api_layer","type":"text","text":"## API 接口层\n\n| 模块 | 功能 |\n|------|------|\n| advertisement | 广告 |\n| betting | 竞猜 |\n| bss | 业务支撑 |\n| chat | 聊天 |\n| expert | 专家 |\n| live | 直播 |\n| login | 登录 |\n| messageNotice | 消息 |\n| photoSys | 图库 |\n| site | 网站 |\n| system | 系统 |\n| task | 任务 |\n| user | 用户 |\n| video | 视频 |\n| webgw | 网关 |","x":2200,"y":-1750,"width":350,"height":590,"color":"1"},
+		{"id":"bbs_module","type":"text","text":"## Bbs 论坛管理\n\n**bbsMainboard/** 论坛主版\n- index.vue\n\n**bbsForum/** 论坛管理\n- index.vue\n\n**bbsAttachmentManagement/** 附件\n- index.vue\n\n**bbsPostContentManagement/** 帖子\n- index.vue 帖子列表\n- editPostContentDialog/ 编辑\n- auditDialog/ 审核\n- bbsPostConfig/ 配置\n- comments.vue 评论\n- phoneFrame.vue 手机预览\n- **new/** 新建帖子\n  - addBBSPostDialog.vue\n  - BBSPostForm.vue\n  - postEditor.vue\n  - gamePage.vue\n  - lottery/ 彩票组件\n- **components/** 评论组件\n  - post-comments.vue\n  - commentItemBox/Form\n  - upIconToggle/downIconToggle\n- **explain-components/** 图解\n- **issue-components/** 期号\n\n**bbsInfo/** 论坛信息\n- index.vue\n\n**bbsCommentsList/** 评论列表\n- index.vue\n\n**photoExplain/** 图解管理\n- index.vue 图解列表\n- addExplain.vue\n- editExplain.vue\n- chooseIssue.vue\n- commentExplain.vue\n- explainEditPage/","x":1600,"y":-4720,"width":300,"height":1340,"color":"3"},
+		{"id":"photo_module","type":"text","text":"## PhotosSys 图库系统\n\n**series/** 系列管理\n- index.vue\n\n**newspaper/** 报纸管理\n- index.vue\n- relatedLayout.vue\n- RecommendSortedList.vue\n\n**newsPaperIssue/** 期刊发布\n- index.vue 期刊列表\n- batchAddIssues/ 批量添加\n- IssueDialog.vue\n- IssueForm.vue\n- IssueImageUploader.vue\n- CommentTab.vue\n- chooseExplain.vue\n- clearGameTypeCacheDialog.vue\n\n**issueMappingList/** 期号映射\n- index.vue\n- editDialog.vue\n- batchMappingAdd/ 批量映射\n\n**commentsList/** 评论列表\n- index.vue\n\n**websites/** 站点管理\n- index.vue\n\n**guarantee/** 担保管理\n- index.vue\n\n**bbsEncyclopedia/** 百科\n- index.vue\n\n**advertisementList/** 广告\n- index.vue\n- addAdvertisementDailog.vue\n\n**gameResult/** 开奖结果\n- index.vue\n- history.vue 历史记录\n- calendar.vue 日历视图\n- lottoBall.vue / svgLottoBall.vue\n\n**issueVideo/** 期号视频\n- index.vue\n- VideoFormDialog.vue\n- GenericVideoUploader.vue","x":2060,"y":-4720,"width":300,"height":1440,"color":"3"},
+		{"id":"user_module","type":"text","text":"## User 用户管理\n\n**userList/** 用户列表\n- index.vue 用户列表\n- userListComponent.vue\n- **components/**\n  - persionInfo.vue 个人信息\n  - accountInfo.vue 账户信息\n  - achievementShow.vue 成就\n  - phoneInput.vue\n  - blockList.vue 黑名单\n  - followerList.vue 关注\n  - myFans.vue 粉丝\n  - myTeams.vue 团队\n  - userVisiter.vue 访客\n  - anonymousVisiter.vue\n  - userVote.vue 投票\n  - likeList.vue 点赞\n  - favoriteList/ 收藏\n  - myComment/ 评论\n  - browseHistory/ 浏览历史\n  - points/ 积分\n  - stars/ 星星\n  - editPoints/ 编辑积分\n  - ChangePoint/ 积分变更\n  - TagMaster/ 标签大师\n  - SaleLists/ 卖料\n  - BuyingLists/ 买料\n  - cashOutListForUser/ 提现\n  - SMSCodeSend/ 短信\n\n**clientList/** 客户端列表\n- index.vue\n- basicInformation.vue\n- browsingHistory.vue\n- collectionAnonymously.vue\n- followAnonymously.vue\n- likeAnonymously.vue\n- voatAnonymously.vue","x":2520,"y":-4720,"width":300,"height":1140,"color":"5"},
+		{"id":"user_module_2","type":"text","text":"## User 用户管理 (续)\n\n**customerTags/** 用户标签\n- index.vue\n- editCustomerTag/\n\n**memberLevel/** 会员等级\n- index.vue\n- editLevelRule/\n\n**pointsRules/** 积分规则\n- index.vue\n- baseConfigTab/\n  - PointConfigTab.vue\n  - StarConfigTab.vue\n  - TaskRewardConfigTab.vue\n\n**pointDetail/** 积分明细\n- index.vue\n\n**starDetail/** 星星明细\n- index.vue\n\n**activityCenter/** 活动中心\n- index.vue\n- activityCenterDialog/\n\n**leaderboard/** 排行榜\n- index.vue\n- fans/ 粉丝榜\n- leaderPoints/ 积分榜\n- overall/ 综合榜\n- popularity/ 人气榜\n- query/ 查询\n- showLeaderBoard/\n- statusTagUser/\n\n**recommendList/** 推广列表\n- index.vue\n- RecommandConfigDialog.vue\n- RecommandDetailDialog.vue","x":2980,"y":-4720,"width":300,"height":1200,"color":"5"},
+		{"id":"video_module","type":"text","text":"## VideoList 视频管理\n\n**VideoList/** 视频列表\n- index.vue\n- createVideo.vue\n- createVideoDialog.vue\n- editVideo/\n- auditVideo/\n- VideoPlayer.vue\n- VideoHlsPlayer.vue\n- DeferredVideoUploader.vue\n- FileInfo.vue\n- UploadProgress.vue\n- VideoFileInput.vue\n\n**VideoTagList/** 视频标签\n- index.vue\n- createVideoTag.vue\n- videoTagDialog.vue","x":220,"y":-4720,"width":300,"height":560,"color":"1"},
+		{"id":"chat_module","type":"text","text":"## ChatroomSystem 聊天室\n\n**chatroomList/** 聊天室列表\n- index.vue\n- createRoomDialog.vue\n- createChatRoom.vue\n- createLiveRoom.vue\n- createVoiceRoom.vue\n- rulesConfigDialog.vue\n- whiteConfigDialog.vue\n- whiteListUserAutocomplete.vue\n- selectGameSerialNo/\n- selectIssueId/\n- selectNewspaperCode/\n\n**batchRoomCreator/** 批量创建\n- index.vue\n- addChatroomNameDialog.vue\n- addOwnerDialog.vue\n- mPopover.vue\n\n**chatroomUserManagement/** 成员\n- index.vue\n\n**chatroomMsgList/** 消息列表\n- index.vue\n\n**chatroomMsgManagement/** 消息管理\n- index.vue","x":-760,"y":-4720,"width":360,"height":840,"color":"1"},
+		{"id":"live_module","type":"text","text":"## LiveRoomManagement 直播\n\n**liveRoomList/** 直播列表\n- index.vue\n\n**liveRoomUserManagement/** 成员\n- index.vue\n\n**liveRoomMsgList/** 消息列表\n- index.vue\n\n**liveRoomMessageManagement/** 消息管理\n- index.vue","x":-240,"y":-4720,"width":300,"height":480,"color":"1"},
+		{"id":"system_module","type":"text","text":"## System 系统管理\n\n**account/** 账号管理\n- index.vue 账号列表\n- addUserDialog.vue 添加用户\n\n**roles.vue** 角色管理\n**resource** 资源管理 (路由内嵌)\n\n**gameTypeManage/** 彩种管理\n- index.vue 彩种列表\n- addGameType/ 添加彩种\n- editGameType/ 编辑彩种\n\n**operationLog.vue** 操作日志\n**task.vue** 任务调度\n**taskPush/** 任务推送\n**ipAddress/** IP地址管理\n**uploadLog/** 上传日志\n**dictionary.vue** 字典配置\n**SMSManage/** 短信管理\n**sensitiveWord/** 敏感词管理","x":680,"y":-4720,"width":300,"height":600,"color":"2"},
+		{"id":"ad_module","type":"text","text":"## AdvertisementManagement 广告\n\n**index.vue** 广告管理\n- AdvertisementSortedList.vue\n- addAdvertisementDialog.vue","x":4820,"y":-4720,"width":300,"height":230,"color":"4"},
+		{"id":"site_module","type":"text","text":"## Site 网站管理\n\n**codeManagement/** 推广码\n- index.vue 推广码列表\n\n**templateManagement/** 模板管理\n- index.vue 模板列表\n- addTemplateDailog.vue\n- templatePath.vue\n- sketchRef.vue\n- codeStaticDailog.vue\n\n**sketchManagement/** 草图管理\n- index.vue 草图列表\n- sketchInfo.vue\n- sketchPath.vue\n\n**siteManagement/** 站点管理\n- index.vue 站点列表\n- addWebsite.vue\n- domainTab.vue\n- bindTemplateDetail.vue\n- sketchTemplateDetail.vue\n\n**Domain/** 域名管理\n- index.vue 域名列表\n- DomainInformationTabs.vue\n- SketchBand/TemplateBand/WebsiteBand\n\n**Navi/** 导航站\n- navigationConfig.vue\n- naviNestedTable.vue\n\n**componentBase/** 页面组件库\n- index.vue\n- viewComponent.vue","x":1140,"y":-4720,"width":300,"height":1060,"color":"2"},
+		{"id":"expert_module","type":"text","text":"## ExpertManagement 专家\n\n**expertList/** 专家列表\n- index.vue\n- expertRulesConfig/\n\n**competitionList/** 竞选列表\n- index.vue\n\n**pointsList/** 打赏记录\n- index.vue\n- configDialog.vue\n\n**saleList/** 卖料列表\n- index.vue\n- **XSdialog/**\n  - index.vue\n  - saleInfo.vue\n  - gameBox.vue\n  - ChooseLastSale.vue\n\n**buyingList/** 买料列表\n- index.vue\n\n**sixKingList/** 六肖王\n- index.vue\n- Sixking.vue\n- QueryForm.vue\n- Switcher.vue\n- ExpertStatistics.vue\n- HistoryChampion.vue\n- WinningStreakRank.vue\n- SixKingRankBoard/\n- GameTypeCodeItem.vue","x":3440,"y":-4720,"width":300,"height":980,"color":"5"},
+		{"id":"betting_module","type":"text","text":"## Betting 竞猜管理\n\n**bettingList/** 竞猜列表\n- index.vue\n- bettingInfo.vue\n- gameView.vue","x":3900,"y":-4720,"width":300,"height":220,"color":"4"},
+		{"id":"message_module","type":"text","text":"## MessageNotice 消息公告\n\n**index.vue** 公告管理\n- NoticeSortedList.vue\n\n**maintenance.vue** 维护管理","x":4360,"y":-4720,"width":300,"height":240,"color":"4"},
+		{"id":"task_module","type":"text","text":"## TaskManagement 任务\n\n**TaskList/** 任务列表\n- index.vue\n\n**liveTaskList/** 直播任务\n- index.vue\n- **createLiveTaskRoom/**\n  - index.vue\n  - LiveVideoUploader.vue\n\n**components/**\n- basicDateRangeSelecter.vue\n- createTaskRoomDialog.vue\n- createVoiceTaskRoom.vue\n- fileUploaderBtn.vue","x":5280,"y":-4720,"width":300,"height":500,"color":"4"},
+		{"id":"order_module","type":"text","text":"## Order 订单中心\n\n**orderList/** 订单列表\n- index.vue\n\n**cashOut/** 提现列表\n- index.vue\n- **auditCashOut/**\n  - index.vue 审核\n  - AuditCashOutReason.vue\n- **cashOutConfig/**\n  - index.vue 配置","x":5740,"y":-4720,"width":300,"height":380,"color":"4"},
+		{"id":"other_pages","type":"text","text":"## 其他页面\n\n**Home/** 首页\n- index.vue 仪表盘\n- echarts/ 图表组件\n  - index.vue\n  - bar/ 柱状图\n  - line/ 折线图\n\n**Login/** 登录\n- index.vue\n\n**SSO/** 单点登录\n- index.vue\n\n**Demo/** 演示\n- index.vue\n\n**404.vue** 错误页面","x":6200,"y":-4720,"width":300,"height":540,"color":"6"},
+		{"id":"service_layer","type":"text","text":"## Service 服务层\n\n**业务服务**\n- bbs.ts BBS服务\n- website.ts 网站服务\n- kv.ts 键值存储\n\n**拦截器**\n- interceptorChain.ts 拦截器链","x":2960,"y":-1800,"width":300,"height":305,"color":"2"},
+		{"id":"env_config","type":"text","text":"## 环境配置\n\n**开发环境**\n- .env.development.49gallery\n- .env.development.6gallery\n\n**生产环境**\n- .env.production\n- .env.production.49gallery\n- .env.production.6gallery\n\n**构建命令**\n- dev:49gallery\n- dev:6gallery\n- build\n- test / test:e2e","x":2960,"y":-1390,"width":300,"height":470,"color":"2"},
+		{"id":"cicd_pipeline","type":"text","text":"## CI/CD 流水线\n\n**Jenkins Pipeline**\n- Jenkinsfile.dev (6gallery)\n- Jenkinsfile.49dev\n\n**构建阶段**\n1. 初始化\n2. 代码拉取\n3. 更新子模块\n4. 依赖安装 (pnpm)\n5. 生成配置文件\n6. 项目构建\n7. Cloudflare 部署\n\n**通知集成**\n- 📱 Telegram Bot\n- 🔔 飞书 Webhook\n- 🐛 禅道 Bug 追踪\n\n**部署目标**\n- Cloudflare Pages\n- tk-admin6.pwtk.cc","x":3540,"y":-1495,"width":300,"height":680,"color":"1"},
+		{"id":"tech_stack","type":"text","text":"## 技术栈\n\n- **前端框架**: Vue 3.5\n- **构建工具**: Vite 5.3\n- **语言**: TypeScript 5.0\n- **UI组件**: Element Plus 2.7 + Vant 4.9\n- **状态管理**: Pinia 2.0\n- **路由**: Vue Router 4.2\n- **HTTP**: Axios 1.4\n- **国际化**: vue-i18n 9.2\n- **图表**: ECharts 5.4\n- **编辑器**: TinyMCE / CKEditor / WangEditor","x":-6080,"y":-4410,"width":380,"height":360,"color":"4"},
+		{"id":"todo_list","type":"text","text":"## 待办事项\n\n### 技术优化\n- [ ] 组件库文档完善\n- [ ] 单元测试覆盖率提升\n- [ ] E2E 测试用例补充\n- [ ] 性能优化\n\n### 功能迭代\n- [ ] 国际化完善\n- [ ] 移动端适配","x":-6050,"y":-3420,"width":300,"height":380,"color":"1"},
+		{"id":"i18n","type":"text","text":"## 国际化 (i18n)\n\n**语言支持**\n- 🇨🇳 zh-cn 简体中文 (63K)\n- 🇹🇼 zh-tw 繁体中文 (63K)\n- 🇺🇸 en 英文 (70K)\n\n**特性**\n- vue-i18n 9.2\n- 浏览器语言自动检测\n- localStorage 持久化\n- 动态切换支持","x":-6030,"y":-3860,"width":280,"height":380,"color":"5"},
+		{"id":"testing","type":"text","text":"## 测试体系\n\n**单元测试 (Vitest)**\n```\ntests/unit/utils/\n├── dataFormat.spec.ts\n├── validators.spec.ts\n├── getCid.spec.ts\n└── ... (18个测试文件)\n```\n\n**E2E测试 (Playwright)**\n```\ntests/e2e/\n├── auth/\n├── mocks/\n└── core/\n```\n\n**命令**\n- pnpm test\n- pnpm test:coverage\n- pnpm test:e2e","x":-3295,"y":-4505,"width":370,"height":610,"color":"1"},
+		{"id":"assets","type":"text","text":"## 静态资源\n\n**CSS样式**\n- main.less 入口\n- base.less 基础 (9K)\n- global.less 全局 (10K)\n- reset.css 重置\n- skin.css 皮肤 (68K)\n\n**字体图标**\n- iconfont/ 自定义图标\n\n**图片资源**\n- images/ (41个文件)\n\n**JSON数据**\n- json/ 静态数据","x":-2772,"y":-4495,"width":395,"height":500,"color":"3"},
+		{"id":"directives","type":"text","text":"## 自定义指令\n\n- **v-copy** 复制到剪贴板\n- **v-permission** 权限控制","x":-2005,"y":-3910,"width":240,"height":140,"color":"3"},
+		{"id":"http_service","type":"text","text":"## HTTP 服务层\n\n**Axios 封装**\n- 请求/响应拦截器\n- Token 自动注入\n- 错误统一处理\n- Loading 全局遮罩\n\n**多服务支持**\n- apiPath 主API\n- chatApiPath 聊天服务\n- taskApiPath 任务服务\n- videoApiPath 视频服务\n- liveApiPath 直播服务\n- audioConvertToolUrl 音频转换","x":2220,"y":-640,"width":300,"height":470,"color":"1"},
+		{"id":"vite_config","type":"text","text":"## Vite 构建配置\n\n**插件**\n- @vitejs/plugin-vue\n- unplugin-auto-import\n- unplugin-vue-components\n- unplugin-icons\n- vite-plugin-html\n- vite-plugin-vue-devtools\n\n**代码分割**\n- element-plus 单独分块\n- wangeditor 单独分块\n- vue-vendor (vue/pinia/router)\n- vendor-lodash-utils\n\n**图标集**\n- ep / mdi / ri / ic\n- openmoji / twemoji\n\n**开发服务器**\n- 端口: 8000\n- 代理: VITE_PROXY_DOMAIN","x":2960,"y":-500,"width":300,"height":660,"color":"4"},
+		{"id":"data_flow","type":"text","text":"## 数据流\n\n```\n用户操作\n   ↓\nViews 页面\n   ↓\nComposables/Hooks\n   ↓\nAPI 接口调用\n   ↓\nHTTP Service (Axios)\n   ↓\n后端服务\n   ↓\n响应数据\n   ↓\nPinia Stores\n   ↓\nComponents 更新\n```","x":-765,"y":-585,"width":370,"height":520,"color":"6"},
+		{"id":"architecture","type":"text","text":"## 架构流程\n\n```\n浏览器\n   ↓\nVue Router (路由守卫)\n   ↓\nViews (页面组件)\n   ↓\nComponents (公共组件)\n   ↓\nAPI Layer (Axios)\n   ↓\n后端服务\n```\n\n**认证流程**\n- Cookie: token, cid\n- SSO 单点登录支持","x":-305,"y":-2545,"width":440,"height":610,"color":"6"},
+		{"id":"project_structure","type":"text","text":"## 项目结构\n\n```\nsrc/\n├── api/          # 接口层 (22模块)\n├── assets/       # 静态资源\n├── components/   # 组件 (95+)\n├── composables/  # 组合函数 (10)\n├── const/        # 常量\n├── directive/    # 指令 (2)\n├── hooks/        # 钩子 (5)\n├── locales/      # 国际化\n├── router/       # 路由\n├── service/      # 服务层\n├── stores/       # 状态 (13)\n├── types/        # 类型\n├── utils/        # 工具 (45+)\n└── views/        # 页面 (19模块)\n```","x":-290,"y":-1780,"width":410,"height":620,"color":"6"},
+		{"id":"views_summary","type":"text","text":"## Views 页面统计\n\n| 模块 | 页面数 |\n|------|-------|\n| System | 15 |\n| Site | 25 |\n| Bbs | 45 |\n| PhotosSys | 30 |\n| User | 55 |\n| ChatroomSystem | 18 |\n| LiveRoomManagement | 4 |\n| VideoList | 15 |\n| ExpertManagement | 20 |\n| Order | 6 |\n| Betting | 3 |\n| TaskManagement | 8 |\n| MessageNotice | 3 |\n| AdvertisementManagement | 3 |\n| Home | 4 |\n| Login/SSO/Demo/404 | 4 |\n\n**总计: 230+ 页面**","x":-290,"y":-1030,"width":410,"height":700,"color":"6"},
+		{"id":"router_guard","type":"text","text":"## 路由守卫\n\n**认证检查**\n- Cookie token 验证\n- accountInfo API 校验\n\n**SSO 登录**\n- /superAdmin/ssoLogin\n- JWT Token 解析\n- cid 客户ID 提取\n\n**白名单路由**\n- /login\n- /superAdmin/ssoLogin\n\n**会话管理**\n- lastVisitedPath 记录\n- 自动跳转最后访问页\n- 失效自动清理\n\n**清理数据**\n- token / cid / state\n- imgUrl / last_bbs_post_content","x":375,"y":-2580,"width":280,"height":685,"color":"5"},
+		{"id":"hooks","type":"text","text":"## Hooks 钩子函数\n\n- **useGameTypes** 彩种类型\n- **useSearch** 搜索功能\n- **useSession** 会话管理\n- **useSystemStatus** 系统状态\n- **useTablehook** 表格钩子","x":-3250,"y":-3630,"width":280,"height":250,"color":"4"},
+		{"id":"stores","type":"text","text":"## Pinia Stores\n\n- **userinfo** - 用户信息\n- **menulist** - 菜单列表\n- **bettingStore** - 竞猜状态\n- **modalStore** - 弹窗状态\n- **searchStore** - 搜索状态\n- **photoGroupState** - 图组\n- **commentsState** - 评论\n- **kvStore** - 键值存储\n- **manageSiteStore** - 站点管理\n- **tagview** - 标签页\n- **changeI18n** - 国际化","x":-1840,"y":-565,"width":300,"height":320,"color":"4"},
+		{"id":"composables","type":"text","text":"## Composables 组合式函数\n\n**上传相关**\n- useChunkUpload 分片上传\n- useVideoUpload 视频上传\n- useDeferredVideoUpload 延迟上传\n- useGenericVideoUpload 通用上传\n- useFileValidation 文件验证\n\n**业务逻辑**\n- useMultiSelectLogic 多选逻辑\n- useSubmitData 提交数据\n- useRoomName 房间名\n- useWhiteList 白名单\n- useAppInfo 应用信息","x":-2585,"y":-685,"width":300,"height":560,"color":"5"},
+		{"id":"components","type":"text","text":"## 公共组件概览 (109 组件)\n\n| 分类 | 数量 |\n|------|------|\n| 核心表格/表单 | 12 |\n| 编辑器 | 8 |\n| 选择器 (select*) | 22 |\n| 自动完成 (autoChose*) | 10 |\n| 自动完成 (*Autocomplete) | 7 |\n| 文件上传 | 5 |\n| 媒体播放 | 3 |\n| 通用UI | 9 |\n| 模态框 (modalCommon) | 10 |\n| 布局组件 (common) | 6 |\n| 其他 | 17 |\n\n**组件目录**: 95个子目录","x":-2675,"y":-2465,"width":390,"height":450,"color":"3"},
+		{"id":"select_components","type":"text","text":"## 选择器组件 (25+)\n\n**业务选择器**\n- selectUserId 用户ID\n- selectNickname 昵称\n- selectWebSiteId 站点\n- selectForumID 论坛\n- selectMainboardID 主版\n- selectGameTypeList 彩种\n- selectPlayTypeCodeList 玩法\n- selectTemplateId 模板\n- selectSketchCode 草图\n- selectIssue 期号\n- selectVideoTagList 视频标签\n\n**自动完成**\n- autoChose* 系列 (10+)\n- userAutocomplete 用户\n- templateAutocomplete 模板","x":-2620,"y":-1750,"width":280,"height":400,"color":"5"},
+		{"id":"comp_core","type":"text","text":"## 核心表格/表单组件 (12)\n\n**数据表格**\n- mTable 数据表格\n- mSynchronousTable 同步表格\n- checkboxTable 复选表格\n\n**表单组件**\n- mForm 通用表单\n- mSearchForm 搜索表单\n- mDialogForm 对话框表单\n- modalForm 模态表单\n\n**其他**\n- mComment 评论组件\n- mTabPane 标签页\n- mAutoSelect 自动选择\n- mAutocomplete 自动完成\n- mDatePick 日期选择\n- mEditor 编辑器封装\n- mUpload 上传封装","x":-4695,"y":-2275,"width":300,"height":645,"color":"3"},
+		{"id":"comp_upload","type":"text","text":"## 文件上传组件 (5)\n\n**图片上传**\n- FileImageUpload 图片上传\n- FileMultipleImageUpload 多图上传\n- uploadImage 图片上传\n- cropImg 图片裁剪\n\n**通用上传**\n- mUpload 通用上传","x":-5455,"y":-1550,"width":300,"height":260,"color":"1"},
+		{"id":"comp_media","type":"text","text":"## 媒体组件 (4)\n\n- videoViewer 视频播放器\n- audioViewer 音频播放器\n- AsyncImage 异步图片","x":-5875,"y":-1120,"width":300,"height":180,"color":"1"},
+		{"id":"comp_selectors","type":"text","text":"## 选择器组件 (22)\n\n**用户相关**\n- selectUserId 用户ID\n- selectNickname 昵称\n- selectUserIdAndNickname 用户+昵称\n- selectExpertUserId 专家用户\n- selectWhiteUser 白名单用户\n\n**站点相关**\n- selectWebSiteId 站点ID\n- selectBindSiteId 绑定站点\n- selectDomain 域名\n- selectTemplateId 模板\n- selectSystemTemplate 系统模板\n- selectSketchCode 草图\n\n**论坛相关**\n- selectForumID 论坛ID\n- selectForumIDByMainBoardID 主版论坛\n- selectMainboardID 主版ID\n\n**彩种相关**\n- selectGameTypeList 彩种列表\n- selectPlayTypeCodeList 玩法列表\n- selectIssue 期号\n- selectIssueByYear 年度期号\n\n**其他**\n- selectVideoTagList 视频标签\n- selectTagList 标签列表\n- selectPhoneCode 手机区号\n- selectIPList IP列表","x":-4695,"y":-3135,"width":300,"height":780,"color":"5"},
+		{"id":"comp_editors","type":"text","text":"## 编辑器组件 (8)\n\n**TinyMCE 系列**\n- TinyEditor 富文本编辑器\n- TextTinyEditor 文本编辑器\n\n**CKEditor 系列**\n- CKEditor CKEditor 4\n- CKEditor5 CKEditor 5\n\n**WangEditor**\n- WangEditor 王编辑器\n- Editor 通用编辑器\n\n**特殊编辑器**\n- TextEditor 纯文本\n- TextEditorUploadHtml HTML上传","x":-4695,"y":-1550,"width":300,"height":550,"color":"3"},
+		{"id":"comp_ui","type":"text","text":"## 通用UI组件 (14)\n\n**状态/切换**\n- StatusToggle 状态切换\n- expandIcon 展开图标\n- countdown 倒计时\n\n**链接/复制**\n- linkWithCopy 链接复制\n- codePopover 代码弹框\n- simplePopover 简单弹框\n\n**标签/视图**\n- tagsView 标签视图\n\n**时间选择**\n- BasicTimePicker 基础时间\n- timeSelect 时间选择\n- timeSelect2 时间选择2\n\n**远程输入**\n- remoteInput 远程输入\n- uniRemoteInput 通用远程\n- sysTemplateRemoteInput 系统模板\n\n**彩种**\n- gameTypeList 彩种列表\n- gameTypeListMulti 多彩种\n- gamePlayTypeCode 玩法代码","x":-4695,"y":-920,"width":300,"height":865,"color":"4"},
+		{"id":"comp_modal","type":"text","text":"## 模态框组件 (10)\n\n**modalCommon/**\n\n**BBS相关**\n- bbsSeriesModal BBS系列\n- forumSeriesModal 论坛系列\n- mainboardSeriesModal 主版系列\n- postSeriesModal 帖子系列\n- postScreenDetail 帖子详情\n\n**图库相关**\n- newsSeriesModal 新闻系列\n- photoSeriesModal 图片系列\n\n**站点相关**\n- domainSeriesModal 域名系列\n- siteDetailModal 站点详情","x":-4695,"y":25,"width":300,"height":550,"color":"4"},
+		{"id":"comp_common","type":"text","text":"## 通用布局组件 (6)\n\n**common/**\n\n- header 页头\n- footer 页脚\n- menu 菜单\n- copy 复制\n- formPro 表单Pro\n- SingleSelectArray 单选数组","x":-4695,"y":655,"width":300,"height":280,"color":"4"},
+		{"id":"comp_phone","type":"text","text":"## 手机/地区组件 (6)\n\n**手机号**\n- MobileCountry 国家手机\n- MobilePhoneWithCountryCodes 带区号手机\n- selectPhoneCode 区号选择\n\n**地区/语言**\n- AreaSelect 地区选择\n- AreaSelectByWebsiteId 站点地区\n- languageSelect 语言选择\n- languageSelectByWebsiteId 站点语言\n- switchLanguage 切换语言","x":-5155,"y":1530,"width":300,"height":340,"color":"2"},
+		{"id":"comp_autocomplete","type":"text","text":"## 自动完成组件 (17)\n\n**autoChose* 系列 (10)**\n- autoChoseUserId 用户ID\n- autoChoseNickname 昵称\n- autoChoseLoginId 登录ID\n- autoChoseWebSiteId 站点\n- autoChoseSiteId 站点ID\n- autoChoseTemplate 模板\n- autoChoseSketchCode 草图\n- autoChoseIssue 期号\n- autoChosePromotionCode 推广码\n\n**Autocomplete 系列 (7)**\n- AutoComplete 通用自动完成\n- userAutocomplete 用户\n- userDeleteAutocomplete 删除用户\n- userTwoAutocomplete 双用户\n- templateAutocomplete 模板\n- hAutocomplete H自动完成\n- oneAutocomplete 单选\n- dualAutocomplete 双选","x":-4695,"y":-3885,"width":300,"height":620,"color":"5"},
+		{"id":"utils_layer","type":"text","text":"## Utils 工具函数\n\n**数据处理**\n- dataFormat 数据格式化\n- dateFormat 日期格式化\n- numberFormat 数字格式化\n- JSONFormate JSON处理\n\n**认证相关**\n- clearAuth 清除认证\n- saveAuthTokens 保存令牌\n- isLoggedIn 登录状态\n- passwordEncrypt 密码加密\n\n**业务工具**\n- getCid 获取客户ID\n- getImageUrl 图片URL\n- getServiceUrl 服务URL\n- validators 验证器\n\n**存储**\n- localStorage\n- sessionStorage","x":-3970,"y":-3965,"width":400,"height":670,"color":"2"},
+		{"id":"constants","type":"text","text":"## 常量配置\n\n**const/**\n- options.ts 选项配置 (9K)\n- options.json 选项数据\n- phone.json 手机号码 (30K)\n- medalMap.ts 勋章映射\n- commonSet.ts 通用设置\n\n**constants/**\n- countryCodeAndPhoneCode.json\n- localStorageKeys.ts\n- sessionStorageKeys.ts","x":-3910,"y":-5060,"width":280,"height":280,"color":"2"},
+		{"id":"types_system","type":"text","text":"## 类型系统\n\n**核心类型 (types/)**\n- GameType.ts 彩种类型\n- Request.ts 请求/响应\n- Models.ts 数据模型\n- Interceptor.ts 拦截器\n\n**全局类型 (global_types/)**\n- global.d.ts 全局声明\n- video-upload.ts 视频上传","x":-3910,"y":-4510,"width":280,"height":280,"color":"4"},
+		{"id":"title","type":"text","text":"# PWTK Admin Web 架构 v1\n\n**日期**: 2025-01-02\n**版本**: 1.2.51\n**状态**: 生产环境\n\n技术栈:Vue 3 + TypeScript + Vite\nUI框架:Element Plus + Vant\n\n**Views 模块**: 19个\n**Vue 页面**: 230+\n**公共组件**: 109个","x":-6360,"y":-5640,"width":400,"height":340,"color":"6"},
+		{"id":"df8065411e2e3be3","x":6720,"y":-4720,"width":250,"height":540,"type":"text","text":""}
+	],
+	"edges":[
+		{"id":"edge_system_api","fromNode":"system_module","fromSide":"bottom","toNode":"api_layer","toSide":"top","label":"API 调用"},
+		{"id":"edge_site_api","fromNode":"site_module","fromSide":"bottom","toNode":"api_layer","toSide":"top"},
+		{"id":"edge_bbs_api","fromNode":"bbs_module","fromSide":"bottom","toNode":"api_layer","toSide":"top"},
+		{"id":"edge_photo_api","fromNode":"photo_module","fromSide":"bottom","toNode":"api_layer","toSide":"top"},
+		{"id":"edge_user_api","fromNode":"user_module","fromSide":"bottom","toNode":"api_layer","toSide":"top"},
+		{"id":"edge_user2_api","fromNode":"user_module_2","fromSide":"bottom","toNode":"api_layer","toSide":"top"},
+		{"id":"edge_chat_api","fromNode":"chat_module","fromSide":"bottom","toNode":"api_layer","toSide":"top"},
+		{"id":"edge_live_api","fromNode":"live_module","fromSide":"bottom","toNode":"api_layer","toSide":"top"},
+		{"id":"edge_video_api","fromNode":"video_module","fromSide":"bottom","toNode":"api_layer","toSide":"top"},
+		{"id":"edge_expert_api","fromNode":"expert_module","fromSide":"bottom","toNode":"api_layer","toSide":"top"},
+		{"id":"edge_order_api","fromNode":"order_module","fromSide":"bottom","toNode":"api_layer","toSide":"top"},
+		{"id":"edge_betting_api","fromNode":"betting_module","fromSide":"bottom","toNode":"api_layer","toSide":"top"},
+		{"id":"edge_task_api","fromNode":"task_module","fromSide":"bottom","toNode":"api_layer","toSide":"top"},
+		{"id":"edge_message_api","fromNode":"message_module","fromSide":"bottom","toNode":"api_layer","toSide":"top"},
+		{"id":"edge_ad_api","fromNode":"ad_module","fromSide":"bottom","toNode":"api_layer","toSide":"top"},
+		{"id":"edge_other_api","fromNode":"other_pages","fromSide":"bottom","toNode":"api_layer","toSide":"top"},
+		{"id":"edge_api_http","fromNode":"api_layer","fromSide":"bottom","toNode":"http_service","toSide":"top","label":"HTTP封装"},
+		{"id":"edge_api_env","fromNode":"api_layer","fromSide":"right","toNode":"env_config","toSide":"left","label":"环境配置"},
+		{"id":"edge_service_api","fromNode":"service_layer","fromSide":"left","toNode":"api_layer","toSide":"right","label":"服务调用"},
+		{"id":"edge_stores_arch","fromNode":"stores","fromSide":"right","toNode":"architecture","toSide":"left","label":"状态流转"},
+		{"id":"edge_comp_arch","fromNode":"components","fromSide":"right","toNode":"architecture","toSide":"left"},
+		{"id":"edge_utils_comp","fromNode":"utils_layer","fromSide":"right","toNode":"hooks","toSide":"left","label":"工具支持"},
+		{"id":"edge_composables_stores","fromNode":"composables","fromSide":"right","toNode":"stores","toSide":"left","label":"状态复用"},
+		{"id":"edge_hooks_comp","fromNode":"hooks","fromSide":"right","toNode":"components","toSide":"left"},
+		{"id":"edge_directive_comp","fromNode":"directives","fromSide":"bottom","toNode":"components","toSide":"right"},
+		{"id":"edge_i18n_tech","fromNode":"i18n","fromSide":"top","toNode":"tech_stack","toSide":"bottom","label":"语言支持"},
+		{"id":"edge_types_utils","fromNode":"types_system","fromSide":"bottom","toNode":"utils_layer","toSide":"top","label":"类型定义"},
+		{"id":"edge_const_types","fromNode":"constants","fromSide":"bottom","toNode":"types_system","toSide":"top"},
+		{"id":"edge_test_utils","fromNode":"testing","fromSide":"bottom","toNode":"hooks","toSide":"top","label":"测试覆盖"},
+		{"id":"edge_assets_comp","fromNode":"assets","fromSide":"bottom","toNode":"components","toSide":"top","label":"样式资源"},
+		{"id":"edge_select_comp","fromNode":"select_components","fromSide":"top","toNode":"components","toSide":"bottom","label":"选择器"},
+		{"id":"edge_flow_stores","fromNode":"data_flow","fromSide":"left","toNode":"stores","toSide":"right","label":"数据流向"},
+		{"id":"edge_vite_env","fromNode":"vite_config","fromSide":"top","toNode":"env_config","toSide":"bottom","label":"构建配置"},
+		{"id":"edge_cicd_env","fromNode":"cicd_pipeline","fromSide":"left","toNode":"env_config","toSide":"right","label":"部署流程"},
+		{"id":"edge_guard_arch","fromNode":"router_guard","fromSide":"left","toNode":"architecture","toSide":"right","label":"认证流程"},
+		{"id":"edge_cicd_vite","fromNode":"cicd_pipeline","fromSide":"bottom","toNode":"vite_config","toSide":"right","label":"pnpm build"},
+		{"id":"edge_summary_struct","fromNode":"views_summary","fromSide":"top","toNode":"project_structure","toSide":"bottom","label":"页面统计"},
+		{"id":"edge_comp_core","fromNode":"comp_core","fromSide":"right","toNode":"components","toSide":"left","label":"核心组件"},
+		{"id":"edge_comp_editors","fromNode":"comp_editors","fromSide":"right","toNode":"components","toSide":"left"},
+		{"id":"edge_comp_selectors","fromNode":"comp_selectors","fromSide":"right","toNode":"components","toSide":"left"},
+		{"id":"edge_comp_autocomplete","fromNode":"comp_autocomplete","fromSide":"right","toNode":"components","toSide":"left"},
+		{"id":"edge_comp_upload","fromNode":"comp_upload","fromSide":"right","toNode":"comp_core","toSide":"left"},
+		{"id":"edge_comp_media","fromNode":"comp_media","fromSide":"right","toNode":"comp_upload","toSide":"bottom"},
+		{"id":"edge_comp_ui","fromNode":"comp_ui","fromSide":"right","toNode":"components","toSide":"left"},
+		{"id":"edge_comp_modal","fromNode":"comp_modal","fromSide":"right","toNode":"components","toSide":"left"},
+		{"id":"edge_comp_common","fromNode":"comp_common","fromSide":"right","toNode":"components","toSide":"left"},
+		{"id":"edge_comp_phone","fromNode":"comp_phone","fromSide":"right","toNode":"comp_common","toSide":"bottom"}
+	]
+}

+ 1031 - 0
pwtk-admin-web/discuss-2025-01-02.md

@@ -0,0 +1,1031 @@
+# PWTK Admin Web 项目分析记录
+
+## 2025-01-02
+
+### 项目概述
+
+| 属性 | 值 |
+|------|------|
+| 项目路径 | /Users/yibu/dev_workspace/frontend/pwtk-admin-web |
+| 版本 | 1.2.51 |
+| 技术栈 | Vue 3 + TypeScript + Vite |
+| UI框架 | Element Plus 2.7 + Vant 4.9 |
+| 状态管理 | Pinia 2.0 |
+
+---
+
+### 项目架构
+
+#### 目录结构
+```
+src/
+├── api/              # API 接口层 (22+ 模块)
+├── assets/           # 静态资源
+├── components/       # 公共组件 (95+ 组件)
+├── composables/      # 组合式函数
+├── const/            # 常量定义
+├── directive/        # 自定义指令
+├── hooks/            # 钩子函数
+├── locales/          # 国际化
+├── router/           # 路由配置
+├── service/          # 服务层
+├── stores/           # Pinia 状态管理
+├── types/            # 类型定义
+├── utils/            # 工具函数
+└── views/            # 页面组件 (23+ 模块)
+```
+
+---
+
+### 业务模块分析
+
+#### 核心模块 (23个)
+
+| 模块 | 路径 | 功能描述 |
+|------|------|----------|
+| System | /system | 系统管理:账号、角色、资源、日志等 |
+| Site | /site | 网站管理:推广码、模板、站点、域名等 |
+| BBS | /bbs | 论坛管理:主版、帖子、评论、附件等 |
+| bbsList | /bbsList | 帖子列表:各类论坛帖子分类 |
+| PhotosSys | /photosSys | 图库系统:报纸、期刊、评论等 |
+| User | /user | 用户管理:用户、标签、等级、积分等 |
+| ChatroomSystem | /chatroomSystem | 聊天室系统 |
+| VoiceRoomManagement | /voiceroomManagement | 语音房管理 |
+| LiveRoomManagement | /liveRoomManagement | 直播系统 |
+| VideoManagement | /videoManagement | 视频管理 |
+| ExpertManagement | /expertManagement | 专家管理 |
+| Order | /order | 订单中心 |
+| Betting | /betting | 竞猜管理 |
+| TaskManagement | /taskmanagement | 任务管理 |
+| MessageNotice | /messageNotice | 消息公告 |
+| AdvertisementManagement | - | 广告管理 |
+| NewsSiteMgr | /newsSiteMgr | 新闻站点 |
+| WebVision | /webVision* | 站点组件/页面构建器 |
+| Login | /login | 登录页面 |
+| SSO | /superAdmin/ssoLogin | 单点登录 |
+| Home | /home | 首页仪表盘 |
+| Demo | /demo | 演示页面 |
+| 404 | /404 | 错误页面 |
+
+---
+
+### API 接口层
+
+#### 接口模块 (22个)
+```
+api/
+├── advertisement/  # 广告接口
+├── betting/        # 竞猜接口
+├── bss/            # 业务支撑系统
+├── chat/           # 聊天接口
+├── expert/         # 专家接口
+├── global/         # 全局接口
+├── live/           # 直播接口
+├── login/          # 登录接口
+├── manageSite/     # 站点管理
+├── messageNotice/  # 消息公告
+├── newsSiteMgr/    # 新闻站点
+├── order/          # 订单接口
+├── photoSys/       # 图库接口
+├── site/           # 网站接口
+├── super/          # 超管接口
+├── system/         # 系统接口
+├── task/           # 任务接口
+├── user/           # 用户接口
+├── video/          # 视频接口
+├── webgw/          # Web 网关
+├── index.ts        # 入口
+└── type.ts         # 类型定义
+```
+
+---
+
+### 公共组件 (109 组件)
+
+#### 组件分类统计
+
+| 分类 | 数量 | 说明 |
+|------|------|------|
+| 核心表格/表单 | 12 | m-prefix 组件 |
+| 编辑器 | 8 | TinyMCE/CKEditor/WangEditor |
+| 选择器 (select*) | 22 | 业务选择器 |
+| 自动完成 (autoChose*) | 10 | 自动补全输入 |
+| 自动完成 (*Autocomplete) | 7 | 通用自动完成 |
+| 文件上传 | 5 | 图片/文件上传 |
+| 媒体播放 | 3 | 视频/音频/图片 |
+| 通用UI | 14 | 状态/时间/弹框 |
+| 模态框 (modalCommon) | 10 | 业务模态框 |
+| 布局组件 (common) | 6 | 页头/页脚/菜单 |
+| 手机/地区 | 8 | 国家码/地区选择 |
+| 其他 | 4 | 杂项组件 |
+
+---
+
+#### 核心表格/表单组件 (12)
+
+| 组件 | 功能 |
+|------|------|
+| mTable | 数据表格 |
+| mSynchronousTable | 同步表格 |
+| checkboxTable | 复选表格 |
+| mForm | 通用表单 |
+| mSearchForm | 搜索表单 |
+| mDialogForm | 对话框表单 |
+| modalForm | 模态表单 |
+| mComment | 评论组件 |
+| mTabPane | 标签页 |
+| mAutoSelect | 自动选择 |
+| mAutocomplete | 自动完成 |
+| mDatePick | 日期选择 |
+| mEditor | 编辑器封装 |
+| mUpload | 上传封装 |
+
+---
+
+#### 编辑器组件 (8)
+
+| 类型 | 组件 | 功能 |
+|------|------|------|
+| TinyMCE | TinyEditor | 富文本编辑器 |
+| | TextTinyEditor | 文本编辑器 |
+| CKEditor | CKEditor | CKEditor 4 |
+| | CKEditor5 | CKEditor 5 |
+| WangEditor | WangEditor | 王编辑器 |
+| | Editor | 通用编辑器 |
+| 特殊 | TextEditor | 纯文本 |
+| | TextEditorUploadHtml | HTML上传 |
+
+---
+
+#### 选择器组件 (22)
+
+**用户相关**
+| 组件 | 功能 |
+|------|------|
+| selectUserId | 用户ID选择 |
+| selectNickname | 昵称选择 |
+| selectUserIdAndNickname | 用户+昵称 |
+| selectExpertUserId | 专家用户 |
+| selectWhiteUser | 白名单用户 |
+
+**站点相关**
+| 组件 | 功能 |
+|------|------|
+| selectWebSiteId | 站点ID |
+| selectBindSiteId | 绑定站点 |
+| selectDomain | 域名选择 |
+| selectTemplateId | 模板选择 |
+| selectSystemTemplate | 系统模板 |
+| selectSketchCode | 草图选择 |
+
+**论坛相关**
+| 组件 | 功能 |
+|------|------|
+| selectForumID | 论坛ID |
+| selectForumIDByMainBoardID | 主版论坛 |
+| selectMainboardID | 主版ID |
+
+**彩种相关**
+| 组件 | 功能 |
+|------|------|
+| selectGameTypeList | 彩种列表 |
+| selectPlayTypeCodeList | 玩法列表 |
+| selectIssue | 期号选择 |
+| selectIssueByYear | 年度期号 |
+
+**其他**
+| 组件 | 功能 |
+|------|------|
+| selectVideoTagList | 视频标签 |
+| selectTagList | 标签列表 |
+| selectPhoneCode | 手机区号 |
+| selectIPList | IP列表 |
+
+---
+
+#### 自动完成组件 (17)
+
+**autoChose* 系列 (10)**
+| 组件 | 功能 |
+|------|------|
+| autoChoseUserId | 用户ID |
+| autoChoseNickname | 昵称 |
+| autoChoseLoginId | 登录ID |
+| autoChoseWebSiteId | 站点 |
+| autoChoseSiteId | 站点ID |
+| autoChoseTemplate | 模板 |
+| autoChoseSketchCode | 草图 |
+| autoChoseIssue | 期号 |
+| autoChosePromotionCode | 推广码 |
+
+**Autocomplete 系列 (7)**
+| 组件 | 功能 |
+|------|------|
+| AutoComplete | 通用自动完成 |
+| userAutocomplete | 用户自动完成 |
+| userDeleteAutocomplete | 删除用户 |
+| userTwoAutocomplete | 双用户 |
+| templateAutocomplete | 模板自动完成 |
+| hAutocomplete | H自动完成 |
+| oneAutocomplete | 单选自动完成 |
+| dualAutocomplete | 双选自动完成 |
+
+---
+
+#### 文件上传组件 (5)
+
+| 组件 | 功能 |
+|------|------|
+| FileImageUpload | 图片上传 |
+| FileMultipleImageUpload | 多图上传 |
+| uploadImage | 图片上传 |
+| cropImg | 图片裁剪 |
+| mUpload | 通用上传 |
+
+---
+
+#### 媒体组件 (3)
+
+| 组件 | 功能 |
+|------|------|
+| videoViewer | 视频播放器 |
+| audioViewer | 音频播放器 |
+| AsyncImage | 异步图片加载 |
+
+---
+
+#### 通用UI组件 (14)
+
+**状态/切换**
+| 组件 | 功能 |
+|------|------|
+| StatusToggle | 状态切换 |
+| expandIcon | 展开图标 |
+| countdown | 倒计时 |
+
+**链接/复制**
+| 组件 | 功能 |
+|------|------|
+| linkWithCopy | 链接复制 |
+| codePopover | 代码弹框 |
+| simplePopover | 简单弹框 |
+| tagsView | 标签视图 |
+
+**时间选择**
+| 组件 | 功能 |
+|------|------|
+| BasicTimePicker | 基础时间选择 |
+| timeSelect | 时间选择 |
+| timeSelect2 | 时间选择2 |
+
+**远程输入**
+| 组件 | 功能 |
+|------|------|
+| remoteInput | 远程输入 |
+| uniRemoteInput | 通用远程输入 |
+| sysTemplateRemoteInput | 系统模板远程输入 |
+
+**彩种**
+| 组件 | 功能 |
+|------|------|
+| gameTypeList | 彩种列表 |
+| gameTypeListMulti | 多彩种选择 |
+| gamePlayTypeCode | 玩法代码 |
+
+---
+
+#### 模态框组件 (10)
+
+**modalCommon/**
+
+| 组件 | 功能 |
+|------|------|
+| bbsSeriesModal | BBS系列模态 |
+| forumSeriesModal | 论坛系列模态 |
+| mainboardSeriesModal | 主版系列模态 |
+| postSeriesModal | 帖子系列模态 |
+| postScreenDetail | 帖子详情模态 |
+| newsSeriesModal | 新闻系列模态 |
+| photoSeriesModal | 图片系列模态 |
+| domainSeriesModal | 域名系列模态 |
+| siteDetailModal | 站点详情模态 |
+
+---
+
+#### 通用布局组件 (6)
+
+**common/**
+
+| 组件 | 功能 |
+|------|------|
+| header | 页头 |
+| footer | 页脚 |
+| menu | 菜单 |
+| copy | 复制功能 |
+| formPro | 表单Pro |
+| SingleSelectArray | 单选数组 |
+
+---
+
+#### 手机/地区组件 (8)
+
+**手机号**
+| 组件 | 功能 |
+|------|------|
+| MobileCountry | 国家手机号 |
+| MobilePhoneWithCountryCodes | 带区号手机 |
+| selectPhoneCode | 区号选择 |
+
+**地区/语言**
+| 组件 | 功能 |
+|------|------|
+| AreaSelect | 地区选择 |
+| AreaSelectByWebsiteId | 站点地区选择 |
+| languageSelect | 语言选择 |
+| languageSelectByWebsiteId | 站点语言选择 |
+| switchLanguage | 切换语言 |
+
+---
+
+### 状态管理 (Pinia)
+
+| Store | 功能 |
+|-------|------|
+| userinfo | 用户信息 |
+| menulist | 菜单列表 |
+| bettingStore | 竞猜状态 |
+| modalStore | 弹窗状态 |
+| searchStore | 搜索状态 |
+| photoGroupState | 图组状态 |
+| commentsState | 评论状态 |
+| kvStore | 键值存储 |
+| manageSiteStore | 站点管理 |
+| siteManageStore | 站点状态 |
+| tagview | 标签页视图 |
+| changeI18n | 国际化切换 |
+| indexDB | IndexDB 存储 |
+
+---
+
+### 环境配置
+
+#### 开发环境
+- `.env.development.49gallery` - 49gallery 开发
+- `.env.development.6gallery` - 6gallery 开发
+
+#### 生产环境
+- `.env.production` - 通用生产
+- `.env.production.49gallery` - 49gallery 生产
+- `.env.production.6gallery` - 6gallery 生产
+
+#### 构建命令
+```bash
+pnpm dev              # 默认开发 (6gallery)
+pnpm dev:49gallery    # 49gallery 开发
+pnpm dev:6gallery     # 6gallery 开发
+pnpm build            # 生产构建
+pnpm test             # 单元测试
+pnpm test:e2e         # E2E 测试
+```
+
+---
+
+### 路由守卫
+
+- **认证检查**: Cookie token 验证
+- **SSO 支持**: /superAdmin/ssoLogin 路由
+- **白名单**: /login, /superAdmin/ssoLogin
+- **自动跳转**: 未认证跳转登录页
+
+---
+
+### 关键依赖
+
+#### 核心
+- vue: ^3.5.13
+- vue-router: ^4.2.0
+- pinia: ^2.0.36
+- axios: ^1.4.0
+
+#### UI
+- element-plus: 2.7.5
+- vant: ^4.9.9
+
+#### 工具
+- dayjs: ^1.11.13
+- echarts: ^5.4.2
+- lodash-es: ^4.17.21
+
+#### 开发
+- vite: 5.3.1
+- typescript: ~5.0.4
+- vitest: ^4.0.16
+- @playwright/test: ^1.57.0
+
+---
+
+### 相关资源
+
+- 项目路径: /Users/yibu/dev_workspace/frontend/pwtk-admin-web
+- Canvas 架构图: architecture-v1.canvas
+
+---
+
+### Utils 工具函数 (45+)
+
+#### 数据处理
+| 文件 | 功能 |
+|------|------|
+| dataFormat.ts | 数据格式化 |
+| dateFormat/ | 日期格式化 |
+| numberFormat.ts | 数字格式化 |
+| JSONFormate.ts | JSON 处理 |
+| filterUtils.ts | 过滤工具 |
+| validators.ts | 验证器 |
+
+#### 认证相关
+| 文件 | 功能 |
+|------|------|
+| clearAuth.ts | 清除认证 |
+| saveAuthTokens.ts | 保存令牌 |
+| isLoggedIn.ts | 登录状态 |
+| passwordEncrypt.ts | 密码加密 |
+
+#### 业务工具
+| 文件 | 功能 |
+|------|------|
+| getCid.ts | 获取客户ID |
+| getImageUrl.ts | 图片URL |
+| getServiceUrl.ts | 服务URL |
+| getDownloadAppUrl.ts | APP下载 |
+| timezone.ts | 时区处理 |
+
+---
+
+### Composables 组合式函数 (10)
+
+| 函数 | 功能 |
+|------|------|
+| useChunkUpload | 分片上传 |
+| useVideoUpload | 视频上传 |
+| useDeferredVideoUpload | 延迟上传 |
+| useGenericVideoUpload | 通用上传 |
+| useFileValidation | 文件验证 |
+| useMultiSelectLogic | 多选逻辑 |
+| useSubmitData | 提交数据 |
+| useRoomName | 房间名 |
+| useWhiteList | 白名单 |
+| useAppInfo | 应用信息 |
+
+---
+
+### Hooks 钩子函数 (5)
+
+| 钩子 | 功能 |
+|------|------|
+| useGameTypes | 彩种类型 |
+| useSearch | 搜索功能 |
+| useSession | 会话管理 |
+| useSystemStatus | 系统状态 |
+| useTablehook | 表格钩子 |
+
+---
+
+### HTTP 服务层
+
+#### Axios 封装特性
+- 请求/响应拦截器
+- Token 自动注入 (Cookie)
+- 错误统一处理 (401/403)
+- Loading 全局遮罩
+- 多 Content-Type 支持
+
+#### 多服务端点
+| 变量 | 服务 |
+|------|------|
+| apiPath | 主 API |
+| chatApiPath | 聊天服务 |
+| taskApiPath | 任务服务 |
+| videoApiPath | 视频服务 |
+| liveApiPath | 直播服务 |
+| audioConvertToolUrl | 音频转换 |
+
+---
+
+### Views 页面清单 (230+ 页面)
+
+#### 页面统计
+
+| 模块 | 页面数 | 说明 |
+|------|-------|------|
+| System | 15 | 系统管理 |
+| Site | 28 | 网站管理 |
+| Bbs | 55 | 论坛管理 |
+| PhotosSys | 32 | 图库系统 |
+| User | 58 | 用户管理 |
+| ChatroomSystem | 18 | 聊天室 |
+| LiveRoomManagement | 4 | 直播管理 |
+| VideoList | 16 | 视频管理 |
+| ExpertManagement | 22 | 专家管理 |
+| Order | 6 | 订单中心 |
+| Betting | 4 | 竞猜管理 |
+| TaskManagement | 8 | 任务管理 |
+| MessageNotice | 3 | 消息公告 |
+| AdvertisementManagement | 3 | 广告管理 |
+| 其他 | 6 | Login/Home/Demo/404/SSO |
+
+---
+
+#### System 系统管理 (15 页面)
+
+| 文件 | 功能 |
+|------|------|
+| index.vue | 系统首页 |
+| account/index.vue | 账号管理 |
+| account/addUserDialog.vue | 添加用户弹窗 |
+| roles.vue | 角色管理 |
+| dictionary.vue | 字典管理 |
+| operationLog.vue | 操作日志 |
+| task.vue | 任务管理 |
+| taskPush/index.vue | 任务推送 |
+| uploadLog/index.vue | 上传日志 |
+| ipAddress/index.vue | IP 地址管理 |
+| SMSManage/index.vue | 短信管理 |
+| sensitiveWord/index.vue | 敏感词 |
+| sensitiveWord/addSensitiveWordDialog.vue | 添加敏感词 |
+| gameTypeManage/index.vue | 彩种管理 |
+| gameTypeManage/addGameType/index.vue | 添加彩种 |
+| gameTypeManage/editGameType/index.vue | 编辑彩种 |
+
+---
+
+#### Site 网站管理 (28 页面)
+
+| 目录 | 文件 | 功能 |
+|------|------|------|
+| codeManagement/ | index.vue | 推广码管理 |
+| templateManagement/ | index.vue | 模板管理 |
+| | addTemplateDailog.vue | 添加模板 |
+| | codeStaticDailog.vue | 代码统计 |
+| | templatePath.vue | 模板路径 |
+| | sketchRef.vue | 草图引用 |
+| sketchManagement/ | index.vue | 草图管理 |
+| | sketchInfo.vue | 草图信息 |
+| | sketchPath.vue | 草图路径 |
+| siteManagement/ | index.vue | 站点管理 |
+| | addWebsite.vue | 添加站点 |
+| | domainTab.vue | 域名标签 |
+| | unboundDomain.vue | 未绑定域名 |
+| | uploadLogo.vue | 上传 Logo |
+| Domain/ | index.vue | 域名管理 |
+| | DomainInformationTabs.vue | 域名信息 |
+| | WebsiteBand.vue | 网站绑定 |
+| | TemplateBand.vue | 模板绑定 |
+| | SketchBand.vue | 草图绑定 |
+| | WebsiteTable.vue | 网站表格 |
+| Domain/new/ | addDomainDialog.vue | 添加域名 |
+| | NewWebsiteBand.vue | 新网站绑定 |
+| | NewTemplateBand.vue | 新模板绑定 |
+| | NewSketchBand.vue | 新草图绑定 |
+| Navi/ | navigationConfig.vue | 导航配置 |
+| | naviNestedTable.vue | 嵌套导航表 |
+| componentBase/ | index.vue | 组件库 |
+| | addPageComponentDialog.vue | 添加组件 |
+
+---
+
+#### Bbs 论坛管理 (55 页面)
+
+**主要模块:**
+| 目录 | 文件 | 功能 |
+|------|------|------|
+| bbsMainboard/ | index.vue | 论坛主版 |
+| bbsForum/ | index.vue | 论坛版块 |
+| bbsInfo/ | index.vue | 论坛信息 |
+| bbsCommentsList/ | index.vue | 评论列表 |
+| bbsAttachmentManagement/ | index.vue | 附件管理 |
+
+**帖子管理 (bbsPostContentManagement/):**
+- index.vue - 帖子列表
+- editPostContentDialog/ - 编辑帖子
+- auditDialog/ - 审核弹窗
+- bbsPostConfig/ - 帖子配置
+- comments.vue - 评论组件
+- commentForm.vue - 评论表单
+- commentItem.vue - 评论项
+- phoneFrame.vue - 手机预览框
+- mediaPreview.vue - 媒体预览
+- iconToggle.vue - 图标切换
+- enhancedFileUpload.vue - 增强上传
+
+**新建帖子 (new/):**
+- addBBSPostDialog.vue - 新建帖子弹窗
+- BBSPostForm.vue - 帖子表单
+- ChooseLastPost.vue - 选择上期
+- postEditor.vue - 帖子编辑器
+- attachmentManage.vue - 附件管理
+- gamePage.vue - 彩种页面
+- staticGamePage.vue - 静态彩种
+- lotteryBall.vue - 彩球组件
+
+**彩票组件 (lottery/):**
+- lotteryGameContent.vue
+- lotteryGameTypeEditor.vue
+- lotteryRootGamePage.vue
+- lotteryStaticGamePage.vue
+- reviewLotteryBall.vue
+
+**评论组件 (components/):**
+- commentItemBox.vue
+- commentItemForm.vue
+- post-comments.vue
+- starIconToggle.vue / upIconToggle.vue / downIconToggle.vue
+
+**解释组件 (explain-components/):** 6 个
+**期号组件 (issue-components/):** 6 个
+
+**图解 (photoExplain/):**
+- index.vue - 图解列表
+- addExplain.vue - 添加图解
+- editExplain.vue - 编辑图解
+- commentExplain.vue - 图解评论
+- chooseIssue.vue - 选择期号
+- explainEditPage/index.vue - 图解编辑页
+
+---
+
+#### PhotosSys 图库系统 (32 页面)
+
+| 目录 | 文件 | 功能 |
+|------|------|------|
+| newspaper/ | index.vue | 报纸管理 |
+| | relatedLayout.vue | 相关布局 |
+| | RecommendSortedList.vue | 推荐排序 |
+| newsPaperIssue/ | index.vue | 期号管理 |
+| | IssueDialog.vue | 期号弹窗 |
+| | IssueForm.vue | 期号表单 |
+| | IssueImageUploader.vue | 期号图片 |
+| | CommentTab.vue | 评论标签 |
+| | chooseExplain.vue | 选择图解 |
+| | clearGameTypeCacheDialog.vue | 清除缓存 |
+| | batchAddIssues/index.vue | 批量添加 |
+| commentsList/ | index.vue | 评论列表 |
+| series/ | index.vue | 系列管理 |
+| websites/ | index.vue | 网站管理 |
+| bbsEncyclopedia/ | index.vue | 百科管理 |
+| guarantee/ | index.vue | 担保管理 |
+| advertisementList/ | index.vue | 广告列表 |
+| | addAdvertisementDailog.vue | 添加广告 |
+| gameResult/ | index.vue | 开奖结果 |
+| | calendar.vue | 日历视图 |
+| | history.vue | 历史记录 |
+| | lottoBall.vue | 彩球组件 |
+| | svgLottoBall.vue | SVG 彩球 |
+| issueVideo/ | index.vue | 期号视频 |
+| | VideoFormDialog.vue | 视频表单 |
+| | GenericVideoUploader.vue | 视频上传 |
+| issueMappingList/ | index.vue | 期号映射 |
+| | editDialog.vue | 编辑弹窗 |
+| | batchMappingAdd/index.vue | 批量映射 |
+| | bachAddSet.vue | 批量设置 |
+
+---
+
+#### User 用户管理 (58 页面)
+
+**用户列表 (userList/):**
+- index.vue - 用户列表主页
+- userListComponent.vue - 列表组件
+- persionInfo.vue - 个人信息
+- accountInfo.vue - 账号信息
+- achievementShow.vue - 成就展示
+- phoneInput.vue - 手机输入
+- myFans.vue - 我的粉丝
+- myTeams.vue - 我的团队
+- followerList.vue - 关注列表
+- likeList.vue - 点赞列表
+- blockList.vue - 黑名单
+- userVisiter.vue - 访客
+- anonymousVisiter.vue - 匿名访客
+- userVote.vue - 用户投票
+
+**子功能组件:**
+- BuyingLists/ - 购买列表
+- SaleLists/ - 销售列表
+- ChangePoint/ - 积分变更
+- SMSCodeSend/ - 短信发送
+- TagMaster/ - 标签管理
+- browseHistory/ - 浏览历史
+- cashOutListForUser/ - 提现列表
+- editPoints/ - 编辑积分
+- favoriteList/ - 收藏列表
+- myComment/ - 我的评论
+- points/ - 积分
+- stars/ - 星星
+- subComponet/ - 子组件 (3个)
+
+**其他模块:**
+| 目录 | 文件 | 功能 |
+|------|------|------|
+| clientList/ | index.vue | 客户列表 |
+| | basicInformation.vue | 基本信息 |
+| | browsingHistory.vue | 浏览历史 |
+| | collectionAnonymously.vue | 匿名收藏 |
+| | followAnonymously.vue | 匿名关注 |
+| | likeAnonymously.vue | 匿名点赞 |
+| | voatAnonymously.vue | 匿名投票 |
+| customerTags/ | index.vue | 用户标签 |
+| | editCustomerTag/index.vue | 编辑标签 |
+| memberLevel/ | index.vue | 会员等级 |
+| | editLevelRule/index.vue | 编辑规则 |
+| activityCenter/ | index.vue | 活动中心 |
+| | activityCenterDialog/index.vue | 活动弹窗 |
+| pointsRules/ | index.vue | 积分规则 |
+| | PointConfigTab.vue | 积分配置 |
+| | StarConfigTab.vue | 星星配置 |
+| | TaskRewardConfigTab.vue | 任务奖励 |
+| pointDetail/ | index.vue | 积分明细 |
+| starDetail/ | index.vue | 星星明细 |
+| recommendList/ | index.vue | 推荐列表 |
+| | RecommandConfigDialog.vue | 推荐配置 |
+| | RecommandDetailDialog.vue | 推荐详情 |
+| leaderboard/ | index.vue | 排行榜 |
+| | fans/index.vue | 粉丝榜 |
+| | leaderPoints/index.vue | 积分榜 |
+| | overall/index.vue | 综合榜 |
+| | popularity/index.vue | 人气榜 |
+| | query/index.vue | 查询 |
+| | showLeaderBoard/index.vue | 展示榜单 |
+| | statusTagUser/index.vue | 状态标签 |
+
+---
+
+#### ChatroomSystem 聊天室系统 (18 页面)
+
+| 目录 | 文件 | 功能 |
+|------|------|------|
+| chatroomList/ | index.vue | 聊天室列表 |
+| | createChatRoom.vue | 创建聊天室 |
+| | createLiveRoom.vue | 创建直播间 |
+| | createVoiceRoom.vue | 创建语音房 |
+| | createRoomDialog.vue | 创建房间弹窗 |
+| | rulesConfigDialog.vue | 规则配置 |
+| | whiteConfigDialog.vue | 白名单配置 |
+| | whiteListUserAutocomplete.vue | 白名单自动完成 |
+| | selectGameSerialNo/index.vue | 选择彩期 |
+| | selectIssueId/index.vue | 选择期号 |
+| | selectNewspaperCode/index.vue | 选择报纸 |
+| batchRoomCreator/ | index.vue | 批量创建 |
+| | addChatroomNameDialog.vue | 添加房间名 |
+| | addOwnerDialog.vue | 添加房主 |
+| | mPopover.vue | 弹出框 |
+| chatroomMsgList/ | index.vue | 消息列表 |
+| chatroomMsgManagement/ | index.vue | 消息管理 |
+| chatroomUserManagement/ | index.vue | 用户管理 |
+
+---
+
+#### LiveRoomManagement 直播管理 (4 页面)
+
+| 文件 | 功能 |
+|------|------|
+| liveRoomList/index.vue | 直播间列表 |
+| liveRoomMessageManagement/index.vue | 消息管理 |
+| liveRoomMsgList/index.vue | 消息列表 |
+| liveRoomUserManagement/index.vue | 用户管理 |
+
+---
+
+#### VideoList 视频管理 (16 页面)
+
+| 目录 | 文件 | 功能 |
+|------|------|------|
+| / | index.vue | 视频列表 |
+| VideoTagList/ | index.vue | 视频标签 |
+| | createVideoTag.vue | 创建标签 |
+| | videoTagDialog.vue | 标签弹窗 |
+| components/ | createVideo.vue | 创建视频 |
+| | createVideoDialog.vue | 创建弹窗 |
+| | editVideo/index.vue | 编辑视频 |
+| | editVideoDialog.vue | 编辑弹窗 |
+| | auditVideo/index.vue | 审核视频 |
+| | VideoFileInput.vue | 视频输入 |
+| | DeferredVideoUploader.vue | 延迟上传 |
+| | FileInfo.vue | 文件信息 |
+| | UploadProgress.vue | 上传进度 |
+
+---
+
+#### ExpertManagement 专家管理 (22 页面)
+
+| 目录 | 文件 | 功能 |
+|------|------|------|
+| expertList/ | index.vue | 专家列表 |
+| | expertRulesConfig/index.vue | 规则配置 |
+| saleList/ | index.vue | 销售列表 |
+| | XSdialog/index.vue | 销售弹窗 |
+| | XSdialog/saleInfo.vue | 销售信息 |
+| | XSdialog/gameBox.vue | 彩种选择 |
+| | XSdialog/ChooseLastSale.vue | 选择上期 |
+| buyingList/ | index.vue | 购买列表 |
+| competitionList/ | index.vue | 竞赛列表 |
+| pointsList/ | index.vue | 积分列表 |
+| | configDialog.vue | 配置弹窗 |
+| sixKingList/ | index.vue | 六王列表 |
+| | Sixking.vue | 六王组件 |
+| | ExpertStatistics.vue | 专家统计 |
+| | HistoryChampion.vue | 历史冠军 |
+| | WinningStreakRank.vue | 连胜榜 |
+| | QueryForm.vue | 查询表单 |
+| | Switcher.vue | 切换器 |
+| | SixKingRankBoard/index.vue | 排行榜 |
+| | GameTypeCodeItem.vue | 彩种项 |
+| components/ | popover-list/index.vue | 弹出列表 |
+
+---
+
+#### Order 订单中心 (6 页面)
+
+| 目录 | 文件 | 功能 |
+|------|------|------|
+| orderList/ | index.vue | 订单列表 |
+| cashOut/ | index.vue | 提现管理 |
+| | cashOutConfig/index.vue | 提现配置 |
+| | auditCashOut/index.vue | 审核提现 |
+| | AuditCashOutReason.vue | 审核原因 |
+
+---
+
+#### Betting 竞猜管理 (4 页面)
+
+| 目录 | 文件 | 功能 |
+|------|------|------|
+| bettingList/ | index.vue | 竞猜列表 |
+| | bettingInfo.vue | 竞猜信息 |
+| | gameView.vue | 彩种视图 |
+
+---
+
+#### TaskManagement 任务管理 (8 页面)
+
+| 目录 | 文件 | 功能 |
+|------|------|------|
+| TaskList/ | index.vue | 任务列表 |
+| liveTaskList/ | index.vue | 直播任务 |
+| | createLiveTaskRoom/index.vue | 创建直播任务 |
+| | LiveVideoUploader.vue | 直播视频上传 |
+| components/ | createTaskRoomDialog.vue | 创建任务弹窗 |
+| | createVoiceTaskRoom.vue | 创建语音任务 |
+| | fileUploaderBtn.vue | 文件上传按钮 |
+| | basicDateRangeSelecter.vue | 日期选择器 |
+
+---
+
+#### MessageNotice 消息公告 (3 页面)
+
+| 文件 | 功能 |
+|------|------|
+| index.vue | 消息公告列表 |
+| maintenance.vue | 维护公告 |
+| NoticeSortedList.vue | 公告排序 |
+
+---
+
+#### AdvertisementManagement 广告管理 (3 页面)
+
+| 文件 | 功能 |
+|------|------|
+| index.vue | 广告列表 |
+| addAdvertisementDialog.vue | 添加广告 |
+| AdvertisementSortedList.vue | 广告排序 |
+
+---
+
+#### 其他页面 (6 页面)
+
+| 文件 | 功能 |
+|------|------|
+| Login/index.vue | 登录页 |
+| SSO/index.vue | 单点登录 |
+| Home/index.vue | 首页 |
+| Home/echarts/ | 图表组件 (bar/line) |
+| Demo/index.vue | 演示页 |
+| 404.vue | 错误页 |
+
+---
+
+### 自定义指令 (2)
+
+| 指令 | 功能 |
+|------|------|
+| v-copy | 复制到剪贴板 |
+| v-permission | 权限控制 |
+
+---
+
+### Vite 构建配置
+
+#### 插件体系
+| 插件 | 功能 |
+|------|------|
+| @vitejs/plugin-vue | Vue 3 支持 |
+| unplugin-auto-import | 自动导入 Vue/Router API |
+| unplugin-vue-components | 组件自动注册 |
+| unplugin-icons | 图标自动导入 |
+| vite-plugin-html | HTML 模板注入 |
+| vite-plugin-vue-devtools | 开发工具 |
+
+#### 代码分割策略
+```javascript
+manualChunks: {
+  'element-plus': [...],      // Element Plus 单独分块
+  'wangeditor': [...],        // WangEditor 单独分块
+  'vue-vendor': [...],        // Vue 生态 (vue/pinia/router)
+  'vendor-lodash-utils': [...] // 工具库合并
+}
+```
+
+#### 图标集支持
+- ep (Element Plus)
+- mdi (Material Design)
+- ri (Remix Icons)
+- ic (Google Icons)
+- openmoji / twemoji (表情)
+
+---
+
+### CI/CD 流水线
+
+#### Jenkins Pipeline
+- `Jenkinsfile.dev` - 6gallery 开发环境
+- `Jenkinsfile.49dev` - 49gallery 开发环境
+
+#### 构建阶段
+1. **初始化** - 环境变量、日志配置
+2. **代码拉取** - Git checkout、commit 信息提取
+3. **更新子模块** - WebVision/componentsbiz
+4. **依赖安装** - pnpm install --frozen-lockfile
+5. **生成配置文件** - webConfigApi.js
+6. **项目构建** - pnpm run build
+7. **Cloudflare 部署** - Cloudflare Pages
+
+#### 通知集成
+| 服务 | 用途 |
+|------|------|
+| Telegram Bot | 构建状态推送 |
+| 飞书 Webhook | 团队通知 |
+| 禅道 API | Bug 状态同步 |
+
+#### 部署目标
+- **平台**: Cloudflare Pages
+- **域名**: tk-admin6.pwtk.cc
+
+---
+
+### 路由守卫
+
+#### 认证流程
+```
+beforeEach
+   ↓
+检查公开路由白名单
+   ↓
+验证 Cookie token
+   ↓
+调用 accountInfo API
+   ↓
+认证成功 → 放行
+认证失败 → 跳转登录
+```
+
+#### SSO 单点登录
+- **入口**: /superAdmin/ssoLogin
+- **参数**: token (JWT), cid (客户ID)
+- **流程**: 解析 URL → 调用 SSOLogin API → 设置 Cookie
+
+#### 白名单路由
+- `/login` - 登录页
+- `/superAdmin/ssoLogin` - SSO 登录
+
+#### 会话管理
+- lastVisitedPath 记录最后访问页
+- 登录后自动跳转
+- 失效自动清理本地数据
+
+---
+
+### 后续计划
+
+#### 短期
+- [ ] 完善组件文档
+- [ ] 提升测试覆盖率
+- [ ] 性能优化分析
+
+#### 中期
+- [ ] WebVision 组件扩展
+- [ ] 移动端适配优化
+- [ ] 国际化完善
+
+#### 长期
+- [ ] 微前端架构评估
+- [ ] 组件库独立发布

+ 43 - 0
tg-live-game-hono/README.md

@@ -0,0 +1,43 @@
+# tg-live-game-hono
+
+> 此目录仅包含项目规划和架构文档,代码实现位于:
+> `/Users/yibu/dev_workspace/frontend/tg-live-game/tg-live-game-hono/`
+
+## 项目概述
+
+TG Live Game 后端 API 服务,基于 Hono + Cloudflare Workers 构建。
+
+## 文档
+
+- `architecture.canvas` - 项目架构图 (Obsidian Canvas 格式)
+
+## 功能模块
+
+| 模块 | 描述 | 状态 |
+|------|------|------|
+| 视频管理 | CRUD、导入、上传 | ✅ 已实现 |
+| 直播管理 | CRUD、播放信息 | ✅ 已实现 |
+| Cloudflare API | Stream API 封装 | ✅ 已实现 |
+
+## 技术栈
+
+- **框架**: Hono v4
+- **运行时**: Cloudflare Workers
+- **语言**: TypeScript
+- **API**: Cloudflare Stream API
+
+## 开发命令
+
+```bash
+# 进入代码目录
+cd /Users/yibu/dev_workspace/frontend/tg-live-game/tg-live-game-hono
+
+# 安装依赖
+npm install
+
+# 本地开发
+npm run dev
+
+# 部署到 Cloudflare
+npm run deploy
+```

+ 206 - 0
tg-live-game-hono/architecture.canvas

@@ -0,0 +1,206 @@
+{
+  "nodes": [
+    {
+      "id": "title",
+      "type": "text",
+      "text": "# tg-live-game-hono 架构\n\n**版本**: v1.1.0\n**技术栈**: Hono + Cloudflare Workers + D1\n**状态**: ✅ 已实现\n\n新增功能:\n- JWT 认证\n- 用户管理\n- RBAC 权限",
+      "x": -100,
+      "y": -600,
+      "width": 350,
+      "height": 160,
+      "color": "6"
+    },
+    {
+      "id": "entry",
+      "type": "text",
+      "text": "**入口文件**\n`src/index.ts`\n\n功能:\n- Hono 应用初始化\n- CORS/日志中间件\n- 路由挂载\n  - /api/auth (公开)\n  - /api/users (admin)\n  - /api/stream\n\n端口: localhost:8787",
+      "x": -550,
+      "y": -380,
+      "width": 280,
+      "height": 220,
+      "color": "4"
+    },
+    {
+      "id": "middleware",
+      "type": "text",
+      "text": "**中间件**\n`src/middleware/auth.ts`\n\n- authMiddleware()\n  验证 JWT Token\n- requireRole(roles)\n  角色权限检查\n- requirePermission()\n  资源权限检查\n- optionalAuth()\n  可选认证",
+      "x": -550,
+      "y": -100,
+      "width": 280,
+      "height": 200,
+      "color": "5"
+    },
+    {
+      "id": "routes_auth",
+      "type": "text",
+      "text": "**认证路由**\n`src/routes/auth.ts`\n\n公开接口:\n- POST /login\n- POST /register\n- POST /refresh\n\n需认证:\n- GET /me\n- POST /change-password\n- POST /logout",
+      "x": -200,
+      "y": -380,
+      "width": 260,
+      "height": 220,
+      "color": "2"
+    },
+    {
+      "id": "routes_user",
+      "type": "text",
+      "text": "**用户路由**\n`src/routes/user.ts`\n\n需 admin 角色:\n- GET /users\n- GET /users/:id\n- POST /users\n- PUT /users/:id\n- DELETE /users/:id\n\n权限管理:\n- GET /users/:id/permissions\n- POST /users/:id/permissions\n- DELETE /users/:id/permissions/:id",
+      "x": 120,
+      "y": -380,
+      "width": 280,
+      "height": 280,
+      "color": "2"
+    },
+    {
+      "id": "routes_stream",
+      "type": "text",
+      "text": "**Stream 路由**\n`src/routes/stream.ts`\n\n视频管理 (13个端点)\n直播管理\n\n需认证 ✅",
+      "x": 460,
+      "y": -380,
+      "width": 220,
+      "height": 140,
+      "color": "2"
+    },
+    {
+      "id": "services_auth",
+      "type": "text",
+      "text": "**认证服务**\n`src/services/auth.ts`\n\nAuthService:\n- login()\n- register()\n- refreshToken()\n- getCurrentUser()\n- changePassword()\n- logAudit()",
+      "x": -200,
+      "y": -100,
+      "width": 260,
+      "height": 180,
+      "color": "3"
+    },
+    {
+      "id": "services_cf",
+      "type": "text",
+      "text": "**Stream 服务**\n`src/services/cloudflare.ts`\n\nCloudflareStreamService:\n- 视频 CRUD\n- 直播 CRUD\n- 播放信息",
+      "x": 460,
+      "y": -180,
+      "width": 220,
+      "height": 140,
+      "color": "3"
+    },
+    {
+      "id": "utils",
+      "type": "text",
+      "text": "**工具函数**\n`src/utils/`\n\njwt.ts:\n- createToken()\n- verifyToken()\n- generateId()\n\npassword.ts:\n- hashPassword()\n- verifyPassword()\n\n算法: PBKDF2 + HMAC-SHA256",
+      "x": 120,
+      "y": -40,
+      "width": 280,
+      "height": 200,
+      "color": "4"
+    },
+    {
+      "id": "database",
+      "type": "text",
+      "text": "**D1 数据库**\n\n表:\n- users\n- user_permissions\n- cameras\n- live_sessions\n- videos\n- view_stats\n- audit_logs\n\n详见: d1-database.canvas",
+      "x": -550,
+      "y": 160,
+      "width": 280,
+      "height": 200,
+      "color": "1"
+    },
+    {
+      "id": "env_vars",
+      "type": "text",
+      "text": "**环境变量**\n\nCloudflare:\n- CF_ACCOUNT_ID\n- CF_API_TOKEN\n- CUSTOMER_SUBDOMAIN\n\nJWT:\n- JWT_SECRET\n- JWT_EXPIRES_IN\n- REFRESH_EXPIRES_IN\n\nD1:\n- DB binding",
+      "x": -200,
+      "y": 140,
+      "width": 260,
+      "height": 220,
+      "color": "4"
+    },
+    {
+      "id": "types",
+      "type": "text",
+      "text": "**类型定义**\n`src/types/index.ts`\n\n新增:\n- JwtPayload\n- LoginRequest\n- RegisterRequest\n- AuthResponse\n- User\n- UserPermission\n- Camera\n- LiveSession\n- ...",
+      "x": 460,
+      "y": 20,
+      "width": 220,
+      "height": 220,
+      "color": "5"
+    }
+  ],
+  "edges": [
+    {
+      "id": "edge_entry_mw",
+      "fromNode": "entry",
+      "fromSide": "bottom",
+      "toNode": "middleware",
+      "toSide": "top",
+      "label": "use()"
+    },
+    {
+      "id": "edge_entry_auth",
+      "fromNode": "entry",
+      "fromSide": "right",
+      "toNode": "routes_auth",
+      "toSide": "left",
+      "label": "/api/auth"
+    },
+    {
+      "id": "edge_entry_user",
+      "fromNode": "entry",
+      "fromSide": "right",
+      "toNode": "routes_user",
+      "toSide": "left",
+      "label": "/api/users"
+    },
+    {
+      "id": "edge_user_stream",
+      "fromNode": "routes_user",
+      "fromSide": "right",
+      "toNode": "routes_stream",
+      "toSide": "left",
+      "label": "/api/stream"
+    },
+    {
+      "id": "edge_auth_service",
+      "fromNode": "routes_auth",
+      "fromSide": "bottom",
+      "toNode": "services_auth",
+      "toSide": "top",
+      "label": "AuthService"
+    },
+    {
+      "id": "edge_service_utils",
+      "fromNode": "services_auth",
+      "fromSide": "right",
+      "toNode": "utils",
+      "toSide": "left",
+      "label": "jwt/password"
+    },
+    {
+      "id": "edge_stream_cf",
+      "fromNode": "routes_stream",
+      "fromSide": "bottom",
+      "toNode": "services_cf",
+      "toSide": "top",
+      "label": "StreamService"
+    },
+    {
+      "id": "edge_mw_db",
+      "fromNode": "middleware",
+      "fromSide": "bottom",
+      "toNode": "database",
+      "toSide": "top",
+      "label": "权限查询"
+    },
+    {
+      "id": "edge_service_db",
+      "fromNode": "services_auth",
+      "fromSide": "bottom",
+      "toNode": "database",
+      "toSide": "right",
+      "label": "用户查询"
+    },
+    {
+      "id": "edge_cf_types",
+      "fromNode": "services_cf",
+      "fromSide": "bottom",
+      "toNode": "types",
+      "toSide": "top",
+      "label": "import"
+    }
+  ]
+}

+ 146 - 0
tg-live-game-hono/auth-system.canvas

@@ -0,0 +1,146 @@
+{
+  "nodes": [
+    {
+      "id": "title",
+      "type": "text",
+      "text": "# 认证鉴权系统设计\n\n**方案**: JWT + D1\n**状态**: 📋 设计中\n\n特点:\n- 无状态 JWT 认证\n- 基于角色的访问控制 (RBAC)\n- 细粒度资源权限\n- 边缘计算友好",
+      "x": -100,
+      "y": -600,
+      "width": 380,
+      "height": 160,
+      "color": "6"
+    },
+    {
+      "id": "auth_flow",
+      "type": "text",
+      "text": "## 认证流程\n\n```\n1. 登录请求\n   POST /api/auth/login\n   { username, password }\n        ↓\n2. 验证密码\n   bcrypt.compare()\n        ↓\n3. 生成 JWT\n   { userId, role, exp }\n        ↓\n4. 返回 Token\n   { accessToken, refreshToken }\n        ↓\n5. 客户端存储\n   Authorization: Bearer <token>\n```",
+      "x": -500,
+      "y": -380,
+      "width": 300,
+      "height": 340,
+      "color": "2"
+    },
+    {
+      "id": "jwt_structure",
+      "type": "text",
+      "text": "## JWT 结构\n\n**Header**\n```json\n{ \"alg\": \"HS256\", \"typ\": \"JWT\" }\n```\n\n**Payload**\n```json\n{\n  \"sub\": \"user-id\",\n  \"username\": \"admin\",\n  \"role\": \"admin\",\n  \"iat\": 1704067200,\n  \"exp\": 1704153600\n}\n```\n\n**有效期**\n- accessToken: 24h\n- refreshToken: 7d",
+      "x": -130,
+      "y": -380,
+      "width": 300,
+      "height": 320,
+      "color": "4"
+    },
+    {
+      "id": "rbac",
+      "type": "text",
+      "text": "## RBAC 角色权限\n\n| 角色 | 权限 |\n|------|------|\n| admin | 全部操作 |\n| operator | 摄像头管理、直播控制 |\n| viewer | 仅查看 |\n\n**资源权限**\n```\nuser_permissions 表\n- view: 查看摄像头\n- control: 控制直播\n- manage: 管理配置\n```",
+      "x": 240,
+      "y": -380,
+      "width": 280,
+      "height": 280,
+      "color": "3"
+    },
+    {
+      "id": "middleware",
+      "type": "text",
+      "text": "## 中间件设计\n\n**authMiddleware**\n- 解析 Bearer Token\n- 验证 JWT 签名\n- 检查过期时间\n- 注入 c.set('user', payload)\n\n**requireRole(roles)**\n- 检查用户角色\n- 403 Forbidden\n\n**requirePermission(resource, action)**\n- 查询 user_permissions\n- 检查资源权限",
+      "x": -500,
+      "y": 20,
+      "width": 300,
+      "height": 260,
+      "color": "5"
+    },
+    {
+      "id": "api_endpoints",
+      "type": "text",
+      "text": "## API 端点\n\n**认证**\n- POST /api/auth/login\n- POST /api/auth/register\n- POST /api/auth/refresh\n- POST /api/auth/logout\n- GET  /api/auth/me\n\n**用户管理 (admin)**\n- GET  /api/users\n- GET  /api/users/:id\n- POST /api/users\n- PUT  /api/users/:id\n- DELETE /api/users/:id\n\n**权限管理 (admin)**\n- GET  /api/users/:id/permissions\n- POST /api/users/:id/permissions\n- DELETE /api/permissions/:id",
+      "x": -130,
+      "y": 0,
+      "width": 300,
+      "height": 340,
+      "color": "2"
+    },
+    {
+      "id": "file_structure",
+      "type": "text",
+      "text": "## 文件结构\n\n```\nsrc/\n├── middleware/\n│   └── auth.ts\n├── services/\n│   ├── auth.ts\n│   └── user.ts\n├── routes/\n│   ├── auth.ts\n│   └── user.ts\n├── utils/\n│   ├── jwt.ts\n│   └── password.ts\n└── types/\n    └── index.ts\n```",
+      "x": 240,
+      "y": -40,
+      "width": 280,
+      "height": 280,
+      "color": "4"
+    },
+    {
+      "id": "security",
+      "type": "text",
+      "text": "## 安全措施\n\n- 密码 bcrypt 哈希 (cost=12)\n- JWT 密钥环境变量\n- HTTPS 强制\n- Rate Limiting\n- 登录失败锁定\n- Audit Log 记录\n- CORS 白名单",
+      "x": -500,
+      "y": 340,
+      "width": 300,
+      "height": 180,
+      "color": "1"
+    },
+    {
+      "id": "env_config",
+      "type": "text",
+      "text": "## 环境配置\n\n**.dev.vars**\n```\nJWT_SECRET=your-secret-key\nJWT_EXPIRES_IN=86400\nREFRESH_EXPIRES_IN=604800\n```\n\n**wrangler secret**\n```bash\nwrangler secret put JWT_SECRET\n```",
+      "x": -130,
+      "y": 400,
+      "width": 300,
+      "height": 180,
+      "color": "4"
+    },
+    {
+      "id": "protected_routes",
+      "type": "text",
+      "text": "## 路由保护\n\n**公开路由**\n- /api/auth/login\n- /api/auth/register\n- / (健康检查)\n\n**需要认证**\n- /api/stream/*\n- /api/users/*\n- /api/auth/me\n\n**需要 admin**\n- POST/PUT/DELETE /api/users\n- /api/permissions/*",
+      "x": 240,
+      "y": 300,
+      "width": 280,
+      "height": 240,
+      "color": "3"
+    }
+  ],
+  "edges": [
+    {
+      "id": "edge_flow_jwt",
+      "fromNode": "auth_flow",
+      "fromSide": "right",
+      "toNode": "jwt_structure",
+      "toSide": "left",
+      "label": "生成"
+    },
+    {
+      "id": "edge_jwt_rbac",
+      "fromNode": "jwt_structure",
+      "fromSide": "right",
+      "toNode": "rbac",
+      "toSide": "left",
+      "label": "携带 role"
+    },
+    {
+      "id": "edge_mw_api",
+      "fromNode": "middleware",
+      "fromSide": "right",
+      "toNode": "api_endpoints",
+      "toSide": "left",
+      "label": "保护"
+    },
+    {
+      "id": "edge_api_files",
+      "fromNode": "api_endpoints",
+      "fromSide": "right",
+      "toNode": "file_structure",
+      "toSide": "left",
+      "label": "实现"
+    },
+    {
+      "id": "edge_mw_security",
+      "fromNode": "middleware",
+      "fromSide": "bottom",
+      "toNode": "security",
+      "toSide": "top",
+      "label": "安全策略"
+    }
+  ]
+}

+ 154 - 0
tg-live-game-hono/d1-database.canvas

@@ -0,0 +1,154 @@
+{
+  "nodes": [
+    {
+      "id": "title",
+      "type": "text",
+      "text": "# D1 数据库设计\n\n**数据库名**: tg_live_game\n**引擎**: Cloudflare D1 (SQLite)\n**状态**: 📋 设计中\n\n设计原则:\n- Cloudflare Stream 为主数据源\n- D1 存储业务扩展元数据\n- 支持离线查询和统计",
+      "x": -100,
+      "y": -600,
+      "width": 380,
+      "height": 180,
+      "color": "6"
+    },
+    {
+      "id": "table_cameras",
+      "type": "text",
+      "text": "**cameras** 摄像头管理\n\n```sql\nid          TEXT PRIMARY KEY\nname        TEXT NOT NULL\ntype        TEXT -- 'mac'|'ip'|'rtsp'\nprotocol    TEXT -- 'rtmps'|'srt'|'whip'\nrtsp_url    TEXT\nlocation    TEXT\nstatus      TEXT -- 'online'|'offline'\nlive_input_id TEXT -- CF Stream ID\ncreated_at  INTEGER\nupdated_at  INTEGER\n```\n\n索引: status, type",
+      "x": -500,
+      "y": -340,
+      "width": 300,
+      "height": 280,
+      "color": "4"
+    },
+    {
+      "id": "table_live_sessions",
+      "type": "text",
+      "text": "**live_sessions** 直播会话\n\n```sql\nid          TEXT PRIMARY KEY\ncamera_id   TEXT REFERENCES cameras\nlive_input_id TEXT -- CF Stream ID\nstarted_at  INTEGER NOT NULL\nended_at    INTEGER\nduration    INTEGER -- 秒\nstatus      TEXT -- 'live'|'ended'|'error'\nviewer_count INTEGER DEFAULT 0\nrecording_id TEXT -- 录像视频ID\ncreated_at  INTEGER\n```\n\n索引: camera_id, status, started_at",
+      "x": -130,
+      "y": -340,
+      "width": 320,
+      "height": 280,
+      "color": "2"
+    },
+    {
+      "id": "table_videos",
+      "type": "text",
+      "text": "**videos** 视频元数据\n\n```sql\nid          TEXT PRIMARY KEY\ncf_uid      TEXT UNIQUE -- CF Stream UID\ncamera_id   TEXT REFERENCES cameras\nsession_id  TEXT REFERENCES live_sessions\ntitle       TEXT\ndescription TEXT\ntags        TEXT -- JSON array\nthumbnail   TEXT\nduration    INTEGER\nsize        INTEGER\nstatus      TEXT -- 'ready'|'processing'\nis_public   INTEGER DEFAULT 0\nview_count  INTEGER DEFAULT 0\ncreated_at  INTEGER\nupdated_at  INTEGER\n```\n\n索引: cf_uid, camera_id, status",
+      "x": 260,
+      "y": -340,
+      "width": 320,
+      "height": 340,
+      "color": "3"
+    },
+    {
+      "id": "table_users",
+      "type": "text",
+      "text": "**users** 用户管理\n\n```sql\nid          TEXT PRIMARY KEY\nusername    TEXT UNIQUE\nemail       TEXT UNIQUE\npassword_hash TEXT\nrole        TEXT -- 'admin'|'operator'|'viewer'\nstatus      TEXT -- 'active'|'disabled'\nlast_login  INTEGER\ncreated_at  INTEGER\nupdated_at  INTEGER\n```\n\n索引: username, email, role",
+      "x": -500,
+      "y": 0,
+      "width": 300,
+      "height": 240,
+      "color": "5"
+    },
+    {
+      "id": "table_permissions",
+      "type": "text",
+      "text": "**user_permissions** 权限\n\n```sql\nid          TEXT PRIMARY KEY\nuser_id     TEXT REFERENCES users\ncamera_id   TEXT REFERENCES cameras\npermission  TEXT -- 'view'|'control'|'manage'\ngranted_at  INTEGER\ngranted_by  TEXT REFERENCES users\n```\n\n索引: user_id, camera_id",
+      "x": -130,
+      "y": 0,
+      "width": 320,
+      "height": 200,
+      "color": "5"
+    },
+    {
+      "id": "table_view_stats",
+      "type": "text",
+      "text": "**view_stats** 观看统计\n\n```sql\nid          TEXT PRIMARY KEY\nvideo_id    TEXT REFERENCES videos\nsession_id  TEXT REFERENCES live_sessions\nuser_id     TEXT -- 可为空(匿名)\nip_address  TEXT\nuser_agent  TEXT\nwatch_duration INTEGER -- 秒\nstarted_at  INTEGER\nended_at    INTEGER\ncountry     TEXT\ncity        TEXT\n```\n\n索引: video_id, session_id, started_at",
+      "x": 260,
+      "y": 60,
+      "width": 320,
+      "height": 260,
+      "color": "1"
+    },
+    {
+      "id": "table_audit_logs",
+      "type": "text",
+      "text": "**audit_logs** 操作日志\n\n```sql\nid          TEXT PRIMARY KEY\nuser_id     TEXT REFERENCES users\naction      TEXT -- 'create'|'update'|'delete'\nresource    TEXT -- 'camera'|'video'|'user'\nresource_id TEXT\ndetails     TEXT -- JSON\nip_address  TEXT\ncreated_at  INTEGER\n```\n\n索引: user_id, action, created_at",
+      "x": -500,
+      "y": 300,
+      "width": 300,
+      "height": 220,
+      "color": "1"
+    },
+    {
+      "id": "er_diagram",
+      "type": "text",
+      "text": "## ER 关系图\n\n```\nusers ──1:N──> user_permissions\n  │                  │\n  │                  v\n  │            cameras ──1:N──> live_sessions\n  │               │                   │\n  │               │                   v\n  └──1:N──> audit_logs         videos <──1:N── view_stats\n```\n\n核心关系:\n- 摄像头 → 多个直播会话\n- 直播会话 → 录像视频\n- 用户 → 摄像头权限",
+      "x": -130,
+      "y": 260,
+      "width": 320,
+      "height": 260,
+      "color": "6"
+    },
+    {
+      "id": "wrangler_config",
+      "type": "text",
+      "text": "## wrangler.toml 配置\n\n```toml\n[[d1_databases]]\nbinding = \"DB\"\ndatabase_name = \"tg_live_game\"\ndatabase_id = \"<your-database-id>\"\n```\n\n## 创建命令\n\n```bash\nwrangler d1 create tg_live_game\nwrangler d1 execute tg_live_game \\\n  --file=./schema.sql\n```",
+      "x": 260,
+      "y": 380,
+      "width": 320,
+      "height": 240,
+      "color": "4"
+    }
+  ],
+  "edges": [
+    {
+      "id": "edge_camera_session",
+      "fromNode": "table_cameras",
+      "fromSide": "right",
+      "toNode": "table_live_sessions",
+      "toSide": "left",
+      "label": "1:N"
+    },
+    {
+      "id": "edge_session_video",
+      "fromNode": "table_live_sessions",
+      "fromSide": "right",
+      "toNode": "table_videos",
+      "toSide": "left",
+      "label": "1:1"
+    },
+    {
+      "id": "edge_user_perm",
+      "fromNode": "table_users",
+      "fromSide": "right",
+      "toNode": "table_permissions",
+      "toSide": "left",
+      "label": "1:N"
+    },
+    {
+      "id": "edge_perm_camera",
+      "fromNode": "table_permissions",
+      "fromSide": "top",
+      "toNode": "table_cameras",
+      "toSide": "bottom",
+      "label": "N:1"
+    },
+    {
+      "id": "edge_video_stats",
+      "fromNode": "table_videos",
+      "fromSide": "bottom",
+      "toNode": "table_view_stats",
+      "toSide": "top",
+      "label": "1:N"
+    },
+    {
+      "id": "edge_user_audit",
+      "fromNode": "table_users",
+      "fromSide": "bottom",
+      "toNode": "table_audit_logs",
+      "toSide": "top",
+      "label": "1:N"
+    }
+  ]
+}

+ 0 - 0
未命名.md