Some checks failed
Build docker and publish / linux (1.24.5) (push) Failing after 50s
更新了前端构建产物包括JavaScript、CSS和HTML文件,主要涉及以下变更: 1. 新增了多个组件和工具函数,包括异常页面组件、iframe组件等 2. 更新了活动管理、产品管理、优惠券管理等业务模块 3. 优化了构建配置和依赖管理 4. 修复了一些样式和功能问题 5. 更新了测试相关文件 同时更新了部分后端服务接口和测试用例。这些变更主要是为了支持新功能和改进现有功能的用户体验。
5.4 KiB
5.4 KiB
实时奖品价格统计功能 - 系统设计文档
系统架构图
graph TD
A[奖品数据变化] --> B[Vue响应式系统]
B --> C[totalCost计算属性]
C --> D[价格格式化函数]
D --> E[UI界面显示]
F[priceCache] --> C
G[rows数组] --> C
H[productOptions] --> F
I[添加奖品] --> A
J[编辑奖品] --> A
K[删除奖品] --> A
L[清空奖品] --> A
核心组件设计
1. 数据流架构
sequenceDiagram
participant User
participant UI
participant VueReactive
participant Computed
participant Formatter
User->>UI: 添加/编辑/删除奖品
UI->>VueReactive: 更新rows数组
VueReactive->>Computed: 触发totalCost重新计算
Computed->>Computed: 读取priceCache和rows
Computed->>Formatter: 返回计算结果
Formatter->>UI: 格式化显示¥1,234.56
UI->>User: 显示更新后的总价格
2. 模块设计
计算模块(Computation Module)
// 核心计算逻辑
const totalCost = computed(() => {
return rows.value.reduce((sum: number, r: any) => {
const price = priceCache.value[r.product_id] || 0
const qty = Number(r.quantity) || 0
return sum + price * qty
}, 0)
})
格式化模块(Formatter Module)
// 货币格式化函数
function formatCurrency(amount: number): string {
return new Intl.NumberFormat('zh-CN', {
style: 'currency',
currency: 'CNY',
minimumFractionDigits: 2,
maximumFractionDigits: 2
}).format(amount)
}
缓存模块(Cache Module)
// 价格缓存机制
const priceCache = ref<Record<number, number>>({})
// 商品加载时更新缓存
async function loadProducts() {
const response = await fetchProducts({ page: 1, page_size: 100 })
response.list?.forEach((p: any) => {
if (p.id && p.price !== undefined) {
priceCache.value[p.id] = Number(p.price) || 0
}
})
}
3. 接口设计
内部接口(Internal Interfaces)
interface PriceCalculationService {
calculateTotalCost(rewards: Reward[], prices: PriceCache): number
formatCurrency(amount: number): string
updatePriceCache(products: Product[]): void
}
interface Reward {
product_id: number
quantity: number
// ... 其他属性
}
interface PriceCache {
[productId: number]: number
}
外部接口(External Interfaces)
// 商品接口(现有)
interface Product {
id: number
name: string
price: number
// ... 其他属性
}
// API响应接口(现有)
interface ProductResponse {
list: Product[]
total: number
}
4. UI组件设计
统计展示组件
<!-- 奖品工具栏统计区域 -->
<div class="reward-stats">
<span class="stat-item">总计:{{ rows.length }} 个奖品</span>
<span class="stat-item ml-4">总价值:{{ formatCurrency(totalCost) }}</span>
</div>
样式设计
.reward-stats {
margin-left: auto;
display: flex;
align-items: center;
gap: 16px;
.stat-item {
font-size: 14px;
color: var(--el-text-color-regular);
font-weight: 500;
&.ml-4 {
margin-left: 16px;
}
}
}
数据模型设计
奖品数据模型(Reward Data Model)
interface Reward {
product_id: number // 商品ID
product_name: string // 商品名称
product_price: number // 商品单价(冗余存储)
quantity: number // 奖品数量
weight: number // 抽奖权重
level: number // 奖品等级
is_boss: number // 是否Boss奖品
}
价格缓存模型(Price Cache Model)
interface PriceCache {
[productId: number]: number // 商品ID到价格的映射
}
异常处理设计
数据异常处理
// 空值处理
const price = priceCache.value[r.product_id] || 0
const qty = Number(r.quantity) || 0
// 非法价格处理
function validatePrice(price: any): number {
const num = Number(price)
return isNaN(num) || num < 0 ? 0 : num
}
计算异常处理
// 计算溢出保护
function safeMultiply(a: number, b: number): number {
const result = a * b
return isFinite(result) ? result : 0
}
性能设计
计算性能优化
- 缓存机制: 复用
priceCache避免重复计算 - 响应式优化: 使用
computed缓存计算结果 - 算法复杂度: O(n),n为奖品数量
内存优化
- 轻量级计算: 不产生额外的内存开销
- 缓存复用: 复用现有的价格缓存数据
- 及时清理: 组件卸载时自动清理响应式依赖
安全设计
数据安全
- 输入验证: 验证奖品数量和价格的合法性
- 精度控制: 使用适当的数值精度避免计算误差
- 类型安全: 使用TypeScript确保类型安全
业务安全
- 价格完整性: 确保所有商品都有有效的价格
- 计算准确性: 避免浮点数精度问题
- 显示一致性: 确保货币格式的一致性显示
扩展性设计
功能扩展
- 多货币支持: 易于扩展支持多种货币
- 统计维度: 可扩展支持更多统计维度
- 筛选功能: 可扩展支持按条件筛选统计
技术扩展
- 组件化: 易于提取为独立组件
- 配置化: 支持通过配置自定义显示格式
- 插件化: 可扩展为Vue插件供全局使用