Browse Source

✨ feat(coupon): 实现公共微信代金券批次查询功能

- 添加公共微信代金券批次API路由
- 创建publicWechatCouponStockClient客户端
- 更新代金券批次查询接口引用和状态过滤条件
- 调整前端展示字段,使用availableQuantity和couponQuantity替代原字段

♻️ refactor(api): 优化代金券批次数据获取逻辑

- 重命名wechatCouponStockClient为publicWechatCouponStockClient
- 调整查询参数filters中status值为'RUNNING'字符串类型
- 更新代金券剩余数量展示逻辑,使用新的字段名
yourname 3 months ago
parent
commit
0f01c2f2df

+ 7 - 7
mini/src/pages/index/index.tsx

@@ -2,7 +2,7 @@ import { useState } from 'react'
 import { View, Text, ScrollView, Swiper, SwiperItem, Image } from '@tarojs/components'
 import Taro from '@tarojs/taro'
 import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
-import { publicAdvertisementClient, wechatCouponStockClient } from '@/api'
+import { publicAdvertisementClient, publicWechatCouponStockClient } from '@/api'
 import { Button } from '@/components/ui/button'
 import { Card, CardContent, CardHeader } from '@/components/ui/card'
 import { cn } from '@/utils/cn'
@@ -17,7 +17,7 @@ type AdvertisementResponse = InferResponseType<typeof publicAdvertisementClient.
 type Advertisement = AdvertisementResponse['data'][0]
 
 // 使用RPC类型安全提取代金券批次响应类型
-type WechatCouponStockResponse = InferResponseType<typeof wechatCouponStockClient.$get, 200>
+type WechatCouponStockResponse = InferResponseType<typeof publicWechatCouponStockClient.$get, 200>
 type WechatCouponStock = WechatCouponStockResponse['data'][0]
 
 export default function IndexPage() {
@@ -45,11 +45,11 @@ export default function IndexPage() {
   const { data: stocks, isLoading: stocksLoading } = useQuery({
     queryKey: ['wechat-coupon-stocks'],
     queryFn: async () => {
-      const response = await wechatCouponStockClient.$get({
+      const response = await publicWechatCouponStockClient.$get({
         query: {
           page: 1,
           pageSize: 20,
-          filters: JSON.stringify({ status: 1 }),
+          filters: JSON.stringify({ status: 'RUNNING' }),
         },
       })
       if (response.status !== 200) throw new Error('获取批次失败')
@@ -194,7 +194,7 @@ export default function IndexPage() {
                   
                   <View className="flex justify-between items-center">
                     <Text className="text-xs text-gray-500">
-                      剩余: {stock.couponRemaining}/{stock.couponTotal}
+                      剩余: {stock.availableQuantity}/{stock.couponQuantity}
                     </Text>
                     <Text className="text-xs text-gray-500">
                       {new Date(stock.endTime).toLocaleDateString()} 截止
@@ -208,10 +208,10 @@ export default function IndexPage() {
                         ? 'bg-red-500 text-white'
                         : 'bg-gray-300 text-gray-500'
                     )}
-                    disabled={stock.couponRemaining === 0}
+                    disabled={stock.availableQuantity === 0}
                     onClick={() => handleReceiveCoupon(stock.id)}
                   >
-                    {stock.couponRemaining > 0 ? '立即领取' : '已领完'}
+                    {stock.availableQuantity > 0 ? '立即领取' : '已领完'}
                   </Button>
                 </CardContent>
               </Card>

+ 6 - 1
src/client/api.ts

@@ -12,6 +12,7 @@ import type { CouponLogRoutes } from '@/server/api'
 import type { RedemptionCodeRoutes } from '@/server/api'
 import type { AdvertisementRoutes } from '@/server/api'
 import type { PublicAdvertisementRoutes } from '@/server/api'
+import type { PublicWechatCouponStockRoutes } from '@/server/api'
 
 export const authClient = hc<AuthRoutes>('/', {
   fetch: axiosFetch,
@@ -59,4 +60,8 @@ export const advertisementClient = hc<AdvertisementRoutes>('/', {
 
 export const publicAdvertisementClient = hc<PublicAdvertisementRoutes>('/', {
   fetch: axiosFetch,
-}).api.v1.public.advertisements
+}).api.v1.public.advertisements
+
+export const publicWechatCouponStockClient = hc<PublicWechatCouponStockRoutes>('/', {
+  fetch: axiosFetch,
+}).api.v1.public['wechat-coupon-stocks']

+ 3 - 0
src/server/api.ts

@@ -13,6 +13,7 @@ import couponLogRoutes from './api/coupon-logs/index'
 import redemptionCodeRoutes from './api/redemption-codes/index'
 import advertisementRoutes from './api/advertisements/index'
 import publicAdvertisementRoutes from './api/public/advertisements/index'
+import publicWechatCouponStockRoutes from './api/public/wechat-coupon-stocks/index'
 import { AuthContext } from './types/context'
 import { AppDataSource } from './data-source'
 import { Hono } from 'hono'
@@ -119,6 +120,7 @@ const couponLogApiRoutes = api.route('/api/v1/coupon-logs', couponLogRoutes)
 const redemptionCodeApiRoutes = api.route('/api/v1/redemption-codes', redemptionCodeRoutes)
 const advertisementApiRoutes = api.route('/api/v1/advertisements', advertisementRoutes)
 const publicAdvertisementApiRoutes = api.route('/api/v1/public/advertisements', publicAdvertisementRoutes)
+const publicWechatCouponStockApiRoutes = api.route('/api/v1/public/wechat-coupon-stocks', publicWechatCouponStockRoutes)
 
 export type AuthRoutes = typeof authRoutes
 export type UserRoutes = typeof userRoutes
@@ -132,6 +134,7 @@ export type CouponLogRoutes = typeof couponLogApiRoutes
 export type RedemptionCodeRoutes = typeof redemptionCodeApiRoutes
 export type AdvertisementRoutes = typeof advertisementApiRoutes
 export type PublicAdvertisementRoutes = typeof publicAdvertisementApiRoutes
+export type PublicWechatCouponStockRoutes = typeof publicWechatCouponStockApiRoutes
 
 app.route('/', api)
 export default app

+ 16 - 0
src/server/api/public/wechat-coupon-stocks/index.ts

@@ -0,0 +1,16 @@
+import { createCrudRoutes } from '@/server/utils/generic-crud.routes';
+import { WechatCouponStock } from '@/server/modules/wechat-pay/wechat-coupon-stock.entity';
+import { WechatCouponStockSchema } from '@/server/modules/wechat-pay/wechat-coupon-stock.schema';
+
+const wechatCouponStockRoutes = createCrudRoutes({
+  entity: WechatCouponStock,
+  createSchema: WechatCouponStockSchema,
+  updateSchema: WechatCouponStockSchema,
+  getSchema: WechatCouponStockSchema,
+  listSchema: WechatCouponStockSchema,
+  searchFields: ['stockName', 'stockId'],
+  relations: ['config'],
+  readOnly: true,
+});
+
+export default wechatCouponStockRoutes;