From 5fe881b927f96101a95e7f5816287d8fe7a99432 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E5=BF=A0=E6=9E=97?= <170083662@qq.com> Date: Tue, 31 Mar 2026 13:37:14 +0800 Subject: [PATCH] =?UTF-8?q?feat(dealer):=20=E6=B7=BB=E5=8A=A0=E9=85=8D?= =?UTF-8?q?=E9=80=81=E5=91=98=E8=A7=A3=E5=86=BB=E8=B5=84=E9=87=91=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在dealer页面添加配送员权限判断和解冻资金功能 - 导入useUser hook和updateShopDealerUser API - 仅配送员角色可操作冻结金额转入可提现 - 点击待使用金额弹出确认框进行资金转移 - 统一rider和dealer页面的解冻资金逻辑实现 - 修改环境配置支持SERVER_API_URL变量导出 - 更新版权信息配置结构优化代码注释 - 优化待使用金额卡片点击交互体验 --- .workbuddy/memory/2026-03-31.md | 29 ++++++++++ .workbuddy/memory/MEMORY.md | 0 config/app.ts | 1 + config/env.ts | 39 ++++++------- src/dealer/index.tsx | 73 ++++++++++++++++++++++-- src/pages/user/components/UserFooter.tsx | 2 +- src/rider/index.tsx | 73 ++++++++++++++++++++++-- src/utils/server.ts | 9 +-- 8 files changed, 193 insertions(+), 33 deletions(-) create mode 100644 .workbuddy/memory/2026-03-31.md create mode 100644 .workbuddy/memory/MEMORY.md diff --git a/.workbuddy/memory/2026-03-31.md b/.workbuddy/memory/2026-03-31.md new file mode 100644 index 0000000..085e128 --- /dev/null +++ b/.workbuddy/memory/2026-03-31.md @@ -0,0 +1,29 @@ +# 2026-03-31 工作日志 + +## 新增 dealer/index.tsx 配送员解冻资金功能 + +将 `/rider/index.tsx` 的 `handleFreezeMoneyClick` 功能复制到 `/dealer/index.tsx`: +- 导入 `useUser` hook 和 `updateShopDealerUser` API +- 添加 `isRider` 判断(只有 `hasRole('rider')` 才可操作) +- "待使用"卡片点击事件(仅配送员+有冻结金额时可用) +- 确认后冻结金额转入可提现 + +## 修改 rider/index.tsx (React Taro 项目) + +修改了 `/Users/gxwebsoft/VUE/template-10584/src/rider/index.tsx`: + +### 修改内容: +1. **统一显示格式** - 把"桶数"改成"待使用" +2. **添加配送员权限控制** - 只有 `hasRole('rider')` 的用户才能点击操作 +3. **点击解冻功能**: + - 配送员点击"待使用"金额时显示蓝色高亮提示"(点击转入)" + - 弹出确认框:`确定要将 ¥xx.xx 待使用金额转入可提现吗?` + - 确认后调用 `updateShopDealerUser` API + - 将 `freezeMoney` 清零,加到 `money` + - 成功后提示"更新成功"并刷新数据 + +### 关键代码: +- 使用 `useUser` hook 获取 `hasRole` 函数 +- `isRider` 判断是否为配送员 +- `handleFreezeMoneyClick` 处理点击解冻逻辑 +- 使用 `Taro.showModal` / `Taro.showToast` 提示用户 diff --git a/.workbuddy/memory/MEMORY.md b/.workbuddy/memory/MEMORY.md new file mode 100644 index 0000000..e69de29 diff --git a/config/app.ts b/config/app.ts index 8256046..ff427b8 100644 --- a/config/app.ts +++ b/config/app.ts @@ -10,5 +10,6 @@ export const BaseUrl = API_BASE_URL; export const Version = 'v3.0.8'; // 版权信息 export const Copyright = '桂乐淘·购享无界 乐惠万家'; +// export const Copyright = '测试环境 v3.2.6'; // java -jar CertificateDownloader.jar -k 0kF5OlPr482EZwtn9zGufUcqa7ovgxRL -m 1723321338 -f ./apiclient_key.pem -s 2B933F7C35014A1C363642623E4A62364B34C4EB -o ./ diff --git a/config/env.ts b/config/env.ts index 390067b..d0947f1 100644 --- a/config/env.ts +++ b/config/env.ts @@ -1,44 +1,43 @@ // 环境变量配置 + +// ============ 环境切换开关(修改这里即可切换环境)============ +// 可选值: 'development' | 'test' | 'production' +const CURRENT_ENV = 'production' as const +// =========================================================== + export const ENV_CONFIG = { // 开发环境 development: { - API_BASE_URL: 'http://127.0.0.1:9200/api', - // API_BASE_URL: 'https://glt-api2.websoft.top/api', + API_BASE_URL: 'https://glt-dev-api.websoft.top/api', + SERVER_API_URL: 'https://glt-dev-server.websoft.top/api', APP_NAME: '开发环境', DEBUG: 'true', }, + // 测试环境 + test: { + API_BASE_URL: 'https://glt-dev-api.websoft.top/api', + SERVER_API_URL: 'https://glt-dev-server.websoft.top/api', + APP_NAME: '测试环境', + DEBUG: 'true', + }, // 生产环境 production: { - API_BASE_URL: 'https://glt-api2.websoft.top/api', + API_BASE_URL: 'https://glt-api.websoft.top/api', + SERVER_API_URL: 'https://glt-server.websoft.top/api', APP_NAME: '桂乐淘', DEBUG: 'false', }, - // 测试环境 - test: { - // API_BASE_URL: 'http://127.0.0.1:9200/api', - API_BASE_URL: 'https://glt-api2.websoft.top/api', - APP_NAME: '测试环境', - DEBUG: 'true', - } } // 获取当前环境配置 export function getEnvConfig() { - const env = process.env.NODE_ENV || 'development' - if (env === 'production') { - return ENV_CONFIG.production - } else { // @ts-ignore - if (env === 'test') { - return ENV_CONFIG.test - } else { - return ENV_CONFIG.development - } - } + return ENV_CONFIG[CURRENT_ENV] } // 导出环境变量 export const { API_BASE_URL, + SERVER_API_URL, APP_NAME, DEBUG } = getEnvConfig() diff --git a/src/dealer/index.tsx b/src/dealer/index.tsx index ca1f6d7..17c6a35 100644 --- a/src/dealer/index.tsx +++ b/src/dealer/index.tsx @@ -10,8 +10,10 @@ import { People } from '@nutui/icons-react-taro' import {useDealerUser} from '@/hooks/useDealerUser' +import {useUser} from '@/hooks/useUser' import { useThemeStyles } from '@/hooks/useTheme' import {businessGradients, cardGradients, gradientUtils} from '@/styles/gradients' +import {updateShopDealerUser} from '@/api/shop/shopDealerUser' import Taro from '@tarojs/taro' const DealerIndex: React.FC = () => { @@ -21,6 +23,9 @@ const DealerIndex: React.FC = () => { refresh, } = useDealerUser() + // 获取用户角色信息 + const { hasRole } = useUser() + // 使用主题样式 const themeStyles = useThemeStyles() @@ -55,6 +60,59 @@ const DealerIndex: React.FC = () => { console.log(getGradientBackground(),'getGradientBackground()') + // 判断是否是配送员 + const isRider = hasRole('rider') + + // 点击待使用金额 - 配送员专用:将冻结金额转入可提现 + const handleFreezeMoneyClick = async () => { + // 检查是否是配送员 + if (!isRider) { + return + } + + // 检查冻结金额是否为 0 + const freezeMoney = Number(dealerUser?.freezeMoney ?? 0) + if (freezeMoney <= 0) { + return + } + + // 弹出确认框 + Taro.showModal({ + title: '确认操作', + content: `确定要将 ¥${freezeMoney.toFixed(2)} 转入钱包吗?`, + confirmText: '确定', + cancelText: '取消', + success: async (res) => { + if (res.confirm) { + try { + Taro.showLoading({ title: '处理中...' }) + const currentMoney = Number(dealerUser?.money ?? 0) + await updateShopDealerUser({ + id: dealerUser?.id, + money: (currentMoney + freezeMoney).toFixed(2), + freezeMoney: '0.00' + }) + Taro.hideLoading() + Taro.showToast({ + title: '更新成功', + icon: 'success', + duration: 1500 + }) + // 刷新数据 + refresh() + } catch (error) { + Taro.hideLoading() + Taro.showToast({ + title: '更新失败', + icon: 'none', + duration: 1500 + }) + } + } + } + }) + } + if (error) { return ( @@ -140,13 +198,20 @@ const DealerIndex: React.FC = () => { 可提现 - + 0 ? 1 : 0.8 + }} + onClick={isRider && Number(dealerUser.freezeMoney ?? 0) > 0 ? handleFreezeMoneyClick : undefined} + > {formatMoney(dealerUser.freezeMoney)} - 待使用 + + {isRider && Number(dealerUser.freezeMoney ?? 0) > 0 ? '待使用' : '待使用'} + { const [openLoginByPhone, setOpenLoginByPhone] = useState(false) const [clickNum, setClickNum] = useState(0) diff --git a/src/rider/index.tsx b/src/rider/index.tsx index 744297d..901bb5a 100644 --- a/src/rider/index.tsx +++ b/src/rider/index.tsx @@ -11,8 +11,10 @@ import { Scan } from '@nutui/icons-react-taro' import {useDealerUser} from '@/hooks/useDealerUser' +import {useUser} from '@/hooks/useUser' import { useThemeStyles } from '@/hooks/useTheme' import {businessGradients, cardGradients, gradientUtils} from '@/styles/gradients' +import {updateShopDealerUser} from '@/api/shop/shopDealerUser' import Taro from '@tarojs/taro' const DealerIndex: React.FC = () => { @@ -22,6 +24,9 @@ const DealerIndex: React.FC = () => { refresh, } = useDealerUser() + // 获取用户角色信息 + const { hasRole } = useUser() + // 使用主题样式 const themeStyles = useThemeStyles() @@ -56,6 +61,59 @@ const DealerIndex: React.FC = () => { console.log(getGradientBackground(),'getGradientBackground()') + // 判断是否是配送员 + const isRider = hasRole('rider') + + // 点击待使用金额 - 配送员专用:将冻结金额转入可提现 + const handleFreezeMoneyClick = async () => { + // 检查是否是配送员 + if (!isRider) { + return + } + + // 检查冻结金额是否为 0 + const freezeMoney = Number(dealerUser?.freezeMoney ?? 0) + if (freezeMoney <= 0) { + return + } + + // 弹出确认框 + Taro.showModal({ + title: '确认操作', + content: `确定要将 ¥${freezeMoney.toFixed(2)} 转入钱包吗?`, + confirmText: '确定', + cancelText: '取消', + success: async (res) => { + if (res.confirm) { + try { + Taro.showLoading({ title: '处理中...' }) + const currentMoney = Number(dealerUser?.money ?? 0) + await updateShopDealerUser({ + id: dealerUser?.id, + money: (currentMoney + freezeMoney).toFixed(2), + freezeMoney: '0.00' + }) + Taro.hideLoading() + Taro.showToast({ + title: '更新成功', + icon: 'success', + duration: 1500 + }) + // 刷新数据 + refresh() + } catch (error) { + Taro.hideLoading() + Taro.showToast({ + title: '更新失败', + icon: 'none', + duration: 1500 + }) + } + } + } + }) + } + if (error) { return ( @@ -148,13 +206,20 @@ const DealerIndex: React.FC = () => { 本月配送佣金 - + 0 ? 1 : 0.8 + }} + onClick={isRider && Number(dealerUser.freezeMoney ?? 0) > 0 ? handleFreezeMoneyClick : undefined} + > {formatMoney(dealerUser.freezeMoney)} - 桶数 + + {isRider && Number(dealerUser.freezeMoney ?? 0) > 0 ? '待使用' : '待使用'} +