fix: bug
Some checks failed
构建并部署前端到测试环境 / build-and-deploy (push) Has been cancelled

This commit is contained in:
sexygoat
2026-05-11 15:14:38 +08:00
parent 28246f5345
commit 52311fae0a
22 changed files with 547 additions and 1773 deletions

View File

@@ -1,7 +1,7 @@
/**
* 佣金模块 API (代理端)
*/
import { get, post } from '@/utils/request'
import { get } from '@/utils/request'
/**
* 资金概览 (代理端主页用)
@@ -141,7 +141,7 @@ export interface ListResponse<T> {
}
export interface FundSummaryParams {
shop_name?: string
username?: string
}
/**
@@ -151,7 +151,7 @@ export interface FundSummaryParams {
export function getFundSummary(params?: FundSummaryParams) {
return get<{ items: FundSummary[] }>(
'/api/admin/shops/fund-summary',
params?.shop_name ? { params } : undefined
params?.username ? { params } : undefined
).then(res => res.items?.[0])
}

View File

@@ -0,0 +1,88 @@
<script setup lang="ts">
import { computed } from 'vue'
import type { FundSummary } from '@/api/commission'
type SummaryMetric = {
label: string
amount?: number | null
cardClass: string
labelClass: string
}
const props = defineProps<{
summary?: FundSummary | null
}>()
const metrics = computed<SummaryMetric[]>(() => [
{
label: '预充值余额',
amount: props.summary?.main_balance,
cardClass: 'bg-[#f4fbf5] border border-[#e3f2e6]',
labelClass: 'text-[#2f7d32]',
},
{
label: '累计佣金',
amount: props.summary?.total_commission,
cardClass: 'bg-[#f8fafc] border border-[#eef2f6]',
labelClass: 'text-[#6b7280]',
},
{
label: '已提现',
amount: props.summary?.withdrawn_commission,
cardClass: 'bg-[#f8fafc] border border-[#eef2f6]',
labelClass: 'text-[#6b7280]',
},
{
label: '冻结',
amount: props.summary?.frozen_commission,
cardClass: 'bg-[#f8fafc] border border-[#eef2f6]',
labelClass: 'text-[#6b7280]',
},
])
function formatAmount(amount: number) {
const yuan = (amount / 100).toFixed(2)
const parts = yuan.split('.')
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',')
return `¥${parts.join('.')}`
}
function formatAmountDisplay(amount?: number | null) {
return typeof amount === 'number' ? formatAmount(amount) : '--'
}
</script>
<template>
<view class="bg-white rounded-20px shadow-[0_8px_24px_rgba(15,23,42,0.06)] p-5">
<view class="rounded-18px bg-gradient-to-br from-[#f5fbf5] via-white to-[#f8fafc] p-4">
<view class="flex items-start justify-between gap-3">
<view class="min-w-0 flex-1">
<view class="inline-flex items-center gap-1 rounded-full bg-[#e8f5e9] px-2.5 py-1">
<i class="i-mdi-wallet-outline text-13px text-[#2f7d32]" />
<text class="text-11px font-600 text-[#2f7d32]">可提现佣金</text>
</view>
<text class="text-34px font-700 leading-none text-[#1f2937] block mt-3 break-all">
{{ formatAmountDisplay(summary?.available_commission) }}
</text>
</view>
<image src="@/static/icons/佣金中心.png" class="w-16 h-16 shrink-0" mode="aspectFit" />
</view>
</view>
<view class="grid grid-cols-2 gap-3 mt-4">
<view
v-for="metric in metrics"
:key="metric.label"
:class="metric.cardClass"
class="rounded-16px px-3 py-3"
>
<text :class="metric.labelClass" class="text-11px block">
{{ metric.label }}
</text>
<text class="text-15px font-700 text-[#1f2937] block mt-2 break-all">
{{ formatAmountDisplay(metric.amount) }}
</text>
</view>
</view>
</view>
</template>

View File

@@ -340,14 +340,6 @@
</text>
</view>
<!-- 运营商ID -->
<view v-if="cardInfo.carrier_id" class="flex items-start justify-between">
<text class="text-12px text-[#999] w-70px">运营商ID</text>
<text class="flex-1 text-13px text-[#212121] text-right">
{{ cardInfo.carrier_id }}
</text>
</view>
<!-- 卡类型 -->
<view v-if="cardInfo.card_category" class="flex items-start justify-between">
<text class="text-12px text-[#999] w-70px">卡类型</text>

View File

@@ -2,6 +2,7 @@
import { ref, computed, onMounted } from 'vue'
import { getFundSummary, getCommissionRecords, getCommissionStats } from '@/api/commission'
import type { FundSummary, CommissionRecord, CommissionStats } from '@/api/commission'
import AgentFundSummaryCard from '@/components/AgentFundSummaryCard.vue'
import SimplePicker from '@/components/SimplePicker.vue'
type LoginUserInfo = {
@@ -13,7 +14,6 @@ const commissionSummary = ref<FundSummary | null>(null)
const shopId = ref<number>(0)
const commissionRecords = ref<CommissionRecord[]>([])
const commissionStats = ref<CommissionStats | null>(null)
const loading = ref(false)
const loadingRecords = ref(false)
const page = ref(1)
const pageSize = 20
@@ -86,7 +86,7 @@ onMounted(() => {
async function loadCommissionSummary() {
try {
const userInfo = getLoginUserInfo()
commissionSummary.value = await getFundSummary(userInfo?.username ? { shop_name: userInfo.username } : undefined)
commissionSummary.value = await getFundSummary(userInfo?.username ? { username: userInfo.username } : undefined)
} catch (error) {
console.error('加载佣金概览失败:', error)
}
@@ -153,12 +153,6 @@ function loadMore() {
}
}
function onScroll(e: any) {
const { scrollTop, scrollHeight, clientHeight } = e.target
if (scrollHeight - scrollTop - clientHeight < 100) {
loadMore()
}
}
</script>
<template>
@@ -205,37 +199,7 @@ function onScroll(e: any) {
<!-- 内容区域 -->
<view class="px-4 pb-4">
<!-- 概览卡片 -->
<view class="bg-white rounded-16px p-5 mt-4 shadow-[0_2px_12px_rgba(0,0,0,0.08)]">
<view class="flex items-center justify-between">
<view>
<text class="text-12px text-[#999]">可提现佣金</text>
<text class="text-32px font-700 text-[#212121] block mt-1">
{{ commissionSummary ? formatAmount(commissionSummary.available_commission) : '--' }}
</text>
</view>
<image src="@/static/icons/佣金中心.png" class="w-12 h-12 rounded-12px" mode="aspectFit" />
</view>
<view class="flex gap-3 mt-4 pt-4 border-t border-[#f5f5f5]">
<view class="flex-1 text-center">
<text class="text-11px text-[#999]">累计佣金</text>
<text class="text-14px font-600 text-[#212121] block mt-1">
{{ commissionSummary ? formatAmount(commissionSummary.total_commission) : '--' }}
</text>
</view>
<view class="flex-1 text-center border-l border-[#f5f5f5]">
<text class="text-11px text-[#999]">已提现</text>
<text class="text-14px font-600 text-[#52c41a] block mt-1">
{{ commissionSummary ? formatAmount(commissionSummary.withdrawn_commission) : '--' }}
</text>
</view>
<view class="flex-1 text-center border-l border-[#f5f5f5]">
<text class="text-11px text-[#999]">冻结</text>
<text class="text-14px font-600 text-[#ff4d4f] block mt-1">
{{ commissionSummary ? formatAmount(commissionSummary.frozen_commission) : '--' }}
</text>
</view>
</view>
</view>
<AgentFundSummaryCard class="mt-4" :summary="commissionSummary" />
<!-- 佣金统计 -->
<view class="bg-white rounded-16px p-4 mt-3 shadow-[0_2px_8px_rgba(0,0,0,0.04)]">

View File

@@ -5,6 +5,7 @@
import type { UserInfo } from '@/api/auth'
import { getFundSummary, getCommissionDailyStats } from '@/api/commission'
import type { FundSummary, DailyCommissionStats } from '@/api/commission'
import AgentFundSummaryCard from '@/components/AgentFundSummaryCard.vue'
// 用户信息
@@ -36,10 +37,6 @@
return `¥${parts.join('.')}`
}
function formatAmountDisplay(amount?: number | null) {
return typeof amount === 'number' ? formatAmount(amount) : '--'
}
// 格式化日期 (MM-DD)
// 根据用户类型动态生成菜单
function formatDate(dateStr : string) {
@@ -49,72 +46,15 @@
return `${month}-${day}`
}
function getTodayDate() {
const today = new Date()
const year = today.getFullYear()
const month = String(today.getMonth() + 1).padStart(2, '0')
const day = String(today.getDate()).padStart(2, '0')
return `${year}-${month}-${day}`
}
const menuItems = computed(() => {
const menus = [
{
title: '资产列表',
desc: userInfo.value?.user_type === 3 ? '代理资产列表' : '企业资产列表',
icon: '/static/icons/资产列表.png',
path: '/pages/agent-system/assets/index',
},
]
// 企业端显示授权卡和授权设备 (仅 user_type === 4)
if (userInfo.value?.user_type === 4) {
menus.push(
{
title: '授权卡列表',
desc: '企业授权IoT卡',
icon: '/static/icons/授权卡列表.png',
path: '/pages/agent-system/enterprise-cards/index',
},
{
title: '授权设备列表',
desc: '企业授权设备',
icon: '/static/icons/授权设备列表.png',
path: '/pages/agent-system/enterprise-devices/index',
}
)
}
// 仅代理端显示佣金和提现
if (userInfo.value?.user_type === 3) {
menus.push(
{
title: '佣金中心',
desc: '收益统计',
icon: '/static/icons/佣金中心.png',
path: '/pages/agent-system/commission-center/index',
},
{
title: '提现管理',
desc: '申请提现',
icon: '/static/icons/提现管理.png',
path: '/pages/agent-system/withdraw/index',
}
)
}
return menus
})
// 加载佣金数据
async function loadCommissionData(shopName?: string) {
async function loadCommissionData(username?: string) {
if (!isAgent.value) return
loadingCommission.value = true
try {
// 1. 加载佣金概览 (新接口 /shops/fund-summary)
const summary = await getFundSummary(shopName ? { shop_name: shopName } : undefined)
const summary = await getFundSummary(username ? { username } : undefined)
commissionSummary.value = summary
if (!shopId.value) {
@@ -122,11 +62,8 @@
return
}
const today = getTodayDate()
const todayStats = await getCommissionDailyStats(shopId.value, {
days: 1,
start_date: today,
end_date: today,
})
dailyStats.value = todayStats || []
return
@@ -155,19 +92,20 @@
// 设置店铺ID
const loginUserInfo = getLoginUserInfo()
shopId.value = user.shop_id || loginUserInfo?.shop_id || 0
const fundSummaryShopName = loginUserInfo?.username || user.username
const fundSummaryUsername = loginUserInfo?.username || user.username
console.log('首页数据加载成功:', { user })
// 如果是代理账号,加载佣金数据
if (user.user_type === 3) {
await loadCommissionData(fundSummaryShopName)
await loadCommissionData(fundSummaryUsername)
}
}
catch (error : any) {
console.error('加载首页数据失败:', error)
// 如果是前端逻辑错误(非 API 错误),需要手动显示提示
if (error instanceof Error && error.message && !error.statusCode) {
const errorWithStatus = error as { statusCode?: number } | undefined
if (error instanceof Error && error.message && !errorWithStatus?.statusCode) {
uni.$u.toast(error.message)
}
// API 请求错误已由拦截器统一处理
@@ -253,54 +191,16 @@
<!-- 代理端: 佣金展示 -->
<view v-if="isAgent" class="px-4 pt-4">
<view
class="bg-white rounded-16px shadow-[0_2px_12px_rgba(0,0,0,0.06)] p-5 mb-3"
<AgentFundSummaryCard
class="mb-3"
:summary="commissionSummary"
@click="navigateTo('/pages/agent-system/commission-center/index')"
>
<view class="flex items-center justify-between gap-3">
<view class="min-w-0 flex-1">
<text class="text-12px text-[#999]">可提现佣金</text>
<text class="text-32px font-700 text-[#212121] block mt-1 break-all">
{{ formatAmountDisplay(commissionSummary?.available_commission) }}
</text>
<text class="text-11px text-[#999] block mt-2">
当前可直接发起提现的佣金金额
</text>
</view>
<view class="flex flex-col items-end gap-2">
<image src="@/static/icons/佣金中心.png" class="w-12 h-12 rounded-12px" mode="aspectFit" />
<view class="flex items-center gap-1">
<text class="text-12px text-[#999]">佣金中心</text>
<i class="i-mdi-chevron-right text-16px text-[#cbd5e1]" />
</view>
</view>
</view>
<view class="flex gap-3 mt-4 pt-4 border-t border-[#f5f5f5]">
<view class="flex-1 text-center">
<text class="text-11px text-[#999]">累计佣金</text>
<text class="text-14px font-600 text-[#212121] block mt-1">
{{ formatAmountDisplay(commissionSummary?.total_commission) }}
</text>
</view>
<view class="flex-1 text-center border-l border-[#f5f5f5]">
<text class="text-11px text-[#999]">已提现</text>
<text class="text-14px font-600 text-[#52c41a] block mt-1">
{{ formatAmountDisplay(commissionSummary?.withdrawn_commission) }}
</text>
</view>
<view class="flex-1 text-center border-l border-[#f5f5f5]">
<text class="text-11px text-[#999]">冻结</text>
<text class="text-14px font-600 text-[#ff4d4f] block mt-1">
{{ formatAmountDisplay(commissionSummary?.frozen_commission) }}
</text>
</view>
</view>
</view>
/>
<!-- 今日佣金 -->
<!-- 最近一天佣金 -->
<view>
<view class="flex items-center justify-between mb-3">
<text class="text-16px font-700 text-[#212121]">今日佣金</text>
<text class="text-16px font-700 text-[#212121]">最近一天佣金</text>
<text class="text-13px text-[#999]" @click="navigateTo('/pages/agent-system/commission-center/index')">明细</text>
</view>
<view class="bg-white rounded-16px shadow-[0_2px_12px_rgba(0,0,0,0.06)] p-4">
@@ -325,7 +225,7 @@
</view>
</view>
<view v-if="!todayStat" class="mt-3 pt-3 border-t border-[#f5f5f5] text-center">
<text class="text-12px text-[#999]">今日暂无佣金数据</text>
<text class="text-12px text-[#999]">最近一天暂无佣金数据</text>
</view>
</view>
</view>

File diff suppressed because it is too large Load Diff

View File

@@ -26,6 +26,7 @@ const pageSize = 20
const total = ref(0)
const statusFilter = ref<number | undefined>(undefined)
const showStatusPicker = ref(false)
const MIN_WITHDRAW_AMOUNT = 100
const statusOptions = [
{ label: '全部状态', value: undefined },
@@ -41,7 +42,7 @@ const selectedStatusName = computed(() => {
return option?.label || '状态'
})
const tabs = [
const tabs: Array<{ key: 'apply' | 'records', label: string }> = [
{ key: 'apply', label: '申请提现' },
{ key: 'records', label: '提现记录' },
]
@@ -51,6 +52,8 @@ const availableAmount = computed(() => {
return commissionSummary.value.available_commission / 100
})
const canWithdrawByMinAmount = computed(() => availableAmount.value >= MIN_WITHDRAW_AMOUNT)
function formatAmount(amount: number) {
const yuan = (amount / 100).toFixed(2)
const parts = yuan.split('.')
@@ -95,7 +98,7 @@ async function loadCommissionSummary() {
loading.value = true
try {
const userInfo = getLoginUserInfo()
commissionSummary.value = await getFundSummary(userInfo?.username ? { shop_name: userInfo.username } : undefined)
commissionSummary.value = await getFundSummary(userInfo?.username ? { username: userInfo.username } : undefined)
withdrawAmount.value = availableAmount.value.toFixed(2)
} catch (error) {
console.error('加载佣金概览失败:', error)
@@ -144,6 +147,10 @@ async function handleSubmit() {
uni.$u.toast('请输入提现金额')
return
}
if (amount < MIN_WITHDRAW_AMOUNT) {
uni.$u.toast(`${MIN_WITHDRAW_AMOUNT}元才可提现`)
return
}
if (amount > availableAmount.value) {
uni.$u.toast('提现金额超过可用余额')
return
@@ -200,12 +207,6 @@ function loadMore() {
}
}
function onScroll(e: any) {
const { scrollTop, scrollHeight, clientHeight } = e.target
if (scrollHeight - scrollTop - clientHeight < 100) {
loadMore()
}
}
</script>
<template>
@@ -293,10 +294,17 @@ function onScroll(e: any) {
/>
</view>
<view class="mt-6 mb-3 flex items-center gap-1.5 px-3 py-2 rounded-12px bg-[var(--color-warning-bg)]">
<i class="i-mdi-information-outline text-14px text-warning" />
<text class="text-12px" :class="canWithdrawByMinAmount ? 'text-warning' : 'text-error'">
满100元才可提现
</text>
</view>
<!-- 提交按钮 -->
<view
class="bg-brand rounded-full py-4 text-center text-16px font-600 text-white mt-6"
:class="{ 'opacity-50': submitting }"
class="bg-brand rounded-full py-4 text-center text-16px font-600 text-white"
:class="{ 'opacity-50': submitting || !canWithdrawByMinAmount }"
@click="handleSubmit"
>
{{ submitting ? '提交中...' : '确认提现' }}

View File

@@ -6,47 +6,49 @@
:root,
page {
/* === 品牌色 Brand Colors === */
--brand-primary: #1677ff; /* 主色 - 蓝色 */
--brand-primary-light: #4096ff; /* 主色浅 */
--brand-primary-dark: #0958d9; /* 主色深 */
--brand-secondary: #1e293b; /* 辅色 - 深灰/黑色 */
--brand-accent: #ffffff; /* 强调 - 白色 */
--brand-primary: #2f7d32; /* 主色 */
--brand-primary-light: #5a9f5d; /* 主色浅 */
--brand-primary-dark: #245f27; /* 主色深 */
--brand-secondary: #1f2937; /* 辅色 */
--brand-tertiary: #f4fbf5; /* 色 */
--brand-accent: #ffffff; /* 强调白 */
/* === 语义色 Semantic Colors === */
--color-success: #52c41a; /* 成功 - Green */
--color-success-bg: #f6ffed; /* 成功背景 */
--color-warning: #faad14; /* 警告 - Amber */
--color-warning-bg: #fffbe6; /* 警告背景 */
--color-error: #ff4d4f; /* 错误 - Red */
--color-error-bg: #fff2f0; /* 错误背景 */
--color-info: #1677ff; /* 信息 - Blue同主色 */
--color-info-bg: #e6f7ff; /* 信息背景 */
--color-success: #2f7d32;
--color-success-bg: #edf7ee;
--color-warning: #b7791f;
--color-warning-bg: #fff7e6;
--color-error: #c24141;
--color-error-bg: #fdf1f1;
--color-info: var(--brand-primary);
--color-info-bg: var(--brand-tertiary);
/* === 文字色阶 Text Colors === */
--text-primary: #212121; /* 标题/重要文字 */
--text-secondary: #666666; /* 正文 */
--text-tertiary: #999999; /* 辅助信息 */
--text-quaternary: #cccccc; /* 禁用/占位符 */
--text-inverse: #ffffff; /* 反色文字 */
--text-primary: #1f2937;
--text-secondary: #4b5563;
--text-tertiary: #6b7280;
--text-quaternary: #9ca3af;
--text-inverse: #ffffff;
/* === 背景色 Background Colors === */
--bg-page: #faf0f5; /* 页面背景 */
--bg-container: #ffffff; /* 容器/卡片背景 */
--bg-elevated: #ffffff; /* 悬浮层背景 */
--bg-muted: #f5f5f5; /* 静音背景 */
--bg-overlay: rgba(0, 0, 0, 0.45); /* 遮罩层 */
--bg-page: var(--brand-tertiary);
--bg-container: #ffffff;
--bg-elevated: #ffffff;
--bg-muted: #f8faf8;
--bg-overlay: rgba(31, 41, 55, 0.45);
/* === 边框色 Border Colors === */
--border-primary: #e8e8e8; /* 主边框 */
--border-secondary: #f0f0f0; /* 次边框 */
--border-light: #fafafa; /* 浅边框 */
--border-primary: #e3ece4;
--border-secondary: #edf2ee;
--border-light: #f7faf7;
/* === 阴影 Shadows === */
--shadow-sm: 0 1px 3px 0 rgba(0, 0, 0, 0.06);
--shadow-md: 0 2px 8px 0 rgba(0, 0, 0, 0.08);
--shadow-lg: 0 4px 16px 0 rgba(0, 0, 0, 0.12);
--shadow-xl: 0 8px 24px 0 rgba(0, 0, 0, 0.15);
--shadow-brand: 0 4px 12px 0 rgba(22, 119, 255, 0.2);
--shadow-xs: 0 1px 2px 0 rgba(31, 41, 55, 0.04);
--shadow-sm: 0 1px 3px 0 rgba(31, 41, 55, 0.06);
--shadow-md: 0 4px 12px 0 rgba(31, 41, 55, 0.08);
--shadow-lg: 0 8px 20px 0 rgba(31, 41, 55, 0.12);
--shadow-xl: 0 12px 28px 0 rgba(31, 41, 55, 0.16);
--shadow-brand: 0 6px 18px 0 rgba(47, 125, 50, 0.18);
/* === 圆角 Radius === */
--radius-xs: 4px;
@@ -96,38 +98,53 @@ page {
--z-popover: 1060;
--z-tooltip: 1070;
--z-toast: 1080;
/* === 兼容主题别名 Compatibility Theme Aliases === */
--theme-primary: var(--brand-primary);
--theme-primary-light: var(--brand-primary-light);
--theme-primary-dark: var(--brand-primary-dark);
--theme-success: var(--color-success);
--theme-warning: var(--color-warning);
--theme-error: var(--color-error);
--theme-main-color: var(--text-primary);
--theme-content-color: var(--text-secondary);
--theme-tips-color: var(--text-tertiary);
--theme-light-color: var(--text-quaternary);
--theme-disabled-color: var(--text-quaternary);
--theme-bg-color: var(--bg-page);
--theme-bg-color-secondary: var(--bg-container);
--theme-border-color: var(--border-primary);
}
/* === 暗色主题 Dark Theme === */
.theme-dark {
--brand-primary: #4b9cff; /* 暗色下蓝色更柔和 */
--brand-primary-light: #69b1ff;
--brand-primary-dark: #1668dc;
--color-success: #73d13d;
--color-warning: #ffc53d;
--color-error: #ff7875;
--color-info: #4b9cff;
--brand-primary-light: #74b377;
--brand-primary-dark: #245f27;
--color-warning: #f0b451;
--color-error: #ef7f7f;
--text-primary: #ffffff;
--text-secondary: #b0b8c1;
--text-tertiary: #8a8f95;
--text-quaternary: #6c757d;
--text-inverse: #1a1a1a;
--text-primary: #f8fafc;
--text-secondary: #cbd5e1;
--text-tertiary: #94a3b8;
--text-quaternary: #64748b;
--text-inverse: #111827;
--bg-page: #1a1a1a;
--bg-container: #2d2d2d;
--bg-elevated: #3a3a3a;
--bg-muted: #242424;
--bg-page: #111827;
--bg-container: #1f2937;
--bg-elevated: #273548;
--bg-muted: #182232;
--bg-overlay: rgba(0, 0, 0, 0.65);
--border-primary: #3a3a3a;
--border-secondary: #2d2d2d;
--border-light: #242424;
--border-primary: #314155;
--border-secondary: #273548;
--border-light: #1f2937;
--shadow-xs: 0 1px 2px 0 rgba(0, 0, 0, 0.2);
--shadow-sm: 0 1px 3px 0 rgba(0, 0, 0, 0.3);
--shadow-md: 0 2px 8px 0 rgba(0, 0, 0, 0.4);
--shadow-lg: 0 4px 16px 0 rgba(0, 0, 0, 0.5);
--shadow-xl: 0 8px 24px 0 rgba(0, 0, 0, 0.6);
--shadow-md: 0 4px 12px 0 rgba(0, 0, 0, 0.35);
--shadow-lg: 0 8px 20px 0 rgba(0, 0, 0, 0.45);
--shadow-xl: 0 12px 28px 0 rgba(0, 0, 0, 0.55);
--shadow-brand: 0 6px 18px 0 rgba(47, 125, 50, 0.22);
}
/* === 全局重置 Global Resets === */
@@ -144,7 +161,9 @@ page {
.text-primary { color: var(--text-primary); }
.text-secondary { color: var(--text-secondary); }
.text-tertiary { color: var(--text-tertiary); }
.text-quaternary { color: var(--text-quaternary); }
.text-brand { color: var(--brand-primary); }
.text-brand-secondary { color: var(--brand-secondary); }
.text-success { color: var(--color-success); }
.text-warning { color: var(--color-warning); }
.text-error { color: var(--color-error); }
@@ -153,13 +172,15 @@ page {
.bg-container { background-color: var(--bg-container); }
.bg-muted { background-color: var(--bg-muted); }
.bg-brand { background-color: var(--brand-primary); }
.bg-brand-secondary { background-color: var(--brand-secondary); }
.bg-brand-tertiary { background-color: var(--brand-tertiary); }
.bg-brand-light { background-color: var(--brand-primary-light); }
.bg-brand-dark { background-color: var(--brand-primary-dark); }
.bg-gradient-brand { background: linear-gradient(135deg, var(--brand-primary), var(--brand-primary-light)); }
.shadow-brand-colored { box-shadow: 0 4px 16px rgba(22, 119, 255, 0.3); }
.shadow-brand-sm { box-shadow: 0 2px 12px rgba(22, 119, 255, 0.15); }
.shadow-brand-xs { box-shadow: 0 2px 8px rgba(22, 119, 255, 0.2); }
.shadow-brand-colored { box-shadow: 0 8px 22px rgba(47, 125, 50, 0.22); }
.shadow-brand-sm { box-shadow: 0 4px 14px rgba(47, 125, 50, 0.14); }
.shadow-brand-xs { box-shadow: 0 2px 8px rgba(47, 125, 50, 0.16); }
.border-brand { border-color: var(--brand-primary); }
@@ -241,7 +262,7 @@ page {
.input:focus {
border-color: var(--brand-primary);
outline: none;
box-shadow: 0 0 0 3px rgba(22, 119, 255, 0.1);
box-shadow: 0 0 0 3px rgba(47, 125, 50, 0.12);
}
.input::placeholder {

View File

@@ -4,24 +4,24 @@
/* 颜色变量 - 使用CSS变量支持主题切换 */
/* 行为相关颜色 */
$u-primary: var(--theme-primary);
$u-primary-dark: var(--theme-primary-dark);
$u-success: var(--theme-success);
$u-warning: var(--theme-warning);
$u-error: var(--theme-error);
$u-primary: var(--brand-primary);
$u-primary-dark: var(--brand-primary-dark);
$u-success: var(--color-success);
$u-warning: var(--color-warning);
$u-error: var(--color-error);
/* 文字基本颜色 */
$u-main-color: var(--theme-main-color);
$u-content-color: var(--theme-content-color);
$u-tips-color: var(--theme-tips-color);
$u-light-color: var(--theme-light-color);
$u-disabled-color: var(--theme-disabled-color);
$u-main-color: var(--text-primary);
$u-content-color: var(--text-secondary);
$u-tips-color: var(--text-tertiary);
$u-light-color: var(--text-quaternary);
$u-disabled-color: var(--text-quaternary);
/* 背景颜色 */
$u-bg-color: var(--theme-bg-color);
$u-bg-color: var(--bg-page);
/* 边框颜色 */
$u-border-color: var(--theme-border-color);
$u-border-color: var(--border-primary);
/* 尺寸变量 */