diff --git a/docs/ops/2026-02-10__admin__product-module-repaired-full.md b/docs/ops/2026-02-10__admin__product-module-repaired-full.md
new file mode 100644
index 00000000..c7c35b3c
--- /dev/null
+++ b/docs/ops/2026-02-10__admin__product-module-repaired-full.md
@@ -0,0 +1,41 @@
+# 商品模块全量修复与统计补全报告
+
+## 摘要
+本次对 Admin 商品模块进行了深度的端到端修复,重点解决了商品管理页面的搜索筛选失效、状态统计缺失以及商品统计页面的全量 Mock 问题。补齐了配套的后端 RPC 接口,并重构了前端 Service 与 UI 逻辑。
+
+## 修复范围
+
+### 1. 商品管理页 (Product Management)
+- **搜索功能真实化**:接入了分类选择器数据,绑定了搜索关键字,实现了按名称、分类、状态的联动查询。
+- **状态统计同步**:接入了各状态商品数量汇总 RPC,确保 Tab 上的“出售中”、“仓库中”等数量真实准确。
+- **交互完善**:补全了分页翻页逻辑、状态开关(上架/下架)以及逻辑删除(回收站)的操作反馈。
+
+### 2. 商品统计页 (Product Statistics)
+- **数据源迁移**:彻底移除硬编码的静态数组,将 KPI 卡片、ECharts 趋势图及排行表格全部对接真实 RPC 数据流。
+- **动态图表**:趋势图现在能反映真实的浏览量、访客数及支付金额变化。
+- **全维度排行**:商品排行表支持加购、收藏、订单数、支付额及转化率的综合展示。
+
+### 3. 商品分类页 (Classify)
+- **代码核对**:确认已符合 RPC 访问规范,支持树形结构的 CRUD 与状态管理。
+
+## 变更清单
+
+### 数据库 / RPC (SQL)
+- `docs/sql/30_rpc/product/rpc_admin_product_count_stats_v1.sql` (新增):商品状态汇总统计。
+- `docs/sql/30_rpc/product/rpc_admin_product_trend_v1.sql` (新增):商品营业趋势统计。
+- `docs/sql/30_rpc/product/rpc_admin_product_analytics_v1.sql` (升级):增强商品概况指标与全维度排行逻辑。
+
+### 前端代码
+- `services/admin/productService.uts`:补齐了 stats/trend/ranking/counts 等 fetch 方法。
+- `pages/mall/admin/product/product-management/index.uvue`:重构逻辑与模板绑定。
+- `pages/mall/admin/product/product-statistics/index.uvue`:重构数据加载与图表驱动逻辑。
+
+## 验证说明
+1. **数据库执行**:需依次执行 `docs/sql/30_rpc/product/` 下新增及修改的 SQL 脚本。
+2. **功能验证**:
+ - 进入商品管理:确认搜索栏分类可选,点击查询后列表及 Tab 数量能正确刷新。
+ - 进入商品统计:确认顶部 6 个指标不再是固定值,折线图与饼图有动态交互。
+
+## 关联规范
+- 遵循 `AGENT_PROJECT_SPEC.md` 关于 Admin 侧通过 RPC 访问数据的要求。
+- 遵循 SQL 分层归档规范。
diff --git a/docs/ops/2026-02-11__admin__finance-module-repaired-full.md b/docs/ops/2026-02-11__admin__finance-module-repaired-full.md
new file mode 100644
index 00000000..f3feb7e8
--- /dev/null
+++ b/docs/ops/2026-02-11__admin__finance-module-repaired-full.md
@@ -0,0 +1,48 @@
+# 财务模块全量修复与数据库构建报告
+
+## 摘要
+本次对 Admin 侧财务模块进行了深度的端到端修复,完成了核心财务表(提现、充值、流水)的数据库构建、行级安全策略(RLS)配置、管理端 RPC 接口补全,以及前端 5 个核心页面的全量重构。彻底解决了财务数据展示依赖 Mock 的问题。
+
+## 修复范围
+
+### 1. 数据库构建 (Schema & RLS)
+- **`ml_extract` (提现表)**:支持支付宝/微信/银行卡多渠道快照,补齐手续费、余额快照及审核流字段。
+- **`ml_user_recharge` (充值表)**:支持支付状态追踪、渠道类型及订单关联。
+- **`ml_user_bill` (资金流水表)**:统一收支原子日志,支持业务大类与细分类型筛选。
+- **RLS 策略**:为上述表配置了行级安全,确保普通用户仅能访问个人数据,Admin 侧通过 RPC 访问。
+
+### 2. RPC 接口升级 (SECURITY DEFINER)
+- **列表类**:补全了提现、充值、流水的管理端分页查询,支持复杂的名称/订单号/时间筛选。
+- **操作类**:补全了提现审核(通过/驳回)、充值审计逻辑。
+- **统计类**:
+ - `rpc_admin_finance_overview`:提供营业额、充值、提现等核心 KPI。
+ - `rpc_admin_finance_bill_summary`:支持日/周/月维度的收支聚合。
+
+### 3. 前端页面重构
+- **提现申请 (`withdrawal.uvue`)**:接入审核流逻辑,展示账号快照,实现实时统计更新。
+- **充值记录 (`recharge.uvue`)**:接入真实充值流水,对齐支付状态。
+- **资金流水 (`capital_flow.uvue`)**:接入原子流水展示,支持收支筛选。
+- **账单记录 (`bill.uvue`)**:基于周期聚合 RPC 实现动态账单切换。
+- **交易统计 (`transaction_stats.uvue`)**:接入真实 KPI 指标,动态驱动趋势折线图。
+
+## 变更清单
+
+### 数据库 SQL
+- `docs/sql/10_schema/finance/`:`ml_extract_v1.sql`, `ml_user_recharge_v1.sql`, `ml_user_bill_v1.sql`
+- `docs/sql/20_rls/finance/`:`ml_extract_rls_v1.sql`, `ml_user_recharge_rls_v1.sql`, `ml_user_bill_rls_v1.sql`
+- `docs/sql/30_rpc/finance/`:补齐了 `rpc_admin_finance_overview_v1.sql`, `rpc_admin_finance_bill_summary_v1.sql` 等共 7 个接口。
+
+### 前端代码
+- `services/admin/financeService.uts`:补全 DTO 结构与汇总统计方法。
+- `pages/mall/admin/finance/` 目录下 5 个 `.uvue` 文件的逻辑与 UI 重构。
+
+## 验证说明
+1. **数据库执行**:需依次执行 `10_schema` -> `20_rls` -> `30_rpc` 下的财务脚本。
+2. **功能验证**:
+ - 进入财务统计:确认营业额等指标不再是固定值。
+ - 提现审核:确认点击通过/驳回能真实联动数据库状态。
+ - 筛选/分页:确认所有财务列表的分页与日期筛选均真实生效。
+
+## 关联规范
+- 遵循 `AGENT_PROJECT_SPEC.md` 中关于 Admin 数据访问必须走 RPC 的要求。
+- 遵循 SQL 分层归档与版本管理规范。
diff --git a/docs/sql/10_schema/finance/ml_extract_v1.sql b/docs/sql/10_schema/finance/ml_extract_v1.sql
new file mode 100644
index 00000000..15f08dda
--- /dev/null
+++ b/docs/sql/10_schema/finance/ml_extract_v1.sql
@@ -0,0 +1,39 @@
+-- =====================================================================================
+-- Schema: 用户提现申请表
+-- 位置:docs/sql/10_schema/finance/
+-- 对象类型:Schema (DDL)
+-- 版本:v1
+-- 说明:管理用户发起的提现申请(佣金/余额),支持多种提现方式及快照信息
+-- =====================================================================================
+
+CREATE TABLE IF NOT EXISTS public.ml_extract (
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ uid UUID NOT NULL REFERENCES public.ak_users(id),
+
+ real_name TEXT NULL, -- 提现人姓名快照
+ extract_type TEXT NOT NULL, -- 提现方式: alipay, wechat, bank
+
+ -- 账号快照信息
+ alipay_code TEXT NULL, -- 支付宝账号
+ wechat_code TEXT NULL, -- 微信账号
+ bank_code TEXT NULL, -- 银行卡号
+ bank_address TEXT NULL, -- 开户行地址
+
+ extract_price DECIMAL(12,2) NOT NULL DEFAULT 0, -- 申请提现金额
+ service_fee DECIMAL(12,2) NOT NULL DEFAULT 0, -- 提现手续费
+ balance DECIMAL(12,2) NOT NULL DEFAULT 0, -- 提现时的余额快照
+
+ status SMALLINT NOT NULL DEFAULT 0, -- 状态: 0:待审核, 1:已通过, -1:已驳回
+ refusal_reason TEXT NULL, -- 驳回原因
+
+ admin_id UUID NULL REFERENCES public.ak_users(id), -- 审核人ID
+ payment_time TIMESTAMPTZ NULL, -- 打款/到账时间
+
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
+);
+
+-- 索引
+CREATE INDEX IF NOT EXISTS ml_extract_uid_idx ON public.ml_extract (uid);
+CREATE INDEX IF NOT EXISTS ml_extract_status_idx ON public.ml_extract (status);
+CREATE INDEX IF NOT EXISTS ml_extract_created_at_idx ON public.ml_extract (created_at DESC);
diff --git a/docs/sql/10_schema/finance/ml_invoices_v1.sql b/docs/sql/10_schema/finance/ml_invoices_v1.sql
new file mode 100644
index 00000000..0864fa0b
--- /dev/null
+++ b/docs/sql/10_schema/finance/ml_invoices_v1.sql
@@ -0,0 +1,36 @@
+-- =====================================================================================
+-- Schema: 发票管理表
+-- 位置:docs/sql/10_schema/finance/ml_invoices_v1.sql
+-- 对象类型:Schema (DDL)
+-- 版本:v1
+-- 说明:记录用户提交的开票申请及其处理状态
+-- =====================================================================================
+
+CREATE TABLE IF NOT EXISTS public.ml_invoices (
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ uid UUID NOT NULL REFERENCES public.ak_users(id),
+ order_no TEXT NOT NULL, -- 关联订单号
+
+ order_amount DECIMAL(12,2) NOT NULL, -- 订单金额
+
+ invoice_type SMALLINT NOT NULL DEFAULT 1, -- 1: 电子普通发票, 2: 增值税专用发票
+ header_type SMALLINT NOT NULL DEFAULT 1, -- 1: 个人, 2: 企业
+
+ header_name TEXT NOT NULL, -- 发票抬头
+ tax_id TEXT NULL, -- 企业税号
+
+ email TEXT NULL, -- 接收邮箱
+ remark TEXT NULL, -- 备注
+
+ status SMALLINT NOT NULL DEFAULT 0, -- 0: 待开票, 1: 已开票, -1: 已拒绝
+ refusal_reason TEXT NULL, -- 驳回原因
+ invoice_url TEXT NULL, -- 电子发票文件路径/URL
+
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
+);
+
+-- 索引
+CREATE INDEX IF NOT EXISTS ml_invoices_uid_idx ON public.ml_invoices (uid);
+CREATE INDEX IF NOT EXISTS ml_invoices_order_no_idx ON public.ml_invoices (order_no);
+CREATE INDEX IF NOT EXISTS ml_invoices_status_idx ON public.ml_invoices (status);
diff --git a/docs/sql/10_schema/finance/ml_user_bill_v1.sql b/docs/sql/10_schema/finance/ml_user_bill_v1.sql
new file mode 100644
index 00000000..f8442677
--- /dev/null
+++ b/docs/sql/10_schema/finance/ml_user_bill_v1.sql
@@ -0,0 +1,33 @@
+-- =====================================================================================
+-- Schema: 用户资金流水表
+-- 位置:docs/sql/10_schema/finance/
+-- 对象类型:Schema (DDL)
+-- 版本:v1
+-- 说明:记录用户余额、积分、佣金的所有增减流水(原子日志)
+-- =====================================================================================
+
+CREATE TABLE IF NOT EXISTS public.ml_user_bill (
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ uid UUID NOT NULL REFERENCES public.ak_users(id),
+
+ link_id TEXT NULL, -- 关联业务ID(订单号、提现ID、充值ID等)
+ pm SMALLINT NOT NULL DEFAULT 1, -- 0:支出, 1:收入
+
+ title TEXT NOT NULL, -- 流水标题(如:商品购买、充值、提现)
+ category TEXT NOT NULL, -- 业务大类(如:balance-余额, integral-积分, brokerage-佣金)
+ type TEXT NOT NULL, -- 业务子类型(如:recharge, extract, pay, refund, system_add, system_sub)
+
+ number DECIMAL(12,2) NOT NULL DEFAULT 0, -- 变动金额
+ balance DECIMAL(12,2) NOT NULL DEFAULT 0, -- 变动后的余额快照
+
+ mark TEXT NULL, -- 备注
+ status SMALLINT NOT NULL DEFAULT 1, -- 状态(1:有效, 0:无效/冲正)
+
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
+);
+
+-- 常用查询索引
+CREATE INDEX IF NOT EXISTS ml_user_bill_uid_idx ON public.ml_user_bill (uid);
+CREATE INDEX IF NOT EXISTS ml_user_bill_category_type_idx ON public.ml_user_bill (category, type);
+CREATE INDEX IF NOT EXISTS ml_user_bill_created_at_idx ON public.ml_user_bill (created_at DESC);
diff --git a/docs/sql/10_schema/finance/ml_user_recharge_v1.sql b/docs/sql/10_schema/finance/ml_user_recharge_v1.sql
new file mode 100644
index 00000000..490202e5
--- /dev/null
+++ b/docs/sql/10_schema/finance/ml_user_recharge_v1.sql
@@ -0,0 +1,32 @@
+-- =====================================================================================
+-- Schema: 用户充值记录表
+-- 位置:docs/sql/10_schema/finance/
+-- 对象类型:Schema (DDL)
+-- 版本:v1
+-- 说明:记录用户主动发起的充值申请及支付状态
+-- =====================================================================================
+
+CREATE TABLE IF NOT EXISTS public.ml_user_recharge (
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ uid UUID NOT NULL REFERENCES public.ak_users(id),
+
+ order_no TEXT UNIQUE NOT NULL, -- 充值订单号(cz开头)
+ recharge_type TEXT NOT NULL, -- 充值渠道: wechat, alipay, system (后台补单)
+
+ price DECIMAL(12,2) NOT NULL DEFAULT 0, -- 实际充值金额
+ give_price DECIMAL(12,2) NOT NULL DEFAULT 0, -- 赠送金额
+
+ paid SMALLINT NOT NULL DEFAULT 0, -- 支付状态: 0:未支付, 1:已支付
+ pay_time TIMESTAMPTZ NULL, -- 支付时间
+
+ channel_trade_no TEXT NULL, -- 外部渠道流水号
+ status SMALLINT NOT NULL DEFAULT 1, -- 记录状态: 1:正常, 0:逻辑删除
+
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
+);
+
+-- 索引
+CREATE INDEX IF NOT EXISTS ml_user_recharge_uid_idx ON public.ml_user_recharge (uid);
+CREATE INDEX IF NOT EXISTS ml_user_recharge_order_no_idx ON public.ml_user_recharge (order_no);
+CREATE INDEX IF NOT EXISTS ml_user_recharge_created_at_idx ON public.ml_user_recharge (created_at DESC);
diff --git a/docs/sql/20_rls/finance/ml_extract_rls_v1.sql b/docs/sql/20_rls/finance/ml_extract_rls_v1.sql
new file mode 100644
index 00000000..7831493f
--- /dev/null
+++ b/docs/sql/20_rls/finance/ml_extract_rls_v1.sql
@@ -0,0 +1,20 @@
+-- =====================================================================================
+-- RLS: 用户提现申请表
+-- 位置:docs/sql/20_rls/finance/
+-- 对象类型:RLS 策略
+-- 版本:v1
+-- 说明:仅允许用户查看自己的提现记录;管理端通过 RPC 访问
+-- =====================================================================================
+
+ALTER TABLE public.ml_extract ENABLE ROW LEVEL SECURITY;
+
+-- 策略 1: 允许用户读取自己的提现申请
+DROP POLICY IF EXISTS ml_extract_user_select ON public.ml_extract;
+CREATE POLICY ml_extract_user_select
+ ON public.ml_extract
+ FOR SELECT
+ TO authenticated
+ USING (uid = auth.uid());
+
+-- 默认不开放 INSERT/UPDATE/DELETE 给普通用户
+-- 提现申请通常由特定的 RPC 函数 (security definer) 创建,以确保业务逻辑(如冻结余额)的原子性
diff --git a/docs/sql/20_rls/finance/ml_invoices_rls_v1.sql b/docs/sql/20_rls/finance/ml_invoices_rls_v1.sql
new file mode 100644
index 00000000..e2418cf0
--- /dev/null
+++ b/docs/sql/20_rls/finance/ml_invoices_rls_v1.sql
@@ -0,0 +1,19 @@
+-- =====================================================================================
+-- RLS: 发票管理表
+-- 位置:docs/sql/20_rls/finance/ml_invoices_rls_v1.sql
+-- 对象类型:RLS 策略
+-- 版本:v1
+-- 说明:用户仅能查看自己的开票申请;管理端通过 RPC 访问
+-- =====================================================================================
+
+ALTER TABLE public.ml_invoices ENABLE ROW LEVEL SECURITY;
+
+-- 策略 1: 允许用户读取自己的记录
+DROP POLICY IF EXISTS ml_invoices_user_select ON public.ml_invoices;
+CREATE POLICY ml_invoices_user_select
+ ON public.ml_invoices
+ FOR SELECT
+ TO authenticated
+ USING (uid = auth.uid());
+
+-- 默认不开放 INSERT/UPDATE/DELETE 给普通用户,通常由 RPC 或支付后逻辑触发
diff --git a/docs/sql/20_rls/finance/ml_user_bill_rls_v1.sql b/docs/sql/20_rls/finance/ml_user_bill_rls_v1.sql
new file mode 100644
index 00000000..c629fec9
--- /dev/null
+++ b/docs/sql/20_rls/finance/ml_user_bill_rls_v1.sql
@@ -0,0 +1,19 @@
+-- =====================================================================================
+-- RLS: 用户资金流水表
+-- 位置:docs/sql/20_rls/finance/
+-- 对象类型:RLS 策略
+-- 版本:v1
+-- 说明:仅允许用户查看自己的流水记录;管理端通过 RPC 访问
+-- =====================================================================================
+
+ALTER TABLE public.ml_user_bill ENABLE ROW LEVEL SECURITY;
+
+-- 策略 1: 允许用户读取自己的记录
+DROP POLICY IF EXISTS ml_user_bill_user_select ON public.ml_user_bill;
+CREATE POLICY ml_user_bill_user_select
+ ON public.ml_user_bill
+ FOR SELECT
+ TO authenticated
+ USING (uid = auth.uid());
+
+-- 默认不开放 INSERT/UPDATE/DELETE 给普通用户,由后端逻辑或 RPC 触发
diff --git a/docs/sql/20_rls/finance/ml_user_recharge_rls_v1.sql b/docs/sql/20_rls/finance/ml_user_recharge_rls_v1.sql
new file mode 100644
index 00000000..6ba7eaa9
--- /dev/null
+++ b/docs/sql/20_rls/finance/ml_user_recharge_rls_v1.sql
@@ -0,0 +1,19 @@
+-- =====================================================================================
+-- RLS: 用户充值记录表
+-- 位置:docs/sql/20_rls/finance/
+-- 对象类型:RLS 策略
+-- 版本:v1
+-- 说明:仅允许用户查看自己的充值记录;管理端通过 RPC 访问
+-- =====================================================================================
+
+ALTER TABLE public.ml_user_recharge ENABLE ROW LEVEL SECURITY;
+
+-- 策略 1: 允许用户读取自己的记录
+DROP POLICY IF EXISTS ml_user_recharge_user_select ON public.ml_user_recharge;
+CREATE POLICY ml_user_recharge_user_select
+ ON public.ml_user_recharge
+ FOR SELECT
+ TO authenticated
+ USING (uid = auth.uid());
+
+-- 默认不开放 INSERT/UPDATE/DELETE 给普通用户,写操作通常由业务逻辑或支付回调触发
diff --git a/docs/sql/30_rpc/finance/rpc_admin_balance_distribution_v1.sql b/docs/sql/30_rpc/finance/rpc_admin_balance_distribution_v1.sql
new file mode 100644
index 00000000..f8776fc9
--- /dev/null
+++ b/docs/sql/30_rpc/finance/rpc_admin_balance_distribution_v1.sql
@@ -0,0 +1,78 @@
+-- =====================================================================================
+-- Admin 财务统计 - 余额收支分布统计 RPC
+-- 位置:docs/sql/30_rpc/finance/
+-- 对象类型:RPC 函数(SECURITY DEFINER)
+-- 版本:v1
+-- 说明:按业务子类型统计指定时间范围内的余额收入与支出分布
+-- =====================================================================================
+
+CREATE OR REPLACE FUNCTION public.rpc_admin_balance_distribution(
+ p_start_time TIMESTAMP WITH TIME ZONE,
+ p_end_time TIMESTAMP WITH TIME ZONE
+)
+RETURNS JSONB
+SECURITY DEFINER
+SET search_path = public
+LANGUAGE plpgsql
+AS $$
+DECLARE
+ v_total_income DECIMAL(12,2);
+ v_total_expense DECIMAL(12,2);
+ v_income_items JSONB;
+ v_expense_items JSONB;
+BEGIN
+ -- 1. 权限检查
+ IF NOT EXISTS (
+ SELECT 1 FROM public.ak_users
+ WHERE id = auth.uid() AND role IN ('admin', 'analytics')
+ ) THEN
+ RAISE EXCEPTION 'Permission denied';
+ END IF;
+
+ -- 2. 计算总收入与总支出
+ SELECT
+ COALESCE(SUM(number) FILTER (WHERE pm = 1), 0),
+ COALESCE(SUM(number) FILTER (WHERE pm = 0), 0)
+ INTO v_total_income, v_total_expense
+ FROM public.ml_user_bill
+ WHERE category = 'balance'
+ AND created_at >= p_start_time
+ AND created_at <= p_end_time
+ AND status = 1;
+
+ -- 3. 统计收入分布 (来源分析)
+ SELECT jsonb_agg(t) INTO v_income_items
+ FROM (
+ SELECT
+ type AS name,
+ SUM(number) AS value,
+ CASE WHEN v_total_income > 0 THEN ROUND(SUM(number) / v_total_income * 100, 2) ELSE 0 END AS percent
+ FROM public.ml_user_bill
+ WHERE category = 'balance' AND pm = 1 AND status = 1
+ AND created_at >= p_start_time AND created_at <= p_end_time
+ GROUP BY type
+ ORDER BY value DESC
+ ) t;
+
+ -- 4. 统计支出分布 (消耗分析)
+ SELECT jsonb_agg(t) INTO v_expense_items
+ FROM (
+ SELECT
+ type AS name,
+ SUM(number) AS value,
+ CASE WHEN v_total_expense > 0 THEN ROUND(SUM(number) / v_total_expense * 100, 2) ELSE 0 END AS percent
+ FROM public.ml_user_bill
+ WHERE category = 'balance' AND pm = 0 AND status = 1
+ AND created_at >= p_start_time AND created_at <= p_end_time
+ GROUP BY type
+ ORDER BY value DESC
+ ) t;
+
+ RETURN jsonb_build_object(
+ 'income', COALESCE(v_income_items, '[]'::jsonb),
+ 'expense', COALESCE(v_expense_items, '[]'::jsonb)
+ );
+END;
+$$;
+
+COMMENT ON FUNCTION public.rpc_admin_balance_distribution IS '统计财务余额收支来源与消耗分布';
diff --git a/docs/sql/30_rpc/finance/rpc_admin_balance_stats_v1.sql b/docs/sql/30_rpc/finance/rpc_admin_balance_stats_v1.sql
new file mode 100644
index 00000000..23b9eb40
--- /dev/null
+++ b/docs/sql/30_rpc/finance/rpc_admin_balance_stats_v1.sql
@@ -0,0 +1,48 @@
+-- =====================================================================================
+-- Admin 财务统计 - 余额核心指标 RPC
+-- 位置:docs/sql/30_rpc/finance/
+-- 对象类型:RPC 函数(SECURITY DEFINER)
+-- 版本:v1
+-- 说明:获取全站当前余额存量、累计增加总额及累计消耗总额
+-- =====================================================================================
+
+CREATE OR REPLACE FUNCTION public.rpc_admin_balance_stats()
+RETURNS JSONB
+SECURITY DEFINER
+SET search_path = public
+LANGUAGE plpgsql
+AS $$
+DECLARE
+ v_current_balance DECIMAL(12,2);
+ v_total_accumulation DECIMAL(12,2);
+ v_total_consumption DECIMAL(12,2);
+BEGIN
+ -- 1. 权限检查
+ IF NOT EXISTS (
+ SELECT 1 FROM public.ak_users
+ WHERE id = auth.uid() AND role IN ('admin', 'analytics')
+ ) THEN
+ RAISE EXCEPTION 'Permission denied';
+ END IF;
+
+ -- 2. 统计当前全站用户余额总存量
+ SELECT COALESCE(SUM(now_money), 0) INTO v_current_balance FROM public.ak_users;
+
+ -- 3. 统计累计增加 (pm=1) 和 累计消耗 (pm=0)
+ -- 基于 ml_user_bill 表中 category='balance' 的记录
+ SELECT
+ COALESCE(SUM(number) FILTER (WHERE pm = 1), 0),
+ COALESCE(SUM(number) FILTER (WHERE pm = 0), 0)
+ INTO v_total_accumulation, v_total_consumption
+ FROM public.ml_user_bill
+ WHERE category = 'balance' AND status = 1;
+
+ RETURN jsonb_build_object(
+ 'current_balance', v_current_balance,
+ 'total_accumulation', v_total_accumulation,
+ 'total_consumption', v_total_consumption
+ );
+END;
+$$;
+
+COMMENT ON FUNCTION public.rpc_admin_balance_stats IS '获取全站余额存量及累计收支汇总';
diff --git a/docs/sql/30_rpc/finance/rpc_admin_balance_trend_v1.sql b/docs/sql/30_rpc/finance/rpc_admin_balance_trend_v1.sql
new file mode 100644
index 00000000..7e627578
--- /dev/null
+++ b/docs/sql/30_rpc/finance/rpc_admin_balance_trend_v1.sql
@@ -0,0 +1,46 @@
+-- =====================================================================================
+-- Admin 财务统计 - 余额收支趋势 RPC
+-- 位置:docs/sql/30_rpc/finance/
+-- 对象类型:RPC 函数(SECURITY DEFINER)
+-- 版本:v1
+-- 说明:按日聚合指定时间范围内的余额积累 (pm=1) 与 余额消耗 (pm=0) 趋势
+-- =====================================================================================
+
+CREATE OR REPLACE FUNCTION public.rpc_admin_balance_trend(
+ p_start_time TIMESTAMP WITH TIME ZONE,
+ p_end_time TIMESTAMP WITH TIME ZONE
+)
+RETURNS JSONB
+SECURITY DEFINER
+SET search_path = public
+LANGUAGE plpgsql
+AS $$
+DECLARE
+ v_items JSONB;
+BEGIN
+ -- 1. 权限检查
+ IF NOT EXISTS (
+ SELECT 1 FROM public.ak_users
+ WHERE id = auth.uid() AND role IN ('admin', 'analytics')
+ ) THEN
+ RAISE EXCEPTION 'Permission denied';
+ END IF;
+
+ -- 2. 按日聚合统计
+ SELECT jsonb_agg(t) INTO v_items
+ FROM (
+ SELECT
+ to_char(date_trunc('day', gs.day), 'YYYY-MM-DD') AS date_group,
+ COALESCE(SUM(number) FILTER (WHERE pm = 1 AND category = 'balance'), 0) AS accumulation,
+ COALESCE(SUM(number) FILTER (WHERE pm = 0 AND category = 'balance'), 0) AS consumption
+ FROM generate_series(date_trunc('day', p_start_time), date_trunc('day', p_end_time), '1 day'::interval) gs(day)
+ LEFT JOIN public.ml_user_bill b ON date_trunc('day', b.created_at) = gs.day AND b.status = 1
+ GROUP BY gs.day
+ ORDER BY gs.day ASC
+ ) t;
+
+ RETURN COALESCE(v_items, '[]'::jsonb);
+END;
+$$;
+
+COMMENT ON FUNCTION public.rpc_admin_balance_trend IS '按日聚合财务余额收支趋势';
diff --git a/docs/sql/30_rpc/finance/rpc_admin_finance_bill_summary_v1.sql b/docs/sql/30_rpc/finance/rpc_admin_finance_bill_summary_v1.sql
new file mode 100644
index 00000000..f633f5c6
--- /dev/null
+++ b/docs/sql/30_rpc/finance/rpc_admin_finance_bill_summary_v1.sql
@@ -0,0 +1,56 @@
+-- =====================================================================================
+-- Admin 财务功能 - 账单汇总统计 RPC
+-- 位置:docs/sql/30_rpc/finance/
+-- 对象类型:RPC 函数(SECURITY DEFINER)
+-- 版本:v1
+-- 说明:按日/周/月维度聚合财务收支数据,支撑账单列表展示
+-- =====================================================================================
+
+CREATE OR REPLACE FUNCTION public.rpc_admin_finance_bill_summary(
+ p_start_time TIMESTAMP WITH TIME ZONE,
+ p_end_time TIMESTAMP WITH TIME ZONE,
+ p_interval TEXT DEFAULT 'day' -- day, week, month
+)
+RETURNS JSONB
+SECURITY DEFINER
+SET search_path = public
+LANGUAGE plpgsql
+AS $$
+DECLARE
+ v_items JSONB;
+BEGIN
+ -- 1. 权限检查
+ IF NOT EXISTS (
+ SELECT 1 FROM public.ak_users
+ WHERE id = auth.uid() AND role IN ('admin', 'analytics')
+ ) THEN
+ RAISE EXCEPTION 'Permission denied';
+ END IF;
+
+ -- 2. 聚合统计
+ SELECT jsonb_agg(t) INTO v_items
+ FROM (
+ SELECT
+ to_char(date_trunc(p_interval, created_at),
+ CASE
+ WHEN p_interval = 'day' THEN 'YYYY-MM-DD'
+ WHEN p_interval = 'week' THEN 'IYYY-IW'
+ ELSE 'YYYY-MM'
+ END
+ ) AS date_group,
+ SUM(number) FILTER (WHERE pm = 1) AS income,
+ SUM(number) FILTER (WHERE pm = 0) AS expense,
+ SUM(CASE WHEN pm = 1 THEN number ELSE -number END) AS net_entry
+ FROM public.ml_user_bill
+ WHERE created_at >= p_start_time
+ AND created_at <= p_end_time
+ AND status = 1
+ GROUP BY date_trunc(p_interval, created_at)
+ ORDER BY date_trunc(p_interval, created_at) DESC
+ ) t;
+
+ RETURN COALESCE(v_items, '[]'::jsonb);
+END;
+$$;
+
+COMMENT ON FUNCTION public.rpc_admin_finance_bill_summary IS '按周期聚合财务收支账单';
diff --git a/docs/sql/30_rpc/finance/rpc_admin_finance_overview_v1.sql b/docs/sql/30_rpc/finance/rpc_admin_finance_overview_v1.sql
new file mode 100644
index 00000000..d3109c3b
--- /dev/null
+++ b/docs/sql/30_rpc/finance/rpc_admin_finance_overview_v1.sql
@@ -0,0 +1,72 @@
+-- =====================================================================================
+-- Admin 财务功能 - 财务概况统计 RPC
+-- 位置:docs/sql/30_rpc/finance/
+-- 对象类型:RPC 函数(SECURITY DEFINER)
+-- 版本:v1
+-- 说明:获取指定时间段内的财务核心 KPI(营业额、充值汇总、提现汇总、资金存量)
+-- =====================================================================================
+
+CREATE OR REPLACE FUNCTION public.rpc_admin_finance_overview(
+ p_start_time TIMESTAMP WITH TIME ZONE,
+ p_end_time TIMESTAMP WITH TIME ZONE
+)
+RETURNS JSONB
+SECURITY DEFINER
+SET search_path = public
+LANGUAGE plpgsql
+AS $$
+DECLARE
+ v_recharge_amount DECIMAL(12,2);
+ v_recharge_count BIGINT;
+ v_extract_amount DECIMAL(12,2);
+ v_extract_count BIGINT;
+ v_total_user_balance DECIMAL(12,2);
+ v_total_user_brokerage DECIMAL(12,2);
+BEGIN
+ -- 1. 权限检查
+ IF NOT EXISTS (
+ SELECT 1 FROM public.ak_users
+ WHERE id = auth.uid() AND role IN ('admin', 'analytics')
+ ) THEN
+ RAISE EXCEPTION 'Permission denied';
+ END IF;
+
+ -- 2. 统计充值 (仅统计已支付)
+ SELECT
+ COALESCE(SUM(price + give_price), 0),
+ COUNT(*)
+ INTO v_recharge_amount, v_recharge_count
+ FROM public.ml_user_recharge
+ WHERE paid = 1
+ AND created_at >= p_start_time
+ AND created_at <= p_end_time;
+
+ -- 3. 统计提现 (仅统计已通过)
+ SELECT
+ COALESCE(SUM(extract_price), 0),
+ COUNT(*)
+ INTO v_extract_amount, v_extract_count
+ FROM public.ml_extract
+ WHERE status = 1
+ AND created_at >= p_start_time
+ AND created_at <= p_end_time;
+
+ -- 4. 统计全站资金存量 (实时快照)
+ SELECT
+ COALESCE(SUM(now_money), 0),
+ COALESCE(SUM(brokerage_price), 0)
+ INTO v_total_user_balance, v_total_user_brokerage
+ FROM public.ak_users;
+
+ RETURN jsonb_build_object(
+ 'recharge_amount', v_recharge_amount,
+ 'recharge_count', v_recharge_count,
+ 'extract_amount', v_extract_amount,
+ 'extract_count', v_extract_count,
+ 'total_user_balance', v_total_user_balance,
+ 'total_user_brokerage', v_total_user_brokerage
+ );
+END;
+$$;
+
+COMMENT ON FUNCTION public.rpc_admin_finance_overview IS '财务核心 KPI 概况统计';
diff --git a/docs/sql/30_rpc/finance/rpc_admin_invoice_list_v1.sql b/docs/sql/30_rpc/finance/rpc_admin_invoice_list_v1.sql
new file mode 100644
index 00000000..0915a8a5
--- /dev/null
+++ b/docs/sql/30_rpc/finance/rpc_admin_invoice_list_v1.sql
@@ -0,0 +1,93 @@
+-- =====================================================================================
+-- RPC: rpc_admin_invoice_list
+-- 位置:docs/sql/30_rpc/finance/
+-- 对象类型:RPC 函数 (SECURITY DEFINER)
+-- 版本:v1
+-- 说明:管理端分页获取发票申请列表,支持搜索、状态筛选及时间过滤
+-- =====================================================================================
+
+CREATE OR REPLACE FUNCTION public.rpc_admin_invoice_list(
+ p_page INTEGER DEFAULT 1,
+ p_page_size INTEGER DEFAULT 15,
+ p_status SMALLINT DEFAULT NULL,
+ p_start_time TIMESTAMP WITH TIME ZONE DEFAULT NULL,
+ p_end_time TIMESTAMP WITH TIME ZONE DEFAULT NULL,
+ p_search TEXT DEFAULT NULL
+)
+RETURNS JSONB
+SECURITY DEFINER
+SET search_path = public
+LANGUAGE plpgsql
+AS $$
+DECLARE
+ v_offset INTEGER;
+ v_total BIGINT;
+ v_items JSONB;
+BEGIN
+ -- 1. 权限检查
+ IF NOT EXISTS (
+ SELECT 1 FROM public.ak_users
+ WHERE id = auth.uid() AND role IN ('admin', 'analytics')
+ ) THEN
+ RAISE EXCEPTION 'Permission denied';
+ END IF;
+
+ v_offset := (p_page - 1) * p_page_size;
+
+ -- 2. 获取总数
+ SELECT COUNT(*) INTO v_total
+ FROM public.ml_invoices i
+ LEFT JOIN public.ak_users u ON u.id = i.uid
+ WHERE (p_status IS NULL OR i.status = p_status)
+ AND (p_start_time IS NULL OR i.created_at >= p_start_time)
+ AND (p_end_time IS NULL OR i.created_at <= p_end_time)
+ AND (p_search IS NULL OR (
+ i.order_no ILIKE '%' || p_search || '%' OR
+ i.header_name ILIKE '%' || p_search || '%' OR
+ u.username ILIKE '%' || p_search || '%'
+ ));
+
+ -- 3. 获取明细数据
+ SELECT jsonb_agg(t) INTO v_items
+ FROM (
+ SELECT
+ i.id,
+ i.uid,
+ i.order_no,
+ i.order_amount,
+ i.invoice_type,
+ i.header_type,
+ i.header_name,
+ i.tax_id,
+ i.email,
+ i.remark,
+ i.status,
+ i.refusal_reason,
+ i.invoice_url,
+ i.created_at,
+ i.updated_at,
+ u.username as user_name,
+ u.email as user_email
+ FROM public.ml_invoices i
+ LEFT JOIN public.ak_users u ON u.id = i.uid
+ WHERE (p_status IS NULL OR i.status = p_status)
+ AND (p_start_time IS NULL OR i.created_at >= p_start_time)
+ AND (p_end_time IS NULL OR i.created_at <= p_end_time)
+ AND (p_search IS NULL OR (
+ i.order_no ILIKE '%' || p_search || '%' OR
+ i.header_name ILIKE '%' || p_search || '%' OR
+ u.username ILIKE '%' || p_search || '%'
+ ))
+ ORDER BY i.created_at DESC
+ LIMIT p_page_size
+ OFFSET v_offset
+ ) t;
+
+ RETURN jsonb_build_object(
+ 'total', v_total,
+ 'items', COALESCE(v_items, '[]'::jsonb)
+ );
+END;
+$$;
+
+COMMENT ON FUNCTION public.rpc_admin_invoice_list IS '管理员分页查询发票申请列表';
diff --git a/docs/sql/30_rpc/finance/rpc_admin_invoice_process_v1.sql b/docs/sql/30_rpc/finance/rpc_admin_invoice_process_v1.sql
new file mode 100644
index 00000000..29d48a69
--- /dev/null
+++ b/docs/sql/30_rpc/finance/rpc_admin_invoice_process_v1.sql
@@ -0,0 +1,45 @@
+-- =====================================================================================
+-- RPC: rpc_admin_invoice_process
+-- 位置:docs/sql/30_rpc/finance/
+-- 对象类型:RPC 函数 (SECURITY DEFINER)
+-- 版本:v1
+-- 说明:管理端处理发票申请(开票或驳回)
+-- =====================================================================================
+
+CREATE OR REPLACE FUNCTION public.rpc_admin_invoice_process(
+ p_id UUID,
+ p_status SMALLINT, -- 1: 已开票, -1: 已拒绝
+ p_invoice_url TEXT DEFAULT NULL,
+ p_refusal_reason TEXT DEFAULT NULL
+)
+RETURNS BOOLEAN
+SECURITY DEFINER
+SET search_path = public
+LANGUAGE plpgsql
+AS $$
+DECLARE
+ v_ok BOOLEAN;
+BEGIN
+ -- 1. 权限检查
+ IF NOT EXISTS (
+ SELECT 1 FROM public.ak_users
+ WHERE id = auth.uid() AND role IN ('admin', 'analytics')
+ ) THEN
+ RAISE EXCEPTION 'Permission denied';
+ END IF;
+
+ -- 2. 更新状态
+ UPDATE public.ml_invoices
+ SET
+ status = p_status,
+ invoice_url = CASE WHEN p_status = 1 THEN p_invoice_url ELSE invoice_url END,
+ refusal_reason = CASE WHEN p_status = -1 THEN p_refusal_reason ELSE refusal_reason END,
+ updated_at = now()
+ WHERE id = p_id;
+
+ GET DIAGNOSTICS v_ok = ROW_COUNT;
+ RETURN v_ok;
+END;
+$$;
+
+COMMENT ON FUNCTION public.rpc_admin_invoice_process IS '管理员处理发票开票申请';
diff --git a/docs/sql/30_rpc/product/rpc_admin_product_analytics_v1.sql b/docs/sql/30_rpc/product/rpc_admin_product_analytics_v1.sql
index 270819a9..80d4ed4e 100644
--- a/docs/sql/30_rpc/product/rpc_admin_product_analytics_v1.sql
+++ b/docs/sql/30_rpc/product/rpc_admin_product_analytics_v1.sql
@@ -48,7 +48,7 @@ BEGIN
'refund_amount', refund_amount
) INTO v_stats FROM stats;
- RETURN v_stats;
+ RETURN v_stats;
END;
$$;
@@ -86,17 +86,29 @@ BEGIN
p.main_image_url as image,
COALESCE(p.view_count, 0) as views,
(SELECT COUNT(DISTINCT user_id) FROM public.ml_browse_history bh WHERE bh.product_id = p.id AND bh.created_at BETWEEN p_start_time AND p_end_time) as visitors,
- (SELECT COALESCE(SUM(quantity), 0) FROM public.ml_order_items oi JOIN public.ml_orders o ON oi.order_id = o.id
- WHERE oi.product_id = p.id AND o.created_at BETWEEN p_start_time AND p_end_time AND o.order_status NOT IN (1, 5)) as sales,
+ (SELECT COALESCE(SUM(quantity), 0) FROM public.ml_shopping_cart sc WHERE sc.product_id = p.id AND sc.created_at BETWEEN p_start_time AND p_end_time) as cart_count,
+ (SELECT COUNT(DISTINCT o.id) FROM public.ml_orders o JOIN public.ml_order_items oi ON o.id = oi.order_id
+ WHERE oi.product_id = p.id AND o.created_at BETWEEN p_start_time AND p_end_time) as order_count,
+ (SELECT COALESCE(SUM(oi.quantity), 0) FROM public.ml_order_items oi JOIN public.ml_orders o ON oi.order_id = o.id
+ WHERE oi.product_id = p.id AND o.created_at BETWEEN p_start_time AND p_end_time AND o.order_status NOT IN (1, 5)) as pay_count,
(SELECT COALESCE(SUM(oi.total_amount), 0) FROM public.ml_order_items oi JOIN public.ml_orders o ON oi.order_id = o.id
- WHERE oi.product_id = p.id AND o.created_at BETWEEN p_start_time AND p_end_time AND o.order_status NOT IN (1, 5)) as amount
+ WHERE oi.product_id = p.id AND o.created_at BETWEEN p_start_time AND p_end_time AND o.order_status NOT IN (1, 5)) as pay_amount,
+ (SELECT COUNT(*) FROM public.ml_user_favorites f WHERE f.target_id = p.id AND f.target_type = 1 AND f.created_at BETWEEN p_start_time AND p_end_time) as fav_count
FROM public.ml_products p
WHERE p.status != 4
ORDER BY
- CASE WHEN p_sort_by = 'views' THEN 4
- WHEN p_sort_by = 'sales' THEN 6
- WHEN p_sort_by = 'amount' THEN 7
- ELSE 6 END DESC
+ CASE
+ WHEN p_sort_by = 'views' THEN COALESCE(p.view_count, 0)
+ WHEN p_sort_by = 'sales' THEN (
+ SELECT COALESCE(SUM(oi.quantity), 0) FROM public.ml_order_items oi JOIN public.ml_orders o ON oi.order_id = o.id
+ WHERE oi.product_id = p.id AND o.created_at BETWEEN p_start_time AND p_end_time AND o.order_status NOT IN (1, 5)
+ )
+ WHEN p_sort_by = 'amount' THEN (
+ SELECT COALESCE(SUM(oi.total_amount), 0) FROM public.ml_order_items oi JOIN public.ml_orders o ON oi.order_id = o.id
+ WHERE oi.product_id = p.id AND o.created_at BETWEEN p_start_time AND p_end_time AND o.order_status NOT IN (1, 5)
+ )
+ ELSE COALESCE(p.view_count, 0)
+ END DESC
LIMIT p_limit
) t;
diff --git a/docs/sql/30_rpc/product/rpc_admin_product_count_stats_v1.sql b/docs/sql/30_rpc/product/rpc_admin_product_count_stats_v1.sql
new file mode 100644
index 00000000..bf6e2d8d
--- /dev/null
+++ b/docs/sql/30_rpc/product/rpc_admin_product_count_stats_v1.sql
@@ -0,0 +1,38 @@
+-- =====================================================================================
+-- Admin 商品管理 - 商品状态汇总统计 RPC
+-- 位置:docs/sql/30_rpc/product/
+-- 对象类型:RPC 函数(SECURITY DEFINER)
+-- 版本:v1
+-- 说明:统计出售中、仓库中、草稿箱、回收站各状态的商品数量
+-- =====================================================================================
+
+CREATE OR REPLACE FUNCTION public.rpc_admin_product_count_stats()
+RETURNS JSONB
+SECURITY DEFINER
+SET search_path = public
+LANGUAGE plpgsql
+AS $$
+DECLARE
+ v_result JSONB;
+BEGIN
+ -- 1. 权限检查
+ IF NOT EXISTS (
+ SELECT 1 FROM public.ak_users
+ WHERE auth_id = auth.uid() AND role IN ('admin', 'analytics')
+ ) THEN
+ RAISE EXCEPTION 'Permission denied';
+ END IF;
+
+ -- 2. 统计各状态数量
+ -- status 定义:1:上架(出售中), 2:下架(仓库中), 3:草稿, 4:逻辑删除(回收站)
+ SELECT jsonb_build_object(
+ 'selling', COUNT(*) FILTER (WHERE status = 1),
+ 'warehouse', COUNT(*) FILTER (WHERE status = 2),
+ 'draft', COUNT(*) FILTER (WHERE status = 3),
+ 'recycle', COUNT(*) FILTER (WHERE status = 4)
+ ) INTO v_result
+ FROM public.ml_products;
+
+ RETURN v_result;
+END;
+$$;
diff --git a/docs/sql/30_rpc/product/rpc_admin_product_trend_v1.sql b/docs/sql/30_rpc/product/rpc_admin_product_trend_v1.sql
new file mode 100644
index 00000000..5ad2c9e2
--- /dev/null
+++ b/docs/sql/30_rpc/product/rpc_admin_product_trend_v1.sql
@@ -0,0 +1,44 @@
+-- =====================================================================================
+-- Admin 商品统计 - 营业趋势统计 RPC
+-- 位置:docs/sql/30_rpc/product/
+-- 对象类型:RPC 函数(SECURITY DEFINER)
+-- 版本:v1
+-- 说明:按天聚合指定时间范围内的商品浏览量、访客量、支付金额及退款金额
+-- =====================================================================================
+
+CREATE OR REPLACE FUNCTION public.rpc_admin_product_trend(
+ p_start_time TIMESTAMP WITH TIME ZONE,
+ p_end_time TIMESTAMP WITH TIME ZONE
+)
+RETURNS JSONB
+SECURITY DEFINER
+SET search_path = public
+LANGUAGE plpgsql
+AS $$
+DECLARE
+ v_items JSONB;
+BEGIN
+ -- 1. 权限检查
+ IF NOT EXISTS (
+ SELECT 1 FROM public.ak_users
+ WHERE auth_id = auth.uid() AND role IN ('admin', 'analytics')
+ ) THEN
+ RAISE EXCEPTION 'Permission denied';
+ END IF;
+
+ -- 2. 按日聚合统计
+ SELECT jsonb_agg(t) INTO v_items
+ FROM (
+ SELECT
+ to_char(date_trunc('day', gs.day), 'YYYY-MM-DD') AS date_group,
+ (SELECT COUNT(*) FROM public.ml_browse_history bh WHERE date_trunc('day', bh.created_at) = gs.day) as views,
+ (SELECT COUNT(DISTINCT user_id) FROM public.ml_browse_history bh WHERE date_trunc('day', bh.created_at) = gs.day) as visitors,
+ (SELECT COALESCE(SUM(total_amount), 0) FROM public.ml_orders o WHERE date_trunc('day', o.created_at) = gs.day AND o.order_status NOT IN (1, 5)) as pay_amount,
+ (SELECT COALESCE(SUM(total_amount), 0) FROM public.ml_orders o WHERE date_trunc('day', o.created_at) = gs.day AND o.order_status = 7) as refund_amount
+ FROM generate_series(date_trunc('day', p_start_time), date_trunc('day', p_end_time), '1 day'::interval) gs(day)
+ ORDER BY gs.day ASC
+ ) t;
+
+ RETURN COALESCE(v_items, '[]'::jsonb);
+END;
+$$;
diff --git a/pages/mall/admin/finance/balance_record.uvue b/pages/mall/admin/finance/balance_record.uvue
index 17ab5e3b..dad6af02 100644
--- a/pages/mall/admin/finance/balance_record.uvue
+++ b/pages/mall/admin/finance/balance_record.uvue
@@ -3,19 +3,16 @@
-
- 订单时间:
-
- 📅
- 开始日期 - 结束日期
-
+
+ 流水搜索:
+
交易类型:
-
- 请选择
- ▼
-
+
+
+
+ 查询
@@ -23,114 +20,164 @@
-
-
- {{ item.id }}
- {{ item.order }}
- {{ item.time }}
+
+
+ 加载中...
+
+
+ 暂无记录
+
+
+ {{ (page - 1) * pageSize + index + 1 }}
+ {{ item.link_id || '-' }}
+ {{ item.created_at.substring(0, 16).replace('T', ' ') }}
- {{ item.amount }}
+
+ {{ item.pm === 1 ? '+' : '-' }}{{ item.number.toFixed(2) }}
+
- {{ item.user }}
- {{ item.type }}
-
+
+
+ {{ item.user_name || '未知' }}
+ UID:{{ item.uid.substring(0, 8) }}
+
+
+ {{ getBillTypeText(item.type) }}
+
- 备注
+ 详情
-
+
+
+
+
+
diff --git a/pages/mall/admin/finance/balance_stats.uvue b/pages/mall/admin/finance/balance_stats.uvue
index 487852ff..ca19f772 100644
--- a/pages/mall/admin/finance/balance_stats.uvue
+++ b/pages/mall/admin/finance/balance_stats.uvue
@@ -7,7 +7,7 @@
💰
- 1447117274.55
+ {{ statsData.current_balance.toFixed(2) }}
当前余额
@@ -16,7 +16,7 @@
🏦
- 1602611838.49
+ {{ statsData.total_accumulation.toFixed(2) }}
累计余额
@@ -25,7 +25,7 @@
💳
- 155494563.94
+ {{ statsData.total_consumption.toFixed(2) }}
累计消耗余额
@@ -144,30 +144,31 @@
-
-
diff --git a/pages/mall/admin/finance/capital_flow.uvue b/pages/mall/admin/finance/capital_flow.uvue
index 7c67848a..6f5b7a4e 100644
--- a/pages/mall/admin/finance/capital_flow.uvue
+++ b/pages/mall/admin/finance/capital_flow.uvue
@@ -4,24 +4,18 @@
- 订单时间:
-
- 📅
- 开始日期 - 结束日期
-
+ 交易类型:
+
- 交易类型:
-
- 请选择
- ▼
-
+ 收支类型:
+
流水搜索:
-
+
-
+
查询
@@ -30,112 +24,170 @@
-
- {{ item.flowNo }}
- {{ item.orderNo }}
- {{ item.time }}
- {{ item.amount }}
- {{ item.user }}
- {{ item.method }}
-
+
+ 加载中...
+
+
+ 暂无流水记录
+
+
+ {{ item.id.substring(0, 8) }}...
+ {{ item.link_id || '-' }}
+ {{ item.created_at.substring(0, 16).replace('T', ' ') }}
+
+
+ {{ item.pm === 1 ? '+' : '-' }}{{ item.number.toFixed(2) }}
+
+
+
+
+ {{ item.user_name || '未知' }}
+ UID:{{ item.uid.substring(0, 8) }}
+
+
+ {{ getBillTypeText(item.type) }}
+
- 备注
+ 详情
+
+
+
diff --git a/pages/mall/admin/finance/commission.uvue b/pages/mall/admin/finance/commission.uvue
index 55c6104b..41e58f45 100644
--- a/pages/mall/admin/finance/commission.uvue
+++ b/pages/mall/admin/finance/commission.uvue
@@ -3,11 +3,15 @@
-
- 昵称/手机号/分销商ID:
-
+
+ 佣金搜索:
+
-
+
+ 收支类型:
+
+
+
查询
@@ -23,102 +27,159 @@
-
+
+ 加载中...
+
+
+ 暂无佣金记录
+
+
+ {{ (page - 1) * pageSize + index + 1 }}
+ {{ item.link_id || '-' }}
+ {{ item.created_at.substring(0, 16).replace('T', ' ') }}
+
+
+ {{ item.pm === 1 ? '+' : '-' }}{{ item.number.toFixed(2) }}
+
+
- {{ item.userInfo }}
-
-
- {{ item.totalAmount }}
-
-
- {{ item.accountAmount }}
-
-
- {{ item.withdrawAmount }}
+
+ {{ item.user_name || '未知' }}
+ UID:{{ item.uid.substring(0, 8) }}
+
+ {{ getBillTypeText(item.type) }}
+
+
+
+
-
-
diff --git a/pages/mall/admin/finance/invoice.uvue b/pages/mall/admin/finance/invoice.uvue
index 5f559853..7748b2b1 100644
--- a/pages/mall/admin/finance/invoice.uvue
+++ b/pages/mall/admin/finance/invoice.uvue
@@ -7,20 +7,14 @@
创建时间:
📅
- 开始日期 - 结束日期
+ 最近30天
-
+
搜索:
-
-
- 请选择
- ▼
-
-
-
+
-
+
查询
@@ -33,134 +27,206 @@
:key="index"
class="tab-item"
:class="{ active: activeTab === index }"
- @click="activeTab = index"
+ @click="handleTabChange(index)"
>
- {{ tab.name }} ({{ tab.count }})
+ {{ tab.name }}
-
+
-
- {{ item.orderNo }}
- ¥ {{ item.amount }}
- {{ item.invoiceType }}
-
- {{ item.time }}
- {{ item.invStatus }}
- {{ item.orderStatus }}
-
-
- 操作
- |
- 订单信息
+
+ 加载中...
+
+
+ 暂无发票申请
+
+
+ {{ item.order_no }}
+ ¥ {{ item.order_amount.toFixed(2) }}
+ {{ item.invoice_type == 1 ? '普通发票' : '专用发票' }}
+
+ {{ item.created_at.substring(0, 16).replace('T', ' ') }}
+
+
+ {{ getStatusText(item.status) }}
+
+
+
+
+ 开票
+ |
+ 驳回
+
+ -
+
+
+
+
diff --git a/pages/mall/admin/finance/recharge.uvue b/pages/mall/admin/finance/recharge.uvue
index c6af5b4d..dbb90cae 100644
--- a/pages/mall/admin/finance/recharge.uvue
+++ b/pages/mall/admin/finance/recharge.uvue
@@ -4,24 +4,14 @@
- 时间选择:
-
- 📅
- 开始日期 - 结束日期
-
-
-
- 支付类型:
-
- 全部
- ▼
-
+ 支付状态:
+
搜索:
-
+
-
+
查询
@@ -29,7 +19,7 @@
-
+
{{ item.icon }}
@@ -51,8 +41,7 @@
-
- {{ item.id }}
-
-
- 🖼️
-
+
+ 加载中...
+
+
+ 暂无充值记录
+
+
+ {{ (page - 1) * pageSize + index + 1 }}
+
+
+ {{ item.user_name || '未知' }}
+ {{ item.user_email || '-' }}
- {{ item.nickname }}
- {{ item.orderNo }}
- {{ item.amount }}
- {{ item.isPaid }}
- {{ item.type }}
- {{ item.time }}
+ {{ item.order_no }}
+
+
+ ¥{{ item.price.toFixed(2) }}
+ 赠:¥{{ item.give_price.toFixed(2) }}
+
+
+
+
+ {{ item.paid == 1 ? '已支付' : '未支付' }}
+
+
+ {{ getRechargeTypeText(item.recharge_type) }}
+ {{ item.pay_time ? item.pay_time.substring(0, 16).replace('T', ' ') : '-' }}
- 删除
+ 详情
+
+
+
diff --git a/pages/mall/admin/finance/transaction_stats.uvue b/pages/mall/admin/finance/transaction_stats.uvue
index 18ea22cf..20beb1bb 100644
--- a/pages/mall/admin/finance/transaction_stats.uvue
+++ b/pages/mall/admin/finance/transaction_stats.uvue
@@ -8,16 +8,16 @@
:key="index"
class="date-tab-item"
:class="{ active: activeDateTab === index }"
- @click="activeDateTab = index"
+ @click="handleDateTabChange(index)"
>{{ item }}
D
- 2026-02-03 - 2026-02-03
+ {{ displayDateRange }}
-
+
@@ -41,10 +38,10 @@
🕒
营业额
- {{ stats.revenue }}
+ ¥{{ stats.revenue }}
- 环比增长:
- 44275370% ▲
+ 昨日对比:
+ {{ stats.revenueTrend }}
@@ -52,10 +49,10 @@
¥
商品支付金额
- {{ stats.payAmount }}
+ ¥{{ stats.payAmount }}
- 环比增长:
- 43469352% ▲
+ 交易笔数:
+ {{ stats.orderCount }}
@@ -63,10 +60,10 @@
🔒
购买会员金额
- {{ stats.memberAmount }}
+ ¥{{ stats.memberAmount }}
- 环比增长:
- 805918% ▲
+ 占比:
+ -
@@ -74,10 +71,10 @@
💰
充值金额
- {{ stats.rechargeAmount }}
+ ¥{{ stats.rechargeAmount }}
- 环比增长:
- 0% -
+ 笔数:
+ {{ stats.rechargeCount }}
@@ -85,10 +82,10 @@
🛒
线下收银金额
- {{ stats.offlineAmount }}
+ ¥{{ stats.offlineAmount }}
- 环比增长:
- 100% ▲
+ 占比:
+ -
@@ -99,33 +96,33 @@
↘
- 支出金额
- {{ stats.expenditure }}
+ 支出金额 (提现)
+ ¥{{ stats.expenditure }}
- 环比增长:
- 44275269% ▲
+ 笔数:
+ {{ stats.extractCount }}
💳
- 余额支付金额
- {{ stats.balancePay }}
+ 全站余额存量
+ ¥{{ stats.balancePay }}
- 环比增长:
- 5293.00% ▲
+ 用户总数:
+ -
%
- 支付佣金金额
- {{ stats.commissionPay }}
+ 佣金总存量
+ ¥{{ stats.commissionPay }}
- 环比增长:
- 0% -
+ 待结算:
+ -
@@ -133,147 +130,22 @@
📦
商品退款金额
- {{ stats.refundAmount }}
+ ¥{{ stats.refundAmount }}
- 环比增长:
- 0% -
+ 退款率:
+ -
-
-
- 营业额
- 商品支付金额
- 购买会员金额
- 充值金额
- 支出金额
-
-
-
-
-
-
-
-
-
-
-
-
-
- ¥
- 0
-
-
-
-
- 今天
-
-
-
- 昨天
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 0
-
- 昨日:
- 4
-
-
- 日环比:
- -100% ▼
-
-
-
-
-
-
-
-
-
-
- 12
-
- 上月:
- 206
-
-
- 月环比:
- -94% ▼
-
-
-
-
-
-
-
-
-
-
-
-
-
- 0
-
- 昨日:
- 4
-
-
- 日环比:
- -100% ▼
-
-
-
-
-
-
-
-
-
-
- 7
-
- 上月:
- 134
-
-
- 月环比:
- -94% ▼
-
-
-
-
-
-
+ 统计加载中...
+
@@ -281,142 +153,129 @@
@@ -461,7 +315,6 @@ function initCharts() {
min-height: 100vh;
}
-/* 头部筛选 */
.header-filters {
background: #fff;
padding: 12px 20px;
@@ -487,15 +340,8 @@ function initCharts() {
border-right: 1px solid #d9d9d9;
cursor: pointer;
- &:last-child {
- border-right: none;
- }
-
- &.active {
- background-color: #1890ff;
- color: #fff;
- border-color: #1890ff;
- }
+ &:last-child { border-right: none; }
+ &.active { background-color: #1890ff; color: #fff; border-color: #1890ff; }
}
.date-picker-wrap {
@@ -503,167 +349,17 @@ function initCharts() {
flex-direction: row;
align-items: center;
padding: 4px 12px;
- border: 1px solid #d9d9d9;
+ border: 1px solid #dcdfe6;
border-radius: 2px;
}
-.calendar-icon {
- margin-right: 8px;
- font-size: 14px;
-}
+.calendar-icon { margin-right: 8px; font-size: 14px; }
+.date-range-text { font-size: 14px; color: #333; }
-.date-range-text {
- font-size: 14px;
- color: #333;
-}
-
-/* 统计区域布局 */
-.stats-section {
- display: flex;
- flex-direction: row;
- gap: 16px;
-}
-
-.stats-card-main {
- flex: 3;
- background: #fff;
- border-radius: 4px;
- padding: 24px;
- min-height: 380px;
-}
-
-.card-title {
- font-size: 16px;
- color: #333;
- font-weight: 500;
- margin-bottom: 20px;
- display: block;
-}
-
-.amount-wrap {
- margin-top: 10px;
-}
-
-.currency {
- font-size: 24px;
- color: #333;
- margin-right: 8px;
-}
-
-.amount-value {
- font-size: 40px;
- color: #333;
- font-weight: bold;
-}
-
-.chart-legend {
- display: flex;
- flex-direction: row;
- margin-top: 16px;
-}
-
-.legend-item {
- display: flex;
- flex-direction: row;
- align-items: center;
- margin-right: 20px;
- font-size: 14px;
- color: #666;
-}
-
-.dot {
- width: 8px;
- height: 8px;
- border-radius: 50%;
- margin-right: 8px;
-
- &.blue { background-color: #1890ff; }
- &.gray { background-color: #d9d9d9; }
-}
-
-.chart-box {
- width: 100%;
- height: 220px;
- margin-top: 20px;
-}
-
-.stats-chart {
- width: 100%;
- height: 100%;
-}
-
-/* 侧边网格 */
-.stats-side-grid {
- flex: 2;
- display: flex;
- flex-direction: row;
- gap: 16px;
-}
-
-.side-column {
- flex: 1;
- display: flex;
- flex-direction: column;
- gap: 16px;
-}
-
-.side-stat-card {
- background: #fff;
- border-radius: 4px;
- padding: 24px;
- display: flex;
- flex-direction: column;
-}
-
-.main-val {
- font-size: 32px;
- font-weight: bold;
- color: #333;
- margin-bottom: 20px;
- display: block;
-}
-
-.compare-row {
- display: flex;
- flex-direction: row;
- margin-bottom: 8px;
- font-size: 14px;
-}
-
-.compare-row .label {
- color: #999;
- margin-right: 8px;
-}
-
-.compare-row .val {
- color: #333;
-
- &.down { color: #52c41a; }
- &.up { color: #f5222d; }
-}
-
-.mini-chart-placeholder {
- margin-top: 20px;
- height: 2px;
- background-color: #f0f0f0;
- position: relative;
-}
-
-.blue-line {
- position: absolute;
- left: 0;
- top: 0;
- width: 60%;
- height: 100%;
- background-color: #1890ff;
-}
-
-/* 交易概况复刻样式 */
.overview-card {
background: #fff;
border-radius: 4px;
padding: 20px;
- margin-bottom: 20px;
}
.overview-header {
@@ -674,72 +370,22 @@ function initCharts() {
margin-bottom: 24px;
}
-.overview-header .header-left {
- display: flex;
- flex-direction: row;
- align-items: center;
-}
-
-.section-title {
- font-size: 16px;
- font-weight: bold;
- color: #333;
-}
-
+.header-left { display: flex; flex-direction: row; align-items: center; }
+.section-title { font-size: 16px; font-weight: bold; color: #333; }
.info-tag {
- width: 16px;
- height: 16px;
- border-radius: 50%;
- background: #eee;
- color: #999;
- font-size: 11px;
- display: flex;
- align-items: center;
- justify-content: center;
- margin-left: 8px;
-}
-
-.overview-header .header-right {
- display: flex;
- flex-direction: row;
- gap: 12px;
-}
-
-.date-picker-inline {
- border: 1px solid #dcdfe6;
- padding: 5px 15px;
- border-radius: 4px;
- display: flex;
- align-items: center;
-}
-
-.date-text {
- font-size: 13px;
- color: #606266;
+ width: 16px; height: 16px; border-radius: 50%;
+ background: #eee; color: #999; font-size: 11px;
+ display: flex; align-items: center; justify-content: center; margin-left: 8px;
}
+.header-right { display: flex; flex-direction: row; gap: 12px; }
.btn-query, .btn-export {
- padding: 0 16px;
- height: 32px;
- line-height: 32px;
- font-size: 13px;
- border-radius: 4px;
- cursor: pointer;
+ padding: 0 16px; height: 32px; line-height: 32px;
+ font-size: 13px; border-radius: 4px; cursor: pointer;
}
+.btn-query { background-color: #1890ff; color: #fff; border: none; }
+.btn-export { background: #fff; color: #1890ff; border: 1px solid #1890ff; }
-.btn-query {
- background-color: #1890ff;
- color: #fff;
- border: none;
-}
-
-.btn-export {
- background: #fff;
- color: #1890ff;
- border: 1px solid #1890ff;
-}
-
-/* 指标网格 */
.overview-grid {
display: flex;
flex-direction: column;
@@ -748,36 +394,14 @@ function initCharts() {
border-bottom: 1px dashed #f0f0f0;
}
-.grid-row {
- display: flex;
- flex-direction: row;
- justify-content: space-between;
-}
-
-.overview-item {
- flex: 1;
- display: flex;
- flex-direction: row;
- align-items: center;
-}
-
-.overview-item.transparent {
- visibility: hidden;
-}
+.grid-row { display: flex; flex-direction: row; justify-content: space-between; }
+.overview-item { flex: 1; display: flex; flex-direction: row; align-items: center; }
+.overview-item.transparent { visibility: hidden; }
.icon-box {
- width: 44px;
- height: 44px;
- border-radius: 50%;
- display: flex;
- align-items: center;
- justify-content: center;
- margin-right: 12px;
-}
-
-.icon-box .icon {
- font-size: 20px;
- color: #fff;
+ width: 44px; height: 44px; border-radius: 50%;
+ display: flex; align-items: center; justify-content: center; margin-right: 12px;
+ text { color: #fff; font-size: 20px; }
}
.icon-box.blue { background-color: #2f54eb; }
@@ -790,74 +414,14 @@ function initCharts() {
.icon-box.red-purple { background-color: #eb2f96; }
.icon-box.blue-gray { background-color: #4096ff; }
-.item-info {
- display: flex;
- flex-direction: column;
-}
+.item-info { display: flex; flex-direction: column; }
+.item-label { font-size: 13px; color: #999; margin-bottom: 4px; }
+.item-value { font-size: 22px; font-weight: bold; color: #333; margin-bottom: 4px; }
+.trend-row { display: flex; flex-direction: row; font-size: 12px; color: #999; }
+.trend-value { margin-left: 4px; }
-.item-label {
- font-size: 13px;
- color: #999;
- margin-bottom: 4px;
-}
-
-.item-value {
- font-size: 24px;
- font-weight: bold;
- color: #333;
- margin-bottom: 4px;
-}
-
-.trend-row {
- display: flex;
- flex-direction: row;
- font-size: 12px;
- color: #999;
-}
-
-.trend-value.up {
- color: #f5222d;
- margin-left: 4px;
-}
-
-/* 图表区 */
-.overview-chart-section {
- padding-top: 24px;
-}
-
-.overview-chart-legend {
- display: flex;
- flex-direction: row;
- justify-content: center;
- align-items: center;
- gap: 16px;
- margin-bottom: 20px;
-}
-
-.legend-dot {
- width: 8px;
- height: 8px;
- border-radius: 50%;
-}
-
-.legend-dot.blue { background: #1890ff; }
-.legend-dot.green { background: #52c41a; }
-.legend-dot.gray-blue { background: #607d8b; }
-.legend-dot.red { background: #f44336; }
-.legend-dot.orange { background: #fa8c16; }
-
-.legend-text {
- font-size: 12px;
- color: #666;
-}
-
-.overview-chart-box {
- width: 100%;
- height: 400px;
-}
-
-.main-trend-chart {
- width: 100%;
- height: 100%;
-}
+.overview-chart-section { padding-top: 24px; }
+.overview-chart-box { width: 100%; height: 350px; }
+.main-trend-chart { width: 100%; height: 100%; }
+.chart-loading { height: 100%; display: flex; align-items: center; justify-content: center; color: #999; }
diff --git a/pages/mall/admin/finance/withdrawal.uvue b/pages/mall/admin/finance/withdrawal.uvue
index 5d9ef872..25eaec43 100644
--- a/pages/mall/admin/finance/withdrawal.uvue
+++ b/pages/mall/admin/finance/withdrawal.uvue
@@ -25,7 +25,7 @@
-
+
{{ item.icon }}
@@ -43,73 +43,98 @@
-
+
-
- {{ item.id }}
+
+ 加载中...
+
+
+ 暂无提现申请
+
+
+ {{ (page - 1) * pageSize + index + 1 }}
U
- {{ item.nickname }}
- 用户id:{{ item.userId }}
+ {{ item.user_name || '未知' }}
+ UID:{{ item.uid.substring(0, 8) }}
- {{ item.amount }}
- {{ item.fee }}
- {{ item.netAmount }}
+ ¥{{ item.extract_price.toFixed(2) }}
+ ¥{{ item.service_fee.toFixed(2) }}
+ ¥{{ (item.extract_price - item.service_fee).toFixed(2) }}
- 姓名:{{ item.name }}
- {{ item.type }}:{{ item.account }}
- 银行开户地址:{{ item.bank }}
+ {{ getMethodText(item.extract_type) }}
+ 账号:{{ item.alipay_code || item.wechat_code || item.bank_code || '-' }}
-
-
- ■
-
+ {{ item.created_at.substring(0, 16).replace('T', ' ') }}
+
+
+ {{ getStatusText(item.status) }}
+
- {{ item.time }}
-
- 申请中
-
- 编辑
+
+ 通过
|
- 通过
- |
- 驳回
+ 驳回
+ -
+
+
+
diff --git a/pages/mall/admin/product/product-management/index.uvue b/pages/mall/admin/product/product-management/index.uvue
index 96987e1e..33ef86b9 100644
--- a/pages/mall/admin/product/product-management/index.uvue
+++ b/pages/mall/admin/product/product-management/index.uvue
@@ -5,7 +5,7 @@
商品搜索:
-
+
商品类型:
@@ -16,14 +16,19 @@
商品分类:
-
- 请选择
- ▼
-
+ {
+ categoryIndex = e.detail.value;
+ selectedCategoryId = categoryOptions[categoryIndex].value;
+ }">
+
+ {{ categoryOptions[categoryIndex].label }}
+ ▼
+
+
-
-
+
+
展开
▼
@@ -49,7 +54,7 @@
:key="index"
class="tab-item"
:class="{ active: activeStatus === tab.key }"
- @click="activeStatus = tab.key"
+ @click="changeStatus(tab.key)"
>
{{ tab.label }}({{ tab.count }})
@@ -115,7 +120,7 @@
{{ item.stock }}
{{ item.sort }}
-
+
{{ item.status === 1 ? '上架' : '下架' }}
@@ -137,7 +142,7 @@
-
+
@@ -149,10 +154,9 @@
@@ -162,15 +166,21 @@