当前位置: 首页 > news >正文

(阶段三:整合)面向用户 面向商户,场景之:shop

1. 明确边界:cms配置的 PageInstance.sections 数组只用来配置

【默认内容 + 主题颜色(未来开放)】

 

[section_display]props:// 商户定义“这个模块默认展示哪些分类”category_ids_default: ['software', 'education'], sort_tag_default: 'latest' priceRangeBreakpoints: [20, 40, 80] pagination: { pageSize: 12 },CTA: {title: "现在开始",buttonText: "立即购买",description: "xxxxx"position: 6}
}[section_detail]
------ 更新设计:“持久化时扁平,运行时结构化”-------props: {category_ids_default: ['software', 'education'], // 或者nullsort_tag_default: 'latest',price_range_breakpoints: [20, 40, 80],page_size: 12,CTA_title: '立即购买',CTA_buttonText: '现在开始',CTA_description: 'xxxxx',CTA_position: 6
}

渲染前将扁平字段还原成对象:

 

const CTA = {title: props.CTA_title,description: props.CTA_description,buttonText: props.CTA_buttonText,position: props.CTA_position,
}

 

数据型,如category,依然是放在数据库的table里面

2. 细说price range设计

CMS部分

 1. 💡 商户只输入数字数组(比如在 UI 上输入 tag:204080):

type PriceBreakpoints = number[] // e.g. [20, 40, 80]

SectionInstance.props存储

props: {priceRangeBreakpoints: [20, 40, 80]
}

前端渲染部分:根据 priceRangeBreakpoints 转化成标签

2. ✅ 平台自动转成区间列表:

type PriceRangeOption = {label: stringmin?: numbermax?: number
}function generatePriceRanges(breakpoints: number[]): PriceRangeOption[] {const sorted = [...breakpoints].sort((a, b) => a - b)const ranges: PriceRangeOption[] = []if (sorted.length === 0) return []// Less than first
  ranges.push({max: sorted[0],label: `Less than $${sorted[0]}`})for (let i = 0; i < sorted.length - 1; i++) {ranges.push({min: sorted[i],max: sorted[i + 1],label: `$${sorted[i]} - $${sorted[i + 1]}`})}// More than last
  ranges.push({min: sorted[sorted.length - 1],label: `More than $${sorted[sorted.length - 1]}`})return ranges
}

sql查询部分:

标签为:

[{ max: 20, label: "Less than $20" },{ min: 20, max: 40, label: "$20 - $40" },{ min: 40, max: 80, label: "$40 - $80" },{ min: 80, label: "More than $80" }
]

当用户点击某个 price tag,你将这个 { min?, max? } 作为 query param 发给后端:

GET /api/products?price_min=20&price_max=40

后端查询:

function getProducts({ price_min, price_max }) {const conditions = []if (price_min !== undefined) {conditions.push(`price >= ${price_min}`)}if (price_max !== undefined) {conditions.push(`price < ${price_max}`)}const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : ''const sql = `SELECT * FROM products${whereClause}ORDER BY price ASCLIMIT 20 OFFSET 0`return db.query(sql)
}

 3.  display页面整体流程分析

【layout的时候初始化redux】
把sorttagdefault,categorydefault, page=1,
pricerange = null,
注入redux;【涉及用户交互】

【SSR的时候,】

1. 查出sectionInstance.props,比如可以组装成CTA object+pagesize【商家固定】传给client comp

2. 根据pagesize+sortTagdefault+categorydefault(如果是all,就把这个condition忽视),进行products数据库查询。

3. products_count (用于pagination组件赋值)

【client component的时候,】
从redux里面拿出sorttagdefault,categorydefault, page,pricerange 和对应的dispatch方法
用于赋值初始值和onClick


【CSR的时候 】

1. priceRange发生改变,dispatch priceRange,触发react-query:用redux里面的pagesize,sortTag,category,到后台,组装的priceRange condition,进行sql查询。
查完了dispatch products_count

2. pagination发生改变, dispatch page ,触发react-query

3. category发生改变 ( dispatch category ;dispatch page = 1),触发react-query
查完了dispatch products_count

4. sortTag发生变化 ( dispatch sortTag; dispatch page = 1),触发react-query
查完了dispatch products_count

4. 具体修改实操

1. 把shopstack进行router改变:把原先所有路由加入/products下。
【首页】
【layout】的redux里面themeoptions里面拿sceneMap初始化,sceneList。
以及themeName
tenantId+tenantName

获得首页Header:目前暂时直接为null
Client Comp中间层引入themeHook:
1. dymamic import "cool-landing-header" 来setComponent

得到Styled_Header_component。

【page.tsx】目前暂时直接为null
Client Comp中间层引入themeHook:
dynamic import "cool-landing-mainPage"来setComponent


2. /products下的layout里面的查询和redux初始化:

涉及用户auth的redux初始化
把sorttagdefault,categorydefault, page=1,
pricerange = null, 注入redux;

=> 如果商家没有这个scene,那么根本查不到这些数据!!!可以直接return null

Client Comp中间层引入themeHook:
- dynamic import "cool-shop-header"来setComponent
- 往这个component里面注入 redux的用户auth数据!

得到 Styled_Product_Header。

3. /products的【page.tsx】里面

=> SSR里面判断themeOptions里面是否有这个scene,没有就404!

所有sectionInstance.props暂时都写死!

 

http://www.sczhlp.com/news/524.html

相关文章:

  • 现代Web框架的性能基准测试(6084)
  • 服务端推送技术的现代实现(8430)
  • 跨平台Web服务开发的新选择(1992)
  • Astro机器人流畅运动背后的科技原理
  • 实时通信协议的Rust实现(5234)
  • 现代Web框架的性能基准测试(8409)
  • 现代Web服务器性能革命:我的Rust框架探索之旅(1820)
  • 实战项目:文件分块上传系统(4936)
  • HTTP请求处理的高效封装(8307)
  • 实时通信的革命:WebSocket技术的深度探索(1440)
  • Rust生态系统在Web开发中的优势(9219)
  • 高并发处理的Rust实现方案(2866)
  • 从零开始构建高性能实时聊天系统:Hyperlane框架实战指南(5696)
  • 内存使用效率的终极对决:零拷贝技术的实战应用(9040)
  • 推荐6本书《MLIR编译器原理与实践》、《ONNX人工智能技术与开发实践》、《AI芯片开发核心技术详解》、《智能汽车传感器:原理设计应用》、《TVM编译器原理与实践》、《LLVM编译器原理与实践》
  • 实时通信协议的Rust实现(2554)
  • 零依赖Web框架的设计哲学(5850)
  • 微服务架构的轻量级解决方案(8414)
  • WebSocket服务端的高效处理(1857)
  • 利用数据绑定让动画更智能:在Rive中创建动态黄金计算器
  • 服务器配置的精细化控制(5106)
  • HTTP响应处理的灵活设计(3253)
  • 现代Web框架的性能基准测试(6931)
  • 微服务架构的轻量级解决方案(0378)
  • 实战项目:文件分块上传系统(3902)
  • 并发处理能力的巅峰对决:异步编程的艺术(6216)
  • 跨平台Web服务开发的新选择(9898)
  • WebSocket服务端的高效处理(3038)
  • 实战项目:全栈在线群聊系统(6548)
  • Hyperlane性能调优秘籍:从毫秒级响应到百万QPS的优化之路(5845)