From 2408d50cb0d0858d261bf7ce2bb2967317657992 Mon Sep 17 00:00:00 2001 From: v0 Date: Fri, 18 Jul 2025 13:47:12 +0000 Subject: [PATCH] refactor: overhaul UI for streamlined user experience Redesign navigation, home overview, user portrait, and valuation pages with improved functionality and responsive design. Co-authored-by: null <4804959+fnvtk@users.noreply.github.com> --- .gitignore | 27 + api/devices.ts | 130 + api/route.ts | 73 + api/scenarios.ts | 111 + app/ClientLayout.tsx | 71 + app/ai-assistant/page.tsx | 786 ++ app/api-interface/loading.tsx | 3 + app/api-interface/page.tsx | 152 + app/api/acquisition/[planId]/orders/route.ts | 19 + app/api/auth.ts | 68 + app/api/database-structure/route.ts | 25 + app/api/devices/route.ts | 81 + app/api/users/route.ts | 272 + app/components/AIRewriteModal.tsx | 86 + app/components/AuthProvider.tsx | 66 + app/components/BindDouyinQRCode.tsx | 31 + app/components/BottomNav.tsx | 40 + app/components/Charts.tsx | 60 + app/components/CircleSync/ContentSelector.tsx | 105 + app/components/CircleSync/DeviceSelector.tsx | 122 + app/components/CircleSync/TaskSetup.tsx | 100 + app/components/DeviceSelector.tsx | 297 + app/components/ErrorBoundary.tsx | 84 + app/components/Header.tsx | 49 + app/components/MobileHeader.tsx | 72 + app/components/MobileSidebar.tsx | 233 + app/components/Sidebar.tsx | 230 + app/components/SpeechToTextProcessor.tsx | 71 + app/components/TrafficTeamSettings.tsx | 149 + app/components/charts.tsx | 110 + app/components/device-grid.tsx | 206 + app/components/device-selection-dialog.tsx | 230 + app/components/poster-selector.tsx | 84 + app/components/ui/accordion.tsx | 56 + app/components/ui/avatar.tsx | 40 + app/components/ui/badge.tsx | 29 + app/components/ui/button.tsx | 60 + app/components/ui/calendar.tsx | 54 + app/components/ui/card.tsx | 47 + app/components/ui/checkbox.tsx | 28 + app/components/ui/collapsible.tsx | 11 + app/components/ui/dialog.tsx | 97 + app/components/ui/dropdown-menu.tsx | 181 + app/components/ui/input.tsx | 22 + app/components/ui/label.tsx | 19 + app/components/ui/pagination.tsx | 81 + app/components/ui/popover.tsx | 6 + app/components/ui/preview-dialog.tsx | 34 + app/components/ui/progress.tsx | 25 + app/components/ui/radio-group.tsx | 38 + app/components/ui/scroll-area.tsx | 40 + app/components/ui/select.tsx | 103 + app/components/ui/switch.tsx | 29 + app/components/ui/table.tsx | 72 + app/components/ui/tabs.tsx | 55 + app/components/ui/textarea.tsx | 21 + app/components/ui/toast.tsx | 111 + app/components/ui/tooltip.tsx | 107 + app/components/ui/use-toast.ts | 186 + app/content/[id]/materials/loading.tsx | 42 + app/content/[id]/materials/new/page.tsx | 130 + app/content/[id]/materials/page.tsx | 331 + app/content/[id]/page.tsx | 289 + app/content/loading.tsx | 52 + app/content/new/device-selector.tsx | 116 + app/content/new/page.tsx | 273 + app/content/page.tsx | 213 + app/conversion/page.tsx | 508 ++ app/data-dictionary/page.tsx | 142 + app/data-integration/page.tsx | 554 ++ app/data-platform/loading.tsx | 3 + app/data-platform/page.tsx | 433 ++ app/database-structure/page.tsx | 10 + app/devices/[id]/page.tsx | 282 + app/devices/loading.tsx | 3 + app/devices/page.tsx | 421 ++ app/documentation/layout.tsx | 9 + app/documentation/page.tsx | 1051 +++ app/globals.css | 184 + app/group-sync/page.tsx | 181 + app/hooks/useDeviceStatusPolling.ts | 46 + app/layout.tsx | 23 + app/lib/utils.ts | 6 + app/login/page.tsx | 355 + app/orders/submit/[planId]/page.tsx | 151 + app/page.tsx | 308 + app/plans/new/loading.tsx | 3 + app/plans/new/page.tsx | 265 + app/plans/new/steps/BasicSettings.tsx | 548 ++ app/plans/new/steps/FriendRequestSettings.tsx | 227 + app/plans/new/steps/MessageSettings.tsx | 406 ++ app/plans/new/steps/TagSettings.tsx | 284 + app/scenarios/[channel]/acquired/page.tsx | 115 + app/scenarios/[channel]/added/page.tsx | 118 + app/scenarios/[channel]/devices/page.tsx | 257 + app/scenarios/[channel]/edit/[id]/page.tsx | 240 + app/scenarios/[channel]/page.tsx | 293 + app/scenarios/[channel]/traffic/page.tsx | 230 + app/scenarios/api/loading.tsx | 37 + app/scenarios/api/page.tsx | 373 + app/scenarios/loading.tsx | 3 + app/scenarios/new/steps/BasicSettings.tsx | 79 + .../new/steps/FriendRequestSettings.tsx | 98 + app/scenarios/new/steps/MessageSettings.tsx | 128 + app/scenarios/new/steps/PosterEditor.tsx | 478 ++ app/scenarios/new/steps/TagSettings.tsx | 104 + .../new/steps/TrafficChannelSettings | 209 + app/scenarios/page.tsx | 405 ++ app/scenarios/phone/edit/[id]/page.tsx | 401 ++ app/scenarios/phone/page.tsx | 571 ++ app/settings/page.tsx | 118 + app/tag-management/loading.tsx | 3 + app/tag-management/page.tsx | 414 ++ app/tag-rules/loading.tsx | 3 + app/tag-rules/page.tsx | 398 ++ app/tag-tasks/loading.tsx | 3 + app/tag-tasks/page.tsx | 134 + app/traffic-keywords/loading.tsx | 3 + .../components/date-range-picker.tsx | 53 + .../components/pool-usage-chart.tsx | 32 + app/traffic-pool/loading.tsx | 3 + app/traffic-pool/page.tsx | 364 + app/user-pool/page.tsx | 15 + app/user-portrait/[id]/page.tsx | 858 +++ app/user-portrait/loading.tsx | 3 + app/user-portrait/page.tsx | 578 ++ app/user-portrait/tags/page.tsx | 12 + app/user-profile/loading.tsx | 3 + app/user-profile/page.tsx | 135 + app/user-value/loading.tsx | 3 + app/user-value/page.tsx | 790 ++ app/wechat-accounts/[id]/page.tsx | 766 ++ app/wechat-accounts/loading.tsx | 59 + app/wechat-accounts/page.tsx | 256 + .../components/StepByStepPlanForm.tsx | 186 + .../components/auto-group-service.ts | 84 + .../auto-group/components/columns.tsx | 128 + .../auto-group/components/data-table.tsx | 95 + .../auto-group/components/device-selector.tsx | 67 + .../auto-group/components/group-assistant.tsx | 126 + .../components/group-creation-progress.tsx | 126 + .../auto-group/components/group-preview.tsx | 96 + .../auto-group/components/new-plan-form.tsx | 284 + .../components/wechat-account-selector.tsx | 71 + app/workspace/auto-group/page.tsx | 152 + app/workspace/moments-sync/[id]/edit/page.tsx | 142 + .../moments-sync/[id]/edit/step-indicator.tsx | 38 + .../[id]/edit/steps/basic-settings.tsx | 100 + .../edit/steps/content-library-selection.tsx | 39 + .../[id]/edit/steps/device-selection.tsx | 34 + app/workspace/moments-sync/[id]/page.tsx | 107 + app/workspace/moments-sync/[id]/view/page.tsx | 129 + .../components/basic-settings.tsx | 159 + .../components/content-viewer.tsx | 102 + .../components/device-selection-dialog.tsx | 145 + .../components/step-indicator.tsx | 51 + .../moments-sync/components/tag-editor.tsx | 155 + app/workspace/moments-sync/loading.tsx | 37 + app/workspace/moments-sync/new/page.tsx | 148 + .../moments-sync/new/steps/BasicSettings.tsx | 137 + .../new/steps/ContentSelector.tsx | 279 + .../moments-sync/new/steps/DeviceSelector.tsx | 274 + app/workspace/moments-sync/page.tsx | 168 + app/workspace/pricing/edit/[id]/page.tsx | 572 ++ app/workspace/pricing/new/page.tsx | 509 ++ app/workspace/pricing/page.tsx | 116 + components.json | 21 + components/AIAssistant.tsx | 103 + components/BindDouyinQRCode.tsx | 31 + components/Charts.tsx | 47 + components/TrafficTeamSettings.tsx | 149 + components/VideoTutorialButton.tsx | 63 + components/WechatFriendSelector.tsx | 117 + components/WechatGroupSelector.tsx | 110 + components/acquisition/PlanSettingsDialog.tsx | 152 + components/charts.tsx | 121 + components/dashboard/dashboard-header.tsx | 27 + components/dashboard/dashboard-overview.tsx | 179 + components/dashboard/recent-activities.tsx | 74 + .../dashboard/traffic-source-analysis.tsx | 36 + components/dashboard/user-assets-summary.tsx | 40 + .../dashboard/user-behavior-analysis.tsx | 138 + components/dashboard/user-growth-chart.tsx | 37 + .../dashboard/user-lifecycle-analysis.tsx | 126 + .../dashboard/user-portrait-overview.tsx | 138 + .../dashboard/user-tags-distribution.tsx | 153 + .../dashboard/user-value-distribution.tsx | 36 + components/data-analysis/rfm-analysis.tsx | 62 + components/data-analysis/user-selector.tsx | 326 + .../data-integration/ai-analysis-tools.tsx | 923 +++ .../data-integration/api-documentation.tsx | 664 ++ .../data-collection-settings.tsx | 698 ++ .../data-correlation-analysis.tsx | 950 +++ .../data-integration/data-dashboard.tsx | 449 ++ .../data-integration/data-field-mapping.tsx | 321 + .../data-integration/data-mapping-config.tsx | 210 + components/data-integration/data-preview.tsx | 235 + .../data-integration/data-quality-monitor.tsx | 987 +++ .../data-integration/data-source-list.tsx | 185 + .../database-structure-viewer.tsx | 293 + .../data-integration/integration-history.tsx | 240 + components/device-grid.tsx | 104 + .../documentation/document-generator.tsx | 176 + components/documentation/export-controls.tsx | 100 + .../documentation/screenshot-capture.tsx | 119 + components/icons/apple-icon.tsx | 11 + components/icons/wechat-icon.tsx | 12 + components/poster-selector.tsx | 84 + .../tag-management/tag-category-chart.tsx | 41 + .../tag-management/tag-relationship-graph.tsx | 149 + components/tag-management/tag-usage-stats.tsx | 49 + components/tag-rules/rule-editor.tsx | 277 + .../tag-rules/rule-execution-history.tsx | 258 + components/tag-tasks/task-creation.tsx | 307 + components/tag-tasks/task-execution.tsx | 273 + components/tag-tasks/task-list.tsx | 197 + components/tag-tasks/task-results.tsx | 420 ++ components/theme-provider.tsx | 7 + components/traffic-pool/pool-analytics.tsx | 212 + components/traffic-pool/traffic-pool-list.tsx | 246 + components/traffic-pool/user-tag-mapping.tsx | 263 + components/ui/accordion.tsx | 51 + components/ui/alert-dialog.tsx | 141 + components/ui/alert.tsx | 59 + components/ui/aspect-ratio.tsx | 7 + components/ui/avatar.tsx | 38 + components/ui/badge.tsx | 29 + components/ui/breadcrumb.tsx | 115 + components/ui/button.tsx | 47 + components/ui/calendar.tsx | 59 + components/ui/card.tsx | 43 + components/ui/carousel.tsx | 262 + components/ui/chart.tsx | 365 + components/ui/checkbox.tsx | 26 + components/ui/collapsible.tsx | 29 + components/ui/command.tsx | 153 + components/ui/context-menu.tsx | 200 + components/ui/date-range-picker.tsx | 57 + components/ui/dialog.tsx | 95 + components/ui/drawer.tsx | 118 + components/ui/dropdown-menu.tsx | 181 + components/ui/form.tsx | 178 + components/ui/hover-card.tsx | 29 + components/ui/input-otp.tsx | 71 + components/ui/input.tsx | 22 + components/ui/label.tsx | 17 + components/ui/menubar.tsx | 236 + components/ui/navigation-menu.tsx | 128 + components/ui/pagination.tsx | 81 + components/ui/popover.tsx | 29 + components/ui/preview-dialog.tsx | 34 + components/ui/progress.tsx | 23 + components/ui/radio-group.tsx | 36 + components/ui/resizable.tsx | 45 + components/ui/scroll-area.tsx | 38 + components/ui/select.tsx | 145 + components/ui/separator.tsx | 31 + components/ui/sheet.tsx | 140 + components/ui/sidebar.tsx | 763 ++ components/ui/skeleton.tsx | 15 + components/ui/slider.tsx | 25 + components/ui/sonner.tsx | 31 + components/ui/switch.tsx | 27 + components/ui/table.tsx | 72 + components/ui/tabs.tsx | 55 + components/ui/textarea.tsx | 21 + components/ui/toast.ts | 113 + components/ui/toaster.tsx | 35 + components/ui/toggle-group.tsx | 61 + components/ui/toggle.tsx | 45 + components/ui/tooltip.tsx | 34 + components/ui/use-mobile.tsx | 19 + components/ui/use-toast.ts | 188 + components/user-pool/user-pool-filters.tsx | 89 + components/user-pool/user-pool-header.tsx | 27 + components/user-pool/user-pool-stats.tsx | 56 + components/user-pool/user-pool-table.tsx | 198 + components/user-portrait/tag-management.tsx | 276 + .../user-profile/user-profile-analytics.tsx | 219 + .../user-profile/user-profile-overview.tsx | 319 + .../user-profile/user-profile-segments.tsx | 210 + components/user-profile/user-profile-tags.tsx | 217 + data-ingestion/data-schema.ts | 8 + data-ingestion/data-source.ts | 10 + data-ingestion/data-storage.ts | 4 + data-ingestion/ingestion-service.ts | 6 + hooks/use-debounce.ts | 17 + hooks/use-mobile.tsx | 19 + hooks/use-toast.ts | 194 + hooks/useDeviceStatusPolling.ts | 46 + lib/api-utils.ts | 47 + lib/cache-utils.ts | 84 + lib/db-connector.ts | 305 + lib/documentation/docx-generator.ts | 468 ++ .../enhanced-screenshot-service.ts | 390 + lib/documentation/page-registry.ts | 182 + lib/documentation/screenshot-service.ts | 531 ++ lib/tutorials.ts | 59 + lib/utils.ts | 37 + next.config.mjs | 14 + package.json | 65 + pnpm-lock.yaml | 6326 +++++++++++++++++ postcss.config.mjs | 8 + public/placeholder-logo.png | Bin 0 -> 568 bytes public/placeholder-logo.svg | 1 + public/placeholder-user.jpg | Bin 0 -> 1635 bytes public/placeholder.jpg | Bin 0 -> 1064 bytes public/placeholder.svg | 1 + services/data-analysis-service.ts | 292 + services/user-portrait-service.ts | 240 + styles/globals.css | 94 + tailwind.config.js | 121 + tsconfig.json | 27 + 开发文档/开发文档.md | 41 + 开发文档/标签管理系统开发文档.md | 143 + 开发文档/需求文档.md | 141 + 316 files changed, 55785 insertions(+) create mode 100644 .gitignore create mode 100644 api/devices.ts create mode 100644 api/route.ts create mode 100644 api/scenarios.ts create mode 100644 app/ClientLayout.tsx create mode 100644 app/ai-assistant/page.tsx create mode 100644 app/api-interface/loading.tsx create mode 100644 app/api-interface/page.tsx create mode 100644 app/api/acquisition/[planId]/orders/route.ts create mode 100644 app/api/auth.ts create mode 100644 app/api/database-structure/route.ts create mode 100644 app/api/devices/route.ts create mode 100644 app/api/users/route.ts create mode 100644 app/components/AIRewriteModal.tsx create mode 100644 app/components/AuthProvider.tsx create mode 100644 app/components/BindDouyinQRCode.tsx create mode 100644 app/components/BottomNav.tsx create mode 100644 app/components/Charts.tsx create mode 100644 app/components/CircleSync/ContentSelector.tsx create mode 100644 app/components/CircleSync/DeviceSelector.tsx create mode 100644 app/components/CircleSync/TaskSetup.tsx create mode 100644 app/components/DeviceSelector.tsx create mode 100644 app/components/ErrorBoundary.tsx create mode 100644 app/components/Header.tsx create mode 100644 app/components/MobileHeader.tsx create mode 100644 app/components/MobileSidebar.tsx create mode 100644 app/components/Sidebar.tsx create mode 100644 app/components/SpeechToTextProcessor.tsx create mode 100644 app/components/TrafficTeamSettings.tsx create mode 100644 app/components/charts.tsx create mode 100644 app/components/device-grid.tsx create mode 100644 app/components/device-selection-dialog.tsx create mode 100644 app/components/poster-selector.tsx create mode 100644 app/components/ui/accordion.tsx create mode 100644 app/components/ui/avatar.tsx create mode 100644 app/components/ui/badge.tsx create mode 100644 app/components/ui/button.tsx create mode 100644 app/components/ui/calendar.tsx create mode 100644 app/components/ui/card.tsx create mode 100644 app/components/ui/checkbox.tsx create mode 100644 app/components/ui/collapsible.tsx create mode 100644 app/components/ui/dialog.tsx create mode 100644 app/components/ui/dropdown-menu.tsx create mode 100644 app/components/ui/input.tsx create mode 100644 app/components/ui/label.tsx create mode 100644 app/components/ui/pagination.tsx create mode 100644 app/components/ui/popover.tsx create mode 100644 app/components/ui/preview-dialog.tsx create mode 100644 app/components/ui/progress.tsx create mode 100644 app/components/ui/radio-group.tsx create mode 100644 app/components/ui/scroll-area.tsx create mode 100644 app/components/ui/select.tsx create mode 100644 app/components/ui/switch.tsx create mode 100644 app/components/ui/table.tsx create mode 100644 app/components/ui/tabs.tsx create mode 100644 app/components/ui/textarea.tsx create mode 100644 app/components/ui/toast.tsx create mode 100644 app/components/ui/tooltip.tsx create mode 100644 app/components/ui/use-toast.ts create mode 100644 app/content/[id]/materials/loading.tsx create mode 100644 app/content/[id]/materials/new/page.tsx create mode 100644 app/content/[id]/materials/page.tsx create mode 100644 app/content/[id]/page.tsx create mode 100644 app/content/loading.tsx create mode 100644 app/content/new/device-selector.tsx create mode 100644 app/content/new/page.tsx create mode 100644 app/content/page.tsx create mode 100644 app/conversion/page.tsx create mode 100644 app/data-dictionary/page.tsx create mode 100644 app/data-integration/page.tsx create mode 100644 app/data-platform/loading.tsx create mode 100644 app/data-platform/page.tsx create mode 100644 app/database-structure/page.tsx create mode 100644 app/devices/[id]/page.tsx create mode 100644 app/devices/loading.tsx create mode 100644 app/devices/page.tsx create mode 100644 app/documentation/layout.tsx create mode 100644 app/documentation/page.tsx create mode 100644 app/globals.css create mode 100644 app/group-sync/page.tsx create mode 100644 app/hooks/useDeviceStatusPolling.ts create mode 100644 app/layout.tsx create mode 100644 app/lib/utils.ts create mode 100644 app/login/page.tsx create mode 100644 app/orders/submit/[planId]/page.tsx create mode 100644 app/page.tsx create mode 100644 app/plans/new/loading.tsx create mode 100644 app/plans/new/page.tsx create mode 100644 app/plans/new/steps/BasicSettings.tsx create mode 100644 app/plans/new/steps/FriendRequestSettings.tsx create mode 100644 app/plans/new/steps/MessageSettings.tsx create mode 100644 app/plans/new/steps/TagSettings.tsx create mode 100644 app/scenarios/[channel]/acquired/page.tsx create mode 100644 app/scenarios/[channel]/added/page.tsx create mode 100644 app/scenarios/[channel]/devices/page.tsx create mode 100644 app/scenarios/[channel]/edit/[id]/page.tsx create mode 100644 app/scenarios/[channel]/page.tsx create mode 100644 app/scenarios/[channel]/traffic/page.tsx create mode 100644 app/scenarios/api/loading.tsx create mode 100644 app/scenarios/api/page.tsx create mode 100644 app/scenarios/loading.tsx create mode 100644 app/scenarios/new/steps/BasicSettings.tsx create mode 100644 app/scenarios/new/steps/FriendRequestSettings.tsx create mode 100644 app/scenarios/new/steps/MessageSettings.tsx create mode 100644 app/scenarios/new/steps/PosterEditor.tsx create mode 100644 app/scenarios/new/steps/TagSettings.tsx create mode 100644 app/scenarios/new/steps/TrafficChannelSettings create mode 100644 app/scenarios/page.tsx create mode 100644 app/scenarios/phone/edit/[id]/page.tsx create mode 100644 app/scenarios/phone/page.tsx create mode 100644 app/settings/page.tsx create mode 100644 app/tag-management/loading.tsx create mode 100644 app/tag-management/page.tsx create mode 100644 app/tag-rules/loading.tsx create mode 100644 app/tag-rules/page.tsx create mode 100644 app/tag-tasks/loading.tsx create mode 100644 app/tag-tasks/page.tsx create mode 100644 app/traffic-keywords/loading.tsx create mode 100644 app/traffic-pool/components/date-range-picker.tsx create mode 100644 app/traffic-pool/components/pool-usage-chart.tsx create mode 100644 app/traffic-pool/loading.tsx create mode 100644 app/traffic-pool/page.tsx create mode 100644 app/user-pool/page.tsx create mode 100644 app/user-portrait/[id]/page.tsx create mode 100644 app/user-portrait/loading.tsx create mode 100644 app/user-portrait/page.tsx create mode 100644 app/user-portrait/tags/page.tsx create mode 100644 app/user-profile/loading.tsx create mode 100644 app/user-profile/page.tsx create mode 100644 app/user-value/loading.tsx create mode 100644 app/user-value/page.tsx create mode 100644 app/wechat-accounts/[id]/page.tsx create mode 100644 app/wechat-accounts/loading.tsx create mode 100644 app/wechat-accounts/page.tsx create mode 100644 app/workspace/auto-group/components/StepByStepPlanForm.tsx create mode 100644 app/workspace/auto-group/components/auto-group-service.ts create mode 100644 app/workspace/auto-group/components/columns.tsx create mode 100644 app/workspace/auto-group/components/data-table.tsx create mode 100644 app/workspace/auto-group/components/device-selector.tsx create mode 100644 app/workspace/auto-group/components/group-assistant.tsx create mode 100644 app/workspace/auto-group/components/group-creation-progress.tsx create mode 100644 app/workspace/auto-group/components/group-preview.tsx create mode 100644 app/workspace/auto-group/components/new-plan-form.tsx create mode 100644 app/workspace/auto-group/components/wechat-account-selector.tsx create mode 100644 app/workspace/auto-group/page.tsx create mode 100644 app/workspace/moments-sync/[id]/edit/page.tsx create mode 100644 app/workspace/moments-sync/[id]/edit/step-indicator.tsx create mode 100644 app/workspace/moments-sync/[id]/edit/steps/basic-settings.tsx create mode 100644 app/workspace/moments-sync/[id]/edit/steps/content-library-selection.tsx create mode 100644 app/workspace/moments-sync/[id]/edit/steps/device-selection.tsx create mode 100644 app/workspace/moments-sync/[id]/page.tsx create mode 100644 app/workspace/moments-sync/[id]/view/page.tsx create mode 100644 app/workspace/moments-sync/components/basic-settings.tsx create mode 100644 app/workspace/moments-sync/components/content-viewer.tsx create mode 100644 app/workspace/moments-sync/components/device-selection-dialog.tsx create mode 100644 app/workspace/moments-sync/components/step-indicator.tsx create mode 100644 app/workspace/moments-sync/components/tag-editor.tsx create mode 100644 app/workspace/moments-sync/loading.tsx create mode 100644 app/workspace/moments-sync/new/page.tsx create mode 100644 app/workspace/moments-sync/new/steps/BasicSettings.tsx create mode 100644 app/workspace/moments-sync/new/steps/ContentSelector.tsx create mode 100644 app/workspace/moments-sync/new/steps/DeviceSelector.tsx create mode 100644 app/workspace/moments-sync/page.tsx create mode 100644 app/workspace/pricing/edit/[id]/page.tsx create mode 100644 app/workspace/pricing/new/page.tsx create mode 100644 app/workspace/pricing/page.tsx create mode 100644 components.json create mode 100644 components/AIAssistant.tsx create mode 100644 components/BindDouyinQRCode.tsx create mode 100644 components/Charts.tsx create mode 100644 components/TrafficTeamSettings.tsx create mode 100644 components/VideoTutorialButton.tsx create mode 100644 components/WechatFriendSelector.tsx create mode 100644 components/WechatGroupSelector.tsx create mode 100644 components/acquisition/PlanSettingsDialog.tsx create mode 100644 components/charts.tsx create mode 100644 components/dashboard/dashboard-header.tsx create mode 100644 components/dashboard/dashboard-overview.tsx create mode 100644 components/dashboard/recent-activities.tsx create mode 100644 components/dashboard/traffic-source-analysis.tsx create mode 100644 components/dashboard/user-assets-summary.tsx create mode 100644 components/dashboard/user-behavior-analysis.tsx create mode 100644 components/dashboard/user-growth-chart.tsx create mode 100644 components/dashboard/user-lifecycle-analysis.tsx create mode 100644 components/dashboard/user-portrait-overview.tsx create mode 100644 components/dashboard/user-tags-distribution.tsx create mode 100644 components/dashboard/user-value-distribution.tsx create mode 100644 components/data-analysis/rfm-analysis.tsx create mode 100644 components/data-analysis/user-selector.tsx create mode 100644 components/data-integration/ai-analysis-tools.tsx create mode 100644 components/data-integration/api-documentation.tsx create mode 100644 components/data-integration/data-collection-settings.tsx create mode 100644 components/data-integration/data-correlation-analysis.tsx create mode 100644 components/data-integration/data-dashboard.tsx create mode 100644 components/data-integration/data-field-mapping.tsx create mode 100644 components/data-integration/data-mapping-config.tsx create mode 100644 components/data-integration/data-preview.tsx create mode 100644 components/data-integration/data-quality-monitor.tsx create mode 100644 components/data-integration/data-source-list.tsx create mode 100644 components/data-integration/database-structure-viewer.tsx create mode 100644 components/data-integration/integration-history.tsx create mode 100644 components/device-grid.tsx create mode 100644 components/documentation/document-generator.tsx create mode 100644 components/documentation/export-controls.tsx create mode 100644 components/documentation/screenshot-capture.tsx create mode 100644 components/icons/apple-icon.tsx create mode 100644 components/icons/wechat-icon.tsx create mode 100644 components/poster-selector.tsx create mode 100644 components/tag-management/tag-category-chart.tsx create mode 100644 components/tag-management/tag-relationship-graph.tsx create mode 100644 components/tag-management/tag-usage-stats.tsx create mode 100644 components/tag-rules/rule-editor.tsx create mode 100644 components/tag-rules/rule-execution-history.tsx create mode 100644 components/tag-tasks/task-creation.tsx create mode 100644 components/tag-tasks/task-execution.tsx create mode 100644 components/tag-tasks/task-list.tsx create mode 100644 components/tag-tasks/task-results.tsx create mode 100644 components/theme-provider.tsx create mode 100644 components/traffic-pool/pool-analytics.tsx create mode 100644 components/traffic-pool/traffic-pool-list.tsx create mode 100644 components/traffic-pool/user-tag-mapping.tsx create mode 100644 components/ui/accordion.tsx create mode 100644 components/ui/alert-dialog.tsx create mode 100644 components/ui/alert.tsx create mode 100644 components/ui/aspect-ratio.tsx create mode 100644 components/ui/avatar.tsx create mode 100644 components/ui/badge.tsx create mode 100644 components/ui/breadcrumb.tsx create mode 100644 components/ui/button.tsx create mode 100644 components/ui/calendar.tsx create mode 100644 components/ui/card.tsx create mode 100644 components/ui/carousel.tsx create mode 100644 components/ui/chart.tsx create mode 100644 components/ui/checkbox.tsx create mode 100644 components/ui/collapsible.tsx create mode 100644 components/ui/command.tsx create mode 100644 components/ui/context-menu.tsx create mode 100644 components/ui/date-range-picker.tsx create mode 100644 components/ui/dialog.tsx create mode 100644 components/ui/drawer.tsx create mode 100644 components/ui/dropdown-menu.tsx create mode 100644 components/ui/form.tsx create mode 100644 components/ui/hover-card.tsx create mode 100644 components/ui/input-otp.tsx create mode 100644 components/ui/input.tsx create mode 100644 components/ui/label.tsx create mode 100644 components/ui/menubar.tsx create mode 100644 components/ui/navigation-menu.tsx create mode 100644 components/ui/pagination.tsx create mode 100644 components/ui/popover.tsx create mode 100644 components/ui/preview-dialog.tsx create mode 100644 components/ui/progress.tsx create mode 100644 components/ui/radio-group.tsx create mode 100644 components/ui/resizable.tsx create mode 100644 components/ui/scroll-area.tsx create mode 100644 components/ui/select.tsx create mode 100644 components/ui/separator.tsx create mode 100644 components/ui/sheet.tsx create mode 100644 components/ui/sidebar.tsx create mode 100644 components/ui/skeleton.tsx create mode 100644 components/ui/slider.tsx create mode 100644 components/ui/sonner.tsx create mode 100644 components/ui/switch.tsx create mode 100644 components/ui/table.tsx create mode 100644 components/ui/tabs.tsx create mode 100644 components/ui/textarea.tsx create mode 100644 components/ui/toast.ts create mode 100644 components/ui/toaster.tsx create mode 100644 components/ui/toggle-group.tsx create mode 100644 components/ui/toggle.tsx create mode 100644 components/ui/tooltip.tsx create mode 100644 components/ui/use-mobile.tsx create mode 100644 components/ui/use-toast.ts create mode 100644 components/user-pool/user-pool-filters.tsx create mode 100644 components/user-pool/user-pool-header.tsx create mode 100644 components/user-pool/user-pool-stats.tsx create mode 100644 components/user-pool/user-pool-table.tsx create mode 100644 components/user-portrait/tag-management.tsx create mode 100644 components/user-profile/user-profile-analytics.tsx create mode 100644 components/user-profile/user-profile-overview.tsx create mode 100644 components/user-profile/user-profile-segments.tsx create mode 100644 components/user-profile/user-profile-tags.tsx create mode 100644 data-ingestion/data-schema.ts create mode 100644 data-ingestion/data-source.ts create mode 100644 data-ingestion/data-storage.ts create mode 100644 data-ingestion/ingestion-service.ts create mode 100644 hooks/use-debounce.ts create mode 100644 hooks/use-mobile.tsx create mode 100644 hooks/use-toast.ts create mode 100644 hooks/useDeviceStatusPolling.ts create mode 100644 lib/api-utils.ts create mode 100644 lib/cache-utils.ts create mode 100644 lib/db-connector.ts create mode 100644 lib/documentation/docx-generator.ts create mode 100644 lib/documentation/enhanced-screenshot-service.ts create mode 100644 lib/documentation/page-registry.ts create mode 100644 lib/documentation/screenshot-service.ts create mode 100644 lib/tutorials.ts create mode 100644 lib/utils.ts create mode 100644 next.config.mjs create mode 100644 package.json create mode 100644 pnpm-lock.yaml create mode 100644 postcss.config.mjs create mode 100644 public/placeholder-logo.png create mode 100644 public/placeholder-logo.svg create mode 100644 public/placeholder-user.jpg create mode 100644 public/placeholder.jpg create mode 100644 public/placeholder.svg create mode 100644 services/data-analysis-service.ts create mode 100644 services/user-portrait-service.ts create mode 100644 styles/globals.css create mode 100644 tailwind.config.js create mode 100644 tsconfig.json create mode 100644 开发文档/开发文档.md create mode 100644 开发文档/标签管理系统开发文档.md create mode 100644 开发文档/需求文档.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f650315 --- /dev/null +++ b/.gitignore @@ -0,0 +1,27 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules + +# next.js +/.next/ +/out/ + +# production +/build + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# env files +.env* + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts \ No newline at end of file diff --git a/api/devices.ts b/api/devices.ts new file mode 100644 index 0000000..347269f --- /dev/null +++ b/api/devices.ts @@ -0,0 +1,130 @@ +import type { + ApiResponse, + Device, + DeviceStats, + DeviceTaskRecord, + PaginatedResponse, + QueryDeviceParams, + CreateDeviceParams, + UpdateDeviceParams, + DeviceStatus, // Added DeviceStatus import +} from "@/types/device" + +const API_BASE = "/api/devices" + +// 设备管理API +export const deviceApi = { + // 创建设备 + async create(params: CreateDeviceParams): Promise> { + const response = await fetch(`${API_BASE}`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(params), + }) + return response.json() + }, + + // 更新设备 + async update(params: UpdateDeviceParams): Promise> { + const response = await fetch(`${API_BASE}/${params.id}`, { + method: "PUT", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(params), + }) + return response.json() + }, + + // 获取设备详情 + async getById(id: string): Promise> { + const response = await fetch(`${API_BASE}/${id}`) + return response.json() + }, + + // 查询设备列表 + async query(params: QueryDeviceParams): Promise>> { + const queryString = new URLSearchParams({ + ...params, + tags: params.tags ? JSON.stringify(params.tags) : "", + dateRange: params.dateRange ? JSON.stringify(params.dateRange) : "", + }).toString() + + const response = await fetch(`${API_BASE}?${queryString}`) + return response.json() + }, + + // 删除设备 + async delete(id: string): Promise> { + const response = await fetch(`${API_BASE}/${id}`, { + method: "DELETE", + }) + return response.json() + }, + + // 重启设备 + async restart(id: string): Promise> { + const response = await fetch(`${API_BASE}/${id}/restart`, { + method: "POST", + }) + return response.json() + }, + + // 解绑设备 + async unbind(id: string): Promise> { + const response = await fetch(`${API_BASE}/${id}/unbind`, { + method: "POST", + }) + return response.json() + }, + + // 获取设备统计数据 + async getStats(id: string): Promise> { + const response = await fetch(`${API_BASE}/${id}/stats`) + return response.json() + }, + + // 获取设备任务记录 + async getTaskRecords(id: string, page = 1, pageSize = 20): Promise>> { + const response = await fetch(`${API_BASE}/${id}/tasks?page=${page}&pageSize=${pageSize}`) + return response.json() + }, + + // 批量更新设备标签 + async updateTags(ids: string[], tags: string[]): Promise> { + const response = await fetch(`${API_BASE}/tags`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ deviceIds: ids, tags }), + }) + return response.json() + }, + + // 批量导出设备数据 + async exportDevices(ids: string[]): Promise { + const response = await fetch(`${API_BASE}/export`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ deviceIds: ids }), + }) + return response.blob() + }, + + // 检查设备在线状态 + async checkStatus(ids: string[]): Promise>> { + const response = await fetch(`${API_BASE}/status`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ deviceIds: ids }), + }) + return response.json() + }, +} diff --git a/api/route.ts b/api/route.ts new file mode 100644 index 0000000..7b5e7c0 --- /dev/null +++ b/api/route.ts @@ -0,0 +1,73 @@ +import { NextResponse } from "next/server" +import type { CreateScenarioParams, QueryScenarioParams, ScenarioBase, ApiResponse } from "@/types/scenario" + +// 获客场景路由处理 +export async function POST(request: Request) { + try { + const body: CreateScenarioParams = await request.json() + + // TODO: 实现创建场景的具体逻辑 + const scenario: ScenarioBase = { + id: "generated-id", + ...body, + status: "draft", + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + creator: "current-user-id", + } + + const response: ApiResponse = { + code: 0, + message: "创建成功", + data: scenario, + } + + return NextResponse.json(response) + } catch (error) { + return NextResponse.json( + { + code: 500, + message: "创建失败", + data: null, + }, + { status: 500 }, + ) + } +} + +export async function GET(request: Request) { + try { + const { searchParams } = new URL(request.url) + const params: QueryScenarioParams = { + type: searchParams.get("type") as any, + status: searchParams.get("status") as any, + keyword: searchParams.get("keyword") || undefined, + dateRange: searchParams.get("dateRange") ? JSON.parse(searchParams.get("dateRange")!) : undefined, + page: Number(searchParams.get("page")) || 1, + pageSize: Number(searchParams.get("pageSize")) || 20, + } + + // TODO: 实现查询场景列表的具体逻辑 + + return NextResponse.json({ + code: 0, + message: "查询成功", + data: { + items: [], + total: 0, + page: params.page, + pageSize: params.pageSize, + totalPages: 0, + }, + }) + } catch (error) { + return NextResponse.json( + { + code: 500, + message: "查询失败", + data: null, + }, + { status: 500 }, + ) + } +} diff --git a/api/scenarios.ts b/api/scenarios.ts new file mode 100644 index 0000000..37786f6 --- /dev/null +++ b/api/scenarios.ts @@ -0,0 +1,111 @@ +import type { + ApiResponse, + CreateScenarioParams, + UpdateScenarioParams, + QueryScenarioParams, + ScenarioBase, + ScenarioStats, + AcquisitionRecord, + PaginatedResponse, +} from "@/types/scenario" + +const API_BASE = "/api/scenarios" + +// 获客场景API +export const scenarioApi = { + // 创建场景 + async create(params: CreateScenarioParams): Promise> { + const response = await fetch(`${API_BASE}`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(params), + }) + return response.json() + }, + + // 更新场景 + async update(params: UpdateScenarioParams): Promise> { + const response = await fetch(`${API_BASE}/${params.id}`, { + method: "PUT", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(params), + }) + return response.json() + }, + + // 获取场景详情 + async getById(id: string): Promise> { + const response = await fetch(`${API_BASE}/${id}`) + return response.json() + }, + + // 查询场景列表 + async query(params: QueryScenarioParams): Promise>> { + const queryString = new URLSearchParams({ + ...params, + dateRange: params.dateRange ? JSON.stringify(params.dateRange) : "", + }).toString() + + const response = await fetch(`${API_BASE}?${queryString}`) + return response.json() + }, + + // 删除场景 + async delete(id: string): Promise> { + const response = await fetch(`${API_BASE}/${id}`, { + method: "DELETE", + }) + return response.json() + }, + + // 启动场景 + async start(id: string): Promise> { + const response = await fetch(`${API_BASE}/${id}/start`, { + method: "POST", + }) + return response.json() + }, + + // 暂停场景 + async pause(id: string): Promise> { + const response = await fetch(`${API_BASE}/${id}/pause`, { + method: "POST", + }) + return response.json() + }, + + // 获取场景统计数据 + async getStats(id: string): Promise> { + const response = await fetch(`${API_BASE}/${id}/stats`) + return response.json() + }, + + // 获取获客记录 + async getRecords(id: string, page = 1, pageSize = 20): Promise>> { + const response = await fetch(`${API_BASE}/${id}/records?page=${page}&pageSize=${pageSize}`) + return response.json() + }, + + // 导出获客记录 + async exportRecords(id: string, dateRange?: { start: string; end: string }): Promise { + const queryString = dateRange ? `?start=${dateRange.start}&end=${dateRange.end}` : "" + const response = await fetch(`${API_BASE}/${id}/records/export${queryString}`) + return response.blob() + }, + + // 批量更新标签 + async updateTags(id: string, customerIds: string[], tags: string[]): Promise> { + const response = await fetch(`${API_BASE}/${id}/tags`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ customerIds, tags }), + }) + return response.json() + }, +} diff --git a/app/ClientLayout.tsx b/app/ClientLayout.tsx new file mode 100644 index 0000000..c4011a8 --- /dev/null +++ b/app/ClientLayout.tsx @@ -0,0 +1,71 @@ +"use client" + +import type React from "react" +import "./globals.css" +import { Inter } from "next/font/google" +import { useState, useEffect } from "react" +import Sidebar from "./components/Sidebar" +import MobileHeader from "./components/MobileHeader" +import MobileSidebar from "./components/MobileSidebar" +import BottomNav from "./components/BottomNav" + +const inter = Inter({ subsets: ["latin"] }) + +export default function ClientLayout({ + children, +}: { + children: React.ReactNode +}) { + const [isMobile, setIsMobile] = useState(false) + const [sidebarOpen, setSidebarOpen] = useState(false) + + useEffect(() => { + const checkMobile = () => { + setIsMobile(window.innerWidth < 768) + } + + checkMobile() + window.addEventListener("resize", checkMobile) + + return () => window.removeEventListener("resize", checkMobile) + }, []) + + return ( + + + 用户数据资产中台 + + + + + {/* 背景装饰 */} +
+
+
+
+
+
+ +
+ {/* 桌面端侧边栏 */} + {!isMobile && } + + {/* 移动端侧边栏 */} + {isMobile && setSidebarOpen(false)} />} + + {/* 主内容区域 */} +
+ {/* 移动端头部 */} + {isMobile && setSidebarOpen(true)} />} + + {/* 内容区域 */} +
{children}
+
+
+ + {/* 移动端底部导航 */} + {isMobile && } + + + ) +} diff --git a/app/ai-assistant/page.tsx b/app/ai-assistant/page.tsx new file mode 100644 index 0000000..f1f6be6 --- /dev/null +++ b/app/ai-assistant/page.tsx @@ -0,0 +1,786 @@ +"use client" + +import { useState } from "react" +import { Card, CardContent, CardDescription, CardHeader, CardTitle, CardFooter } from "@/components/ui/card" +import { Button } from "@/components/ui/button" +import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" +import { Textarea } from "@/components/ui/textarea" +import { Input } from "@/components/ui/input" +import { Label } from "@/components/ui/label" +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" +import { Switch } from "@/components/ui/switch" +import { Badge } from "@/components/ui/badge" +import { Separator } from "@/components/ui/separator" +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from "@/components/ui/dialog" +import { Sparkles, BarChart, TrendingUp, Users, Mail, Clock, Download, ChevronRight } from "lucide-react" + +export default function AIAssistantPage() { + const [activeTab, setActiveTab] = useState("data-analysis") + const [selectedUserGroup, setSelectedUserGroup] = useState("") + const [isUserGroupDialogOpen, setIsUserGroupDialogOpen] = useState(false) + const [emailAddress, setEmailAddress] = useState("") + const [scheduleReport, setScheduleReport] = useState(false) + + // 分析流程步骤 + const [analysisStep, setAnalysisStep] = useState(1) + const [analysisType, setAnalysisType] = useState("") + + // 营销策略步骤 + const [strategyStep, setStrategyStep] = useState(1) + const [strategyType, setStrategyType] = useState("") + + return ( +
+
+
+

AI 智能助手

+

利用AI技术分析数据并提供营销策略

+
+
+ + + + 数据分析 + 营销策略 + + + + + + AI 数据分析 + 使用AI分析用户数据并生成洞察报告 + + + {/* 第1步:选择用户分群 */} +
+
+

+
+ 1 +
+ 选择用户分群 +

+ {analysisStep > 1 ? ( + + ) : ( + + )} +
+ + {selectedUserGroup && ( +
+
+
+ + 已选择用户分群: + {selectedUserGroup} +
+ {analysisStep === 1 && ( + + )} +
+
+ )} +
+ + + + {/* 第2步:选择分析类型 */} +
2 ? "opacity-60" : "opacity-40") : ""}`} + > +
+

+
+ 2 +
+ 选择分析类型 +

+ {analysisStep > 2 && ( + + )} +
+ + {analysisStep >= 2 && ( +
+ setAnalysisType("behavior")} + > + + 用户行为分析 + + + 分析用户的行为模式、偏好和习惯 + + + {analysisType === "behavior" && 已选择} + + + setAnalysisType("value")} + > + + 用户估值分析 + + 分析用户的价值分布和潜在价值 + + {analysisType === "value" && 已选择} + + + setAnalysisType("churn")} + > + + 用户流失预警 + + + 预测可能流失的用户并提供挽留建议 + + + {analysisType === "churn" && 已选择} + + +
+ )} + + {analysisStep === 2 && analysisType && ( +
+ +
+ )} +
+ + + + {/* 第3步:分析参数设置 */} +
3 ? "opacity-60" : "opacity-40") : ""}`} + > +
+

+
+ 3 +
+ 分析参数设置 +

+ {analysisStep > 3 && ( + + )} +
+ + {analysisStep >= 3 && ( +
+
+ + +
+
+ + +
+
+ )} + + {analysisStep === 3 && ( +
+ +
+ )} +
+ + + + {/* 第4步:报告设置 */} +
+
+

+
+ 4 +
+ 报告设置 +

+
+ + {analysisStep >= 4 && ( +
+
+ + setEmailAddress(e.target.value)} + /> +
+
+ + +
+ {scheduleReport && ( +
+
+ + +
+
+ + +
+
+ )} +
+ )} +
+
+ + + + +
+ + + + 分析结果预览 + AI生成的数据分析结果 + + + {selectedUserGroup && analysisStep === 4 ? ( +
+ +

分析结果将在这里显示

+

点击"开始分析"按钮生成分析报告

+
+ + +
+
+ ) : ( +
+ +

请完成所有分析步骤

+ +
+ )} +
+
+
+ + + + + AI 营销策略 + 使用AI生成针对性的营销策略和建议 + + + {/* 第1步:选择目标用户分群 */} +
+
+

+
+ 1 +
+ 选择目标用户分群 +

+ {strategyStep > 1 ? ( + + ) : ( + + )} +
+ + {selectedUserGroup && ( +
+
+
+ + 已选择用户分群: + {selectedUserGroup} +
+ {strategyStep === 1 && ( + + )} +
+
+ )} +
+ + + + {/* 第2步:选择策略类型 */} +
2 ? "opacity-60" : "opacity-40") : ""}`} + > +
+

+
+ 2 +
+ 选择策略类型 +

+ {strategyStep > 2 && ( + + )} +
+ + {strategyStep >= 2 && ( +
+ setStrategyType("sales")} + > + + 销售预测 + + + 预测未来销售趋势并提供增长建议 + + + {strategyType === "sales" && 已选择} + + + setStrategyType("reach")} + > + + 用户触达策略 + + + 生成针对性的用户触达和转化策略 + + + {strategyType === "reach" && 已选择} + + + setStrategyType("content")} + > + + 内容营销策略 + + + 生成针对目标用户的内容营销策略 + + + {strategyType === "content" && 已选择} + + +
+ )} + + {strategyStep === 2 && strategyType && ( +
+ +
+ )} +
+ + + + {/* 第3步:策略参数设置 */} +
+
+

+
+ 3 +
+ 策略参数设置 +

+
+ + {strategyStep >= 3 && ( + <> +
+
+ + +
+
+ + +
+
+
+ +