|
|
@@ -19,6 +19,8 @@ Completed
|
|
|
3. **组件支持产业切换** - 当用户在种业和果蔬之间切换时,组件应自动更新显示对应产业的数据
|
|
|
4. **验证数据完整性** - 确保种业和果蔬的所有定位点、关键指标、供应链网络和弹出框数据都能正确显示
|
|
|
5. **点击popup时弹出完整SupplyChainModal** - 当用户点击地图上的定位点时,应显示完整的SupplyChainModal弹出层,包含标题、图片和自定义内容区域
|
|
|
+6. **SupplyChainModal图片展示布局优化** - 弹出层应根据图片数量动态选择展示模式:单图时图片居中显示,多图时支持横向滚动
|
|
|
+7. **滚动条交互功能** - 多图模式下,滚动条应支持点击拖动控制图片滚动,滚动条位置与图片滚动位置同步
|
|
|
|
|
|
## Tasks / Subtasks
|
|
|
- [x] 修改SupplyChainMap组件使用动态数据 (AC: #1, #3, #4)
|
|
|
@@ -57,6 +59,19 @@ Completed
|
|
|
- [ ] 实现弹出层关闭功能
|
|
|
- [ ] 验证弹出层主题色正确应用
|
|
|
- [ ] 测试ESC键和遮罩层点击关闭功能
|
|
|
+ - [ ] 优化SupplyChainModal图片展示布局
|
|
|
+ - [ ] 支持单图展示模式(图片居中显示)
|
|
|
+ - [ ] 支持多图展示模式(图片横向滚动)
|
|
|
+ - [ ] 根据图片数量动态选择展示模式
|
|
|
+ - [ ] 实现横向滚动功能
|
|
|
+ - [ ] 实现滚动条交互功能
|
|
|
+ - [ ] 滚动条可点击拖动控制图片滚动
|
|
|
+ - [ ] 滚动条位置与图片滚动位置同步
|
|
|
+ - [ ] 滚动条样式与主题色协调
|
|
|
+ - [ ] 滚动条悬停效果
|
|
|
+ - [ ] 验证单图模式图片居中显示
|
|
|
+ - [ ] 验证多图模式横向滚动功能
|
|
|
+ - [ ] 验证滚动条交互功能正常
|
|
|
- [x] 验证种业-果蔬组合路由功能 (AC: #3, #4)
|
|
|
- [x] 测试路由`/supply-chain/seed-fruit`正确加载种业-果蔬数据
|
|
|
- [x] 验证组合内产业切换功能(种业↔果蔬)
|
|
|
@@ -222,6 +237,149 @@ function getIndustryVariant(industry: string, industries: string[]): 'first' | '
|
|
|
- **种业产业**: 主色 #5DEF8B
|
|
|
- **果蔬产业**: 主色 #FFF586
|
|
|
|
|
|
+#### SupplyChainModal图片展示布局优化设计
|
|
|
+
|
|
|
+**展示模式策略:**
|
|
|
+- **单图模式**: 当只有一张图片时,图片在容器中居中显示
|
|
|
+- **多图模式**: 当有多张图片时,图片在横向滚动容器中排列,支持左右滚动
|
|
|
+
|
|
|
+**实现方案:**
|
|
|
+```typescript
|
|
|
+// 图片展示模式类型
|
|
|
+type ImageDisplayMode = 'single' | 'multiple';
|
|
|
+
|
|
|
+// 根据图片数量确定展示模式
|
|
|
+function getImageDisplayMode(imageUrls: string[]): ImageDisplayMode {
|
|
|
+ return imageUrls.length <= 1 ? 'single' : 'multiple';
|
|
|
+}
|
|
|
+
|
|
|
+// 单图模式布局
|
|
|
+const singleImageLayout = (
|
|
|
+ <div className="flex items-center justify-center">
|
|
|
+ <img src={imageUrls[0]} className="max-w-full max-h-full object-contain" />
|
|
|
+ </div>
|
|
|
+);
|
|
|
+
|
|
|
+// 多图模式布局
|
|
|
+const multipleImageLayout = (
|
|
|
+ <div className="flex overflow-x-auto gap-4">
|
|
|
+ {imageUrls.map((url, index) => (
|
|
|
+ <img key={index} src={url} className="flex-shrink-0 max-h-full object-contain" />
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+);
|
|
|
+```
|
|
|
+
|
|
|
+**CSS样式要求:**
|
|
|
+- 单图模式:图片居中,保持宽高比
|
|
|
+- 多图模式:横向滚动,图片等高等宽,间距统一
|
|
|
+- 滚动条样式:自定义滚动条样式,与主题色协调
|
|
|
+
|
|
|
+#### 滚动条交互功能设计
|
|
|
+
|
|
|
+**滚动条交互实现方案:**
|
|
|
+```typescript
|
|
|
+// 滚动条状态管理
|
|
|
+interface ScrollbarState {
|
|
|
+ isDragging: boolean;
|
|
|
+ scrollPosition: number;
|
|
|
+ scrollbarWidth: number;
|
|
|
+ containerWidth: number;
|
|
|
+}
|
|
|
+
|
|
|
+// 滚动条交互逻辑
|
|
|
+const useScrollbarInteraction = (containerRef: React.RefObject<HTMLDivElement>) => {
|
|
|
+ const [scrollState, setScrollState] = useState<ScrollbarState>({
|
|
|
+ isDragging: false,
|
|
|
+ scrollPosition: 0,
|
|
|
+ scrollbarWidth: 0,
|
|
|
+ containerWidth: 0
|
|
|
+ });
|
|
|
+
|
|
|
+ // 处理滚动条点击
|
|
|
+ const handleScrollbarClick = (event: React.MouseEvent) => {
|
|
|
+ const rect = event.currentTarget.getBoundingClientRect();
|
|
|
+ const clickPosition = event.clientX - rect.left;
|
|
|
+ const scrollPercentage = clickPosition / rect.width;
|
|
|
+
|
|
|
+ if (containerRef.current) {
|
|
|
+ const scrollWidth = containerRef.current.scrollWidth - containerRef.current.clientWidth;
|
|
|
+ containerRef.current.scrollLeft = scrollWidth * scrollPercentage;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // 处理滚动条拖动
|
|
|
+ const handleScrollbarDrag = (event: React.MouseEvent) => {
|
|
|
+ if (!scrollState.isDragging) return;
|
|
|
+
|
|
|
+ const rect = event.currentTarget.getBoundingClientRect();
|
|
|
+ const dragPosition = event.clientX - rect.left;
|
|
|
+ const scrollPercentage = Math.max(0, Math.min(1, dragPosition / rect.width));
|
|
|
+
|
|
|
+ if (containerRef.current) {
|
|
|
+ const scrollWidth = containerRef.current.scrollWidth - containerRef.current.clientWidth;
|
|
|
+ containerRef.current.scrollLeft = scrollWidth * scrollPercentage;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // 同步滚动条位置
|
|
|
+ const syncScrollbarPosition = () => {
|
|
|
+ if (containerRef.current) {
|
|
|
+ const scrollLeft = containerRef.current.scrollLeft;
|
|
|
+ const scrollWidth = containerRef.current.scrollWidth - containerRef.current.clientWidth;
|
|
|
+ const scrollPercentage = scrollWidth > 0 ? scrollLeft / scrollWidth : 0;
|
|
|
+
|
|
|
+ setScrollState(prev => ({
|
|
|
+ ...prev,
|
|
|
+ scrollPosition: scrollPercentage
|
|
|
+ }));
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ return {
|
|
|
+ scrollState,
|
|
|
+ handleScrollbarClick,
|
|
|
+ handleScrollbarDrag,
|
|
|
+ syncScrollbarPosition
|
|
|
+ };
|
|
|
+};
|
|
|
+```
|
|
|
+
|
|
|
+**滚动条样式设计:**
|
|
|
+```css
|
|
|
+/* 滚动条容器 */
|
|
|
+.scrollbar-container {
|
|
|
+ position: absolute;
|
|
|
+ bottom: 20px;
|
|
|
+ left: 50%;
|
|
|
+ transform: translateX(-50%);
|
|
|
+ width: 60%;
|
|
|
+ height: 8px;
|
|
|
+ background: rgba(255, 255, 255, 0.1);
|
|
|
+ border-radius: 4px;
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+
|
|
|
+/* 滚动条滑块 */
|
|
|
+.scrollbar-thumb {
|
|
|
+ position: absolute;
|
|
|
+ height: 100%;
|
|
|
+ background: ${themeColor};
|
|
|
+ border-radius: 4px;
|
|
|
+ transition: background-color 0.2s ease;
|
|
|
+ cursor: grab;
|
|
|
+}
|
|
|
+
|
|
|
+.scrollbar-thumb:hover {
|
|
|
+ background: ${themeColor};
|
|
|
+ opacity: 0.8;
|
|
|
+}
|
|
|
+
|
|
|
+.scrollbar-thumb:active {
|
|
|
+ cursor: grabbing;
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
### 数据集成策略 [Source: architecture/component-architecture.md#技术栈配置]
|
|
|
|
|
|
#### 1. React Query集成
|
|
|
@@ -339,6 +497,12 @@ const KeyMetrics: React.FC<KeyMetricsProps> = ({ title, subtitle }) => {
|
|
|
- 点击定位点弹出完整SupplyChainModal
|
|
|
- 弹出层主题色正确应用
|
|
|
- ESC键和遮罩层点击关闭功能正常
|
|
|
+- 单图模式图片居中显示正确
|
|
|
+- 多图模式横向滚动功能正常
|
|
|
+- 图片展示模式根据图片数量动态切换
|
|
|
+- 滚动条点击拖动控制图片滚动功能正常
|
|
|
+- 滚动条位置与图片滚动位置同步正确
|
|
|
+- 滚动条样式与主题色协调
|
|
|
|
|
|
### 测试用例
|
|
|
- 验证seed-fruit组合数据正确加载
|
|
|
@@ -352,12 +516,20 @@ const KeyMetrics: React.FC<KeyMetricsProps> = ({ title, subtitle }) => {
|
|
|
- 验证弹出层主题色正确应用
|
|
|
- 测试ESC键关闭弹出层功能
|
|
|
- 测试遮罩层点击关闭弹出层功能
|
|
|
+- 测试单图模式图片居中显示
|
|
|
+- 测试多图模式横向滚动功能
|
|
|
+- 验证图片展示模式动态切换
|
|
|
+- 测试滚动条点击控制图片滚动
|
|
|
+- 测试滚动条拖动控制图片滚动
|
|
|
+- 验证滚动条位置与图片滚动同步
|
|
|
|
|
|
## Change Log
|
|
|
| Date | Version | Description | Author |
|
|
|
|------|---------|-------------|--------|
|
|
|
| 2025-11-16 | 1.0 | 初始故事创建,基于Epic 005需求 | Bob (SM) |
|
|
|
| 2025-11-16 | 1.1 | 添加点击popup时弹出完整SupplyChainModal的任务和验收标准 | Claude |
|
|
|
+| 2025-11-16 | 1.2 | 添加SupplyChainModal图片展示布局优化任务,支持单图居中显示和多图横向滚动 | Claude |
|
|
|
+| 2025-11-16 | 1.3 | 添加滚动条交互功能需求,支持点击拖动控制图片滚动 | Claude |
|
|
|
|
|
|
## Dev Agent Record
|
|
|
|