consumer模块完成90%,完善店铺商品优惠券领取

This commit is contained in:
2026-02-05 17:27:22 +08:00
parent 0ee4577b31
commit 06b7369494
22 changed files with 2096 additions and 1286 deletions

View File

@@ -48,6 +48,13 @@ export interface Product {
attributes?: string // JSON string
created_at?: string
updated_at?: string
// Alias fields for compatibility
price?: number
original_price?: number
stock?: number
sales?: number
images?: string
cover?: string
// View fields
brand_name?: string
category_name?: string
@@ -928,21 +935,51 @@ class SupabaseService {
}
}
// 获取与特定商家的聊天记录
async getChatMessages(merchantId: string): Promise<ChatMessage[]> {
try {
const userId = this.getCurrentUserId()
if (!userId) return []
const response = await supa
.from('ml_chat_messages')
.select('*')
.or(`and(sender_id.eq.${userId},receiver_id.eq.${merchantId}),and(sender_id.eq.${merchantId},receiver_id.eq.${userId})`)
.order('created_at', { ascending: false })
.limit(50)
.execute()
if (response.error) {
console.error('获取聊天记录失败:', response.error)
return []
}
return response.data as ChatMessage[]
} catch (e) {
console.error('获取聊天记录异常:', e)
return []
}
}
// 发送聊天消息
async sendChatMessage(content: string, type: string = 'text'): Promise<boolean> {
async sendChatMessage(content: string, toId: string | null = null, type: string = 'text'): Promise<boolean> {
try {
const userId = this.getCurrentUserId()
if (!userId) return false
const payload : any = {
sender_id: userId,
content: content,
msg_type: type,
is_from_user: true,
created_at: new Date().toISOString()
}
if (toId != null) {
payload['receiver_id'] = toId
}
const response = await supa
.from('ml_chat_messages')
.insert({
sender_id: userId,
content: content,
msg_type: type,
is_from_user: true,
created_at: new Date().toISOString()
})
.insert(payload)
.execute()
if (response.error) {
@@ -2732,6 +2769,94 @@ class SupabaseService {
return 0
}
}
// 获取店铺/商品可用优惠券
async getAvailableCoupons(merchantId: string): Promise<any[]> {
return this.fetchShopCoupons(merchantId)
}
// ALIAS for Cache busting: 获取店铺优惠券
async fetchShopCoupons(merchantId: string): Promise<any[]> {
try {
// 查询该商家的优惠券 + 平台通用券 (merchant_id is null)
// 注意:这里简化逻辑,实际可能需要联合查询用户是否已领取
const response = await supa
.from('ml_coupon_templates')
.select('*')
.or(`merchant_id.eq.${merchantId},merchant_id.is.null`)
.eq('status', 1)
.gt('end_time', new Date().toISOString())
.order('discount_value', { ascending: false })
.execute()
if (response.error) {
console.error('Fetch coupons failed:', response.error)
return []
}
return response.data
} catch (e) {
console.error('Fetch coupons error:', e)
return []
}
}
// 领取优惠券
async claimCoupon(templateId: string, userId: string): Promise<boolean> {
return this.claimShopCoupon(templateId, userId)
}
// ALIAS for Cache busting
async claimShopCoupon(templateId: string, userId: string): Promise<boolean> {
try {
// 1. Fetch template details to get merchant_id and validity
const tmplRes = await supa
.from('ml_coupon_templates')
.select('*')
.eq('id', templateId)
.single()
if (tmplRes.error) {
console.error('Claim Coupon: Template not found', tmplRes.error)
return false
}
const template = tmplRes.data as any
// Calculate expire_at
let expireAt = new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString()
if (template['valid_days'] && (template['valid_days'] as number) > 0) {
expireAt = new Date(Date.now() + (template['valid_days'] as number) * 24 * 60 * 60 * 1000).toISOString()
} else if (template['end_time']) {
expireAt = template['end_time'] as string
}
// 2. Insert into user coupons with merchant_id
const insertData = {
user_id: userId,
template_id: templateId,
merchant_id: template['merchant_id'], // Important for shop filtering
coupon_code: 'C' + Date.now() + Math.floor(Math.random() * 1000),
status: 1,
expire_at: expireAt,
received_at: new Date().toISOString()
}
const response = await supa
.from('ml_user_coupons')
.insert(insertData)
.execute()
if (response.error) {
console.error('Claim Coupon: Insert failed', response.error)
return false
}
return true
} catch(e) {
console.error('Claim coupon error:', e)
return false
}
}
}
// 导出单例实例