From 815f020c50637ee94e86fc90820aa7d814bc004d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E5=BF=A0=E6=9E=97?= <170083662@qq.com> Date: Sat, 9 Aug 2025 19:59:48 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=EF=BC=9A=E4=BC=98=E6=83=A0?= =?UTF-8?q?=E5=88=B8=E3=80=81=E7=A7=AF=E5=88=86=E6=98=8E=E7=BB=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/env.ts | 2 +- src/api/shop/shopCoupon/model/index.ts | 65 ++++++ src/api/shop/shopGoodsCoupon/model/index.ts | 35 +++ src/api/user/balance-log/model/index.ts | 1 + src/cms/category/components/ArticleTabs.tsx | 7 +- src/user/coupon/coupon.tsx | 227 +++++++++++--------- src/user/points/points.tsx | 214 +++++++++--------- src/user/wallet/wallet.tsx | 201 ++++++++--------- src/utils/server.ts | 4 +- 9 files changed, 431 insertions(+), 325 deletions(-) create mode 100644 src/api/shop/shopCoupon/model/index.ts create mode 100644 src/api/shop/shopGoodsCoupon/model/index.ts diff --git a/config/env.ts b/config/env.ts index f2afab4..cdc046e 100644 --- a/config/env.ts +++ b/config/env.ts @@ -2,7 +2,7 @@ export const ENV_CONFIG = { // 开发环境 development: { - API_BASE_URL: 'https://cms-api.websoft.top/api', + API_BASE_URL: 'http://127.0.0.1:9200/api', APP_NAME: '时里院子市集', DEBUG: 'true', }, diff --git a/src/api/shop/shopCoupon/model/index.ts b/src/api/shop/shopCoupon/model/index.ts new file mode 100644 index 0000000..5c4f42b --- /dev/null +++ b/src/api/shop/shopCoupon/model/index.ts @@ -0,0 +1,65 @@ +import type { PageParam } from '@/api/index'; + +/** + * 优惠券 + */ +export interface ShopCoupon { + // id + id?: number; + // 优惠券名称 + name?: string; + // 优惠券描述 + description?: string; + // 优惠券类型(10满减券 20折扣券 30免费劵) + type?: number; + // 满减券-减免金额 + reducePrice?: string; + // 折扣券-折扣率(0-100) + discount?: number; + // 最低消费金额 + minPrice?: string; + // 到期类型(10领取后生效 20固定时间) + expireType?: number; + // 领取后生效-有效天数 + expireDay?: number; + // 有效期开始时间 + startTime?: string; + // 有效期结束时间 + endTime?: string; + // 适用范围(10全部商品 20指定商品 30指定分类) + applyRange?: number; + // 适用范围配置(json格式) + applyRangeConfig?: string; + // 是否过期(0未过期 1已过期) + isExpire?: number; + // 排序(数字越小越靠前) + sortNumber?: number; + // 状态, 0正常, 1禁用 + status?: number; + // 是否删除, 0否, 1是 + deleted?: number; + // 创建用户ID + userId?: number; + // 租户id + tenantId?: number; + // 创建时间 + createTime?: string; + // 修改时间 + updateTime?: string; + // 发放总数量(-1表示无限制) + totalCount?: number; + // 已发放数量 + issuedCount?: number; + // 每人限领数量(-1表示无限制) + limitPerUser?: number; + // 是否启用(0禁用 1启用) + enabled?: string; +} + +/** + * 优惠券搜索条件 + */ +export interface ShopCouponParam extends PageParam { + id?: number; + keywords?: string; +} diff --git a/src/api/shop/shopGoodsCoupon/model/index.ts b/src/api/shop/shopGoodsCoupon/model/index.ts new file mode 100644 index 0000000..0caed76 --- /dev/null +++ b/src/api/shop/shopGoodsCoupon/model/index.ts @@ -0,0 +1,35 @@ +import type { PageParam } from '@/api/index'; + +/** + * 商品优惠券表 + */ +export interface ShopGoodsCoupon { + // + id?: number; + // 商品id + goodsId?: number; + // 优惠劵id + issueCouponId?: number; + // 排序(数字越小越靠前) + sortNumber?: number; + // 状态, 0正常, 1冻结 + status?: number; + // 是否删除, 0否, 1是 + deleted?: number; + // 用户ID + userId?: number; + // 租户id + tenantId?: number; + // 注册时间 + createTime?: string; + // 修改时间 + updateTime?: string; +} + +/** + * 商品优惠券表搜索条件 + */ +export interface ShopGoodsCouponParam extends PageParam { + id?: number; + keywords?: string; +} diff --git a/src/api/user/balance-log/model/index.ts b/src/api/user/balance-log/model/index.ts index e2fc4ed..045e8f1 100644 --- a/src/api/user/balance-log/model/index.ts +++ b/src/api/user/balance-log/model/index.ts @@ -8,6 +8,7 @@ export interface UserBalanceLog { userId?: number; scene?: number; money?: string; + balance?: number; describe?: string; remark?: string; sortNumber?: number; diff --git a/src/cms/category/components/ArticleTabs.tsx b/src/cms/category/components/ArticleTabs.tsx index 428d93f..a995345 100644 --- a/src/cms/category/components/ArticleTabs.tsx +++ b/src/cms/category/components/ArticleTabs.tsx @@ -11,7 +11,12 @@ const ArticleTabs = (props: any) => { const reload = async (value) => { const {data} = props - pageCmsArticle({categoryId: data[value].navigationId, page: 1, limit: 10}).then((res) => { + pageCmsArticle({ + categoryId: data[value].navigationId, + page: 1, + status: 0, + limit: 10 + }).then((res) => { res && setList(res?.list || []) }) .catch(err => { diff --git a/src/user/coupon/coupon.tsx b/src/user/coupon/coupon.tsx index 70cd554..0313327 100644 --- a/src/user/coupon/coupon.tsx +++ b/src/user/coupon/coupon.tsx @@ -1,13 +1,22 @@ -import {useEffect, useState} from "react"; +import {useState, useEffect, CSSProperties} from 'react' import Taro from '@tarojs/taro' -import {Button, Cell, Space, Empty, ConfigProvider, Tabs, TabPane, Tag} from '@nutui/nutui-react-taro' -import {View} from '@tarojs/components' +import {Cell, InfiniteLoading, Tabs, TabPane, Tag, Empty, ConfigProvider} from '@nutui/nutui-react-taro' import {pageUserCoupon, getUserCouponCount} from "@/api/user/coupon"; import {UserCoupon as UserCouponType} from "@/api/user/coupon/model"; +import {View} from '@tarojs/components' + +const InfiniteUlStyle: CSSProperties = { + height: '100vh', + width: '100%', + padding: '0', + overflowY: 'auto', + overflowX: 'hidden', +} const UserCoupon = () => { const [list, setList] = useState([]) - const [loading, setLoading] = useState(false) + const [page, setPage] = useState(1) + const [hasMore, setHasMore] = useState(true) const [activeTab, setActiveTab] = useState('0') const [couponCount, setCouponCount] = useState({ total: 0, @@ -23,42 +32,43 @@ const UserCoupon = () => { { key: '3', title: '已过期', status: 2 } ] - const reload = (status?: number) => { - setLoading(true) - const userId = Taro.getStorageSync('UserId') + useEffect(() => { + reload() + loadCouponCount() + }, []) - console.log('Loading coupons for userId:', userId, 'status:', status) + const loadMore = async () => { + setPage(page + 1) + reload(); + } + const reload = () => { + const userId = Taro.getStorageSync('UserId') if (!userId) { - console.warn('No userId found in storage') Taro.showToast({ title: '请先登录', icon: 'error' }); - setLoading(false) return } + const tab = tabs.find(t => t.key === activeTab) pageUserCoupon({ userId: parseInt(userId), - status: status, - page: 1, - limit: 20 + status: tab?.status, + page + }).then(res => { + console.log(res) + const newList = res?.list || []; + setList([...list, ...newList]) + setHasMore(newList.length > 0) + }).catch(error => { + console.error('Coupon error:', error) + Taro.showToast({ + title: error?.message || '获取失败', + icon: 'error' + }); }) - .then((res: any) => { - console.log('Coupon response:', res) - setList(res?.list || []) - }) - .catch((error: any) => { - console.error('Coupon error:', error) - Taro.showToast({ - title: error?.message || '获取失败', - icon: 'error' - }); - }) - .finally(() => { - setLoading(false) - }) } const loadCouponCount = () => { @@ -74,15 +84,15 @@ const UserCoupon = () => { }) } - useEffect(() => { - reload() - loadCouponCount() - }, []); - const onTabChange = (index: string) => { setActiveTab(index) - const tab = tabs.find(t => t.key === index) - reload(tab?.status) + setList([]) // 清空列表 + setPage(1) // 重置页码 + setHasMore(true) // 重置hasMore + // 延迟执行reload,确保状态更新完成 + setTimeout(() => { + reload() + }, 0) } const getCouponTypeText = (type?: number) => { @@ -122,86 +132,91 @@ const UserCoupon = () => { } } - if (loading) { - return ( - -
-
加载中...
-
-
- ) - } - - if (list.length == 0) { - return ( - -
- - - - -
-
- ) - } - return ( - + {tabs.map(tab => ( - - {list.map((item, index) => ( - - - - - - - {formatCouponValue(item.type, item.value)} - - - - {item.name || getCouponTypeText(item.type)} - - {item.minAmount && parseFloat(item.minAmount) > 0 && ( - - 满¥{item.minAmount}可用 +
    + { + console.log('onScroll') + }} + onScrollToUpper={() => { + console.log('onScrollToUpper') + }} + loadingText={ + <> + 加载中 + + } + loadMoreText={ + <> + 没有更多了 + + } + > + + {list.length === 0 ? ( +
    + +
    + ) : ( + list.map((item, index) => ( + + + + + + + {formatCouponValue(item.type, item.value)} + + + + {item.name || getCouponTypeText(item.type)} + + {item.minAmount && parseFloat(item.minAmount) > 0 && ( + + 满¥{item.minAmount}可用 + + )} + - )} - - - - - 有效期: {item.startTime ? new Date(item.startTime).toLocaleDateString() : ''} - {item.endTime ? new Date(item.endTime).toLocaleDateString() : ''} - - - {getCouponStatusText(item.status)} - - - - {item.comments && ( - - {item.comments} + + + 有效期: {item.startTime ? new Date(item.startTime).toLocaleDateString() : ''} - {item.endTime ? new Date(item.endTime).toLocaleDateString() : ''} + + + {getCouponStatusText(item.status)} + + + + {item.comments && ( + + {item.comments} + + )} +
    - )} - - - - - ))} - + + + )) + )} + +
    +
))}
diff --git a/src/user/points/points.tsx b/src/user/points/points.tsx index da1c30b..5157d49 100644 --- a/src/user/points/points.tsx +++ b/src/user/points/points.tsx @@ -1,50 +1,59 @@ -import {useEffect, useState} from "react"; +import {useState, useEffect, CSSProperties} from 'react' import Taro from '@tarojs/taro' -import {Button, Cell, Space, Empty, ConfigProvider, Card} from '@nutui/nutui-react-taro' -import {View} from '@tarojs/components' +import {Cell, InfiniteLoading, Card, Empty, ConfigProvider} from '@nutui/nutui-react-taro' import {pageUserPointsLog, getUserPointsStats} from "@/api/user/points"; import {UserPointsLog as UserPointsLogType, UserPointsStats} from "@/api/user/points/model"; +import {View} from '@tarojs/components' + +const InfiniteUlStyle: CSSProperties = { + height: '100vh', + width: '100%', + padding: '0', + overflowY: 'auto', + overflowX: 'hidden', +} const UserPoints = () => { const [list, setList] = useState([]) - const [loading, setLoading] = useState(false) + const [page, setPage] = useState(1) + const [hasMore, setHasMore] = useState(true) const [stats, setStats] = useState({}) - const reload = () => { - setLoading(true) - const userId = Taro.getStorageSync('UserId') + useEffect(() => { + reload() + loadPointsStats() + }, []) - console.log('Loading points log for userId:', userId) + const loadMore = async () => { + setPage(page + 1) + reload(); + } + const reload = () => { + const userId = Taro.getStorageSync('UserId') if (!userId) { - console.warn('No userId found in storage') Taro.showToast({ title: '请先登录', icon: 'error' }); - setLoading(false) return } pageUserPointsLog({ userId: parseInt(userId), - page: 1, - limit: 20 + page + }).then(res => { + console.log(res) + const newList = res?.list || []; + setList([...list, ...newList]) + setHasMore(newList.length > 0) + }).catch(error => { + console.error('Points log error:', error) + Taro.showToast({ + title: error?.message || '获取失败', + icon: 'error' + }); }) - .then((res: any) => { - console.log('Points log response:', res) - setList(res?.list || []) - }) - .catch((error: any) => { - console.error('Points log error:', error) - Taro.showToast({ - title: error?.message || '获取失败', - icon: 'error' - }); - }) - .finally(() => { - setLoading(false) - }) } const loadPointsStats = () => { @@ -60,11 +69,6 @@ const UserPoints = () => { }) } - useEffect(() => { - reload() - loadPointsStats() - }, []); - const getPointsTypeText = (type?: number) => { switch (type) { case 1: return '获得积分' @@ -85,21 +89,9 @@ const UserPoints = () => { } } - if (loading) { - return ( - -
-
加载中...
-
-
- ) - } - return ( - + {/* 积分统计卡片 */} @@ -134,62 +126,84 @@ const UserPoints = () => { {/* 积分记录 */} - - 积分明细 - - {list.length === 0 ? ( -
- - - - -
- ) : ( - list.map((item, index) => ( - - - - - - {getPointsTypeText(item.type)} - - - {item.reason || '无备注'} - - - - {item.type === 1 ? '+' : item.type === 2 ? '-' : ''} - {item.points || 0} - - - - - - {item.createTime ? new Date(item.createTime).toLocaleString() : ''} - - {item.orderId && ( - - 订单: {item.orderId} - - )} - - - {item.comments && ( - - 备注: {item.comments} - - )} - - - )) - )} + + +
    + { + console.log('onScroll') + }} + onScrollToUpper={() => { + console.log('onScrollToUpper') + }} + loadingText={ + <> + 加载中 + + } + loadMoreText={ + <> + 没有更多了 + + } + > + + {list.length === 0 ? ( +
    + +
    + ) : ( + list.map((item, index) => ( + + + + + + {getPointsTypeText(item.type)} + + + {item.reason || '无备注'} + + + + {item.type === 1 ? '+' : item.type === 2 ? '-' : ''} + {item.points || 0} + + + + + + {item.createTime ? new Date(item.createTime).toLocaleString() : ''} + + {item.orderId && ( + + 订单: {item.orderId} + + )} + + + {item.comments && ( + + 备注: {item.comments} + + )} + + + )) + )} +
    +
    +
diff --git a/src/user/wallet/wallet.tsx b/src/user/wallet/wallet.tsx index 1ecf44d..9b842c3 100644 --- a/src/user/wallet/wallet.tsx +++ b/src/user/wallet/wallet.tsx @@ -1,134 +1,105 @@ -import {useEffect, useState} from "react"; -import Taro from '@tarojs/taro' -import {Button, Cell, Space, Empty, ConfigProvider, InfiniteLoading} from '@nutui/nutui-react-taro' -import {View, ScrollView} from '@tarojs/components' +import {useState, useEffect, CSSProperties} from 'react' +import {Cell, InfiniteLoading} from '@nutui/nutui-react-taro' import {pageUserBalanceLog} from "@/api/user/balance-log"; import {UserBalanceLog} from "@/api/user/balance-log/model"; import {formatCurrency} from "@/utils/common"; +import {View} from '@tarojs/components' + +const InfiniteUlStyle: CSSProperties = { + height: '100vh', + width: '100%', + padding: '0', + overflowY: 'auto', + overflowX: 'hidden', +} const Wallet = () => { const [list, setList] = useState([]) - const [loading, setLoading] = useState(false) - const [loadingMore, setLoadingMore] = useState(false) - const [refreshing, setRefreshing] = useState(false) + const [page, setPage] = useState(1) const [hasMore, setHasMore] = useState(true) - const [currentPage, setCurrentPage] = useState(1) - const [total, setTotal] = useState(0) - const pageSize = 20 - - const reload = () => { - setLoading(true) - const userId = Taro.getStorageSync('UserId') - - console.log('Loading balance log for userId:', userId) - - if (!userId) { - console.warn('No userId found in storage') - Taro.showToast({ - title: '请先登录', - icon: 'error' - }); - setLoading(false) - return - } - - pageUserBalanceLog({ - userId: parseInt(userId), - page: 1, - limit: 20 - }) - .then((res: any) => { - console.log('Balance log response:', res) - setList(res?.list || []) - }) - .catch((error: any) => { - console.error('Balance log error:', error) - Taro.showToast({ - title: error?.message || '获取失败', - icon: 'error' - }); - }) - .finally(() => { - setLoading(false) - }) - } useEffect(() => { reload() - }, []); + }, []) - if (loading) { - return ( - -
-
加载中...
-
-
- ) + const loadMore = async () => { + setPage(page + 1) + reload(); } - if (list.length == 0) { - return ( - -
- - - - -
-
- ) + const reload = () => { + pageUserBalanceLog({page}).then(res => { + console.log(res) + const newList = res?.list || []; + setList([...list, ...newList]) + setHasMore(newList.length > 0) + }) } return ( - - - {list.map((item, index) => ( - - - - - - {item.scene === 10 ? '会员充值' : item.scene === 20 ? '用户消费' : item.scene === 30 ? '管理员操作' : '订单退款'} + <> +
    + { + console.log('onScroll') + }} + onScrollToUpper={() => { + console.log('onScrollToUpper') + }} + loadingText={ + <> + 加载中 + + } + loadMoreText={ + <> + 没有更多了 + + } + > + + {list.map((item, index) => ( + + + + + + {item.scene === 10 ? '会员充值' : item.scene === 20 ? '用户消费' : item.scene === 30 ? '管理员操作' : '订单退款'} + + + {item.comments} + + + + {item.scene === 10 ? '+' : '-'} + {formatCurrency(Number(item.money), 'CNY') || '0.00'} + - - {item.comments} - - - - {item.scene === 10 ? '+' : '-'} - {formatCurrency(Number(item.money), 'CNY') || '0.00'} - - - - - - {item.createTime} - - - {item.remark && ( - - 备注: {item.remark} - - )} - - - ))} - - - ); -}; + + + {item.createTime} + + 余额:{item?.balance} + -export default Wallet; + {item.remark && ( + + 备注: {item.remark} + + )} + + + ))} + + +
+ + ) +} +export default Wallet diff --git a/src/utils/server.ts b/src/utils/server.ts index 8cd39ba..fb48f69 100644 --- a/src/utils/server.ts +++ b/src/utils/server.ts @@ -4,8 +4,8 @@ import {User} from "@/api/system/user/model"; // 模版套餐ID - 请根据实际情况修改 export const TEMPLATE_ID = '10550'; // 服务接口 - 请根据实际情况修改 -// export const SERVER_API_URL = 'https://server.websoft.top/api'; -export const SERVER_API_URL = 'http://127.0.0.1:8000/api'; +export const SERVER_API_URL = 'https://server.websoft.top/api'; +// export const SERVER_API_URL = 'http://127.0.0.1:8000/api'; /** * 保存用户信息到本地存储 * @param token