consumer模块完成90%,完善店铺商品优惠券领取
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 导出单例实例
|
||||
|
||||
Reference in New Issue
Block a user