Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions src/packages/price/price.taro.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { ComponentDefaults } from '@/utils/typings'
import { useRtl } from '@/packages/configprovider/index.taro'
import { TaroPriceProps, PriceColorEnum } from '@/types'
import { harmony } from '@/utils/taro/platform'
import { shouldRenderPriceAsRaw } from '@/utils/should-render-price-raw'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Web 版 price.tsx 未同步该修复,跨端行为将不一致。

本次只在 price.taro.tsx 引入 shouldRenderPriceAsRawrenderRawContent;从提供的 src/packages/price/price.tsx:108-155 可以看到 web 版仍直接使用 formatThousands(price) / formatDecimal(price) 的格式化路径,并没有 raw 渲染分支。这意味着同样传入异常字符串(如 "10元起到200元")时,小程序/鸿蒙端会原样输出,而 H5 端会被 replace(/[^\d.]/g, '') 清洗后渲染为错误数字(如 10.200),违反 PR 标题「组件传入异常信息直接原样返回」的承诺。

建议在 src/packages/price/price.tsx 中按相同模式加上 isRenderPriceRaw 判定与 raw 渲染分支,保持双端一致。

Also applies to: 176-193

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/packages/price/price.taro.tsx` at line 8, The web Price component
(price.tsx) must mirror the Taro fix: import shouldRenderPriceAsRaw and
renderRawContent and add an isRenderPriceRaw branch so anomalous strings are
returned raw instead of being stripped and formatted. In
src/packages/price/price.tsx locate the render logic around the current
formatThousands/formatDecimal usage (the blocks referenced at ~108-155 and
~176-193) and before applying numeric formatting compute const isRenderPriceRaw
= shouldRenderPriceAsRaw(price); if true, return renderRawContent(price) (or use
the same render path as price.taro.tsx), otherwise proceed with existing
formatThousands/formatDecimal behavior.


const defaultProps = {
...ComponentDefaults,
Expand Down Expand Up @@ -38,9 +39,17 @@ export const Price: FunctionComponent<Partial<TaroPriceProps>> = (props) => {

const rtl = useRtl()

const isRenderPriceRaw = useMemo(
() =>
typeof originalPrice === 'string' &&
shouldRenderPriceAsRaw(originalPrice),
[originalPrice]
)

const price = useMemo(() => {
if (isRenderPriceRaw) return ''
return originalPrice.toString().replace(/[^\d.]/g, '')
}, [originalPrice])
}, [originalPrice, isRenderPriceRaw])

const isCustomPriceColor = useMemo(() => {
const specificPriceColor = Object.values(PriceColorEnum)
Expand Down Expand Up @@ -164,21 +173,23 @@ export const Price: FunctionComponent<Partial<TaroPriceProps>> = (props) => {
)
}

const renderRawContent = () => <>{originalPrice}</>

return (
<>
{harmony() || process.env.TARO_ENV === 'dynamic' ? (
<Text
className={`${classPrefix} ${classPrefix}-${color} ${className}`}
style={style}
>
{renderInner()}
{isRenderPriceRaw ? renderRawContent() : renderInner()}
</Text>
) : (
<View
className={`${classPrefix} ${classPrefix}-${color} ${className}`}
style={style}
>
{renderInner()}
{isRenderPriceRaw ? renderRawContent() : renderInner()}
</View>
)}
</>
Expand Down
26 changes: 26 additions & 0 deletions src/utils/should-render-price-raw.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const CJK = /[\u4E00-\u9FFF]/
const RE_NUM = /\d+(?:\.\d+)?/g

function hasNoExtractablePrice(s: string) {
const t = s.trim()
if (!t) return true
if (!/\d/.test(t)) return true
if (t.replace(/[^\d.]/g, '') === '') return true
return false
}

export function shouldRenderPriceAsRaw(s: string) {
if (hasNoExtractablePrice(s)) {
return true
}
const t = s.trim()
if (!CJK.test(t)) return false
const matches = Array.from(t.matchAll(RE_NUM))
if (matches.length < 2) return false
const a = matches[0]
const b = matches[1]
const i0 = a.index!
const i1 = b.index!
const between = t.slice(i0 + a[0].length, i1)
return CJK.test(between)
}
Comment on lines +12 to +26

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

判定规则较窄,部分常见异常入参不会进入原样渲染分支。

当前规则要求「至少两个数字 + 第一/第二个数字之间存在 CJK」。对于单数字 + CJK 的常见异常文案(如 "100元起""起价100""约100元""暂无报价 100 起"),不会命中 raw 分支,仍会走 originalPrice.toString().replace(/[^\d.]/g, ''),导致只显示一个被剥离上下文的数字,与「异常信息原样返回」的目标不一致。

如果产品意图是「字符串里只要明显不是单一价格就原样渲染」,可考虑改成更宽松的判定,例如:当字符串包含 CJK(或除 \d.、空白、货币符以外的语义字符)时即视为 raw。请确认期望覆盖范围;若有意只覆盖区间型表达,可忽略本条。

此外 CJK = /[\u4E00-\u9FFF]/ 仅覆盖基本 CJK 区段,不包含扩展 A/B、假名、谚文等;如果未来要兼容日韩文文案需要扩展该范围。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/utils/should-render-price-raw.ts` around lines 12 - 26, The current
shouldRenderPriceAsRaw logic (in shouldRenderPriceAsRaw) is too narrow: change
the detection to treat inputs that contain CJK or any semantic non-numeric
characters (anything other than digits, dot, whitespace and allowed currency
symbols) as raw so single-number phrases like "100元起", "约100元" or "起价100" return
true; implement this by replacing the "at least two numbers + CJK between" check
with a regex or predicate that returns true if t contains a CJK character
(expand CJK from CJK = /[\u4E00-\u9FFF]/ to a wider Unicode-aware class or use
Unicode properties like \p{Script=Han} plus Hiragana/Katakana/Hangul as needed)
or contains characters not matching /^[\d.\s¥$€£¢¥元-]*$/; keep
hasNoExtractablePrice behavior unchanged and ensure callers that strip numbers
(originalPrice.toString().replace(...)) are avoided when shouldRenderPriceAsRaw
returns true.

Loading