继续完善页面布局
This commit is contained in:
187
pages/mall/admin/homePage/components/KpiMiniCard.uvue
Normal file
187
pages/mall/admin/homePage/components/KpiMiniCard.uvue
Normal file
@@ -0,0 +1,187 @@
|
||||
<template>
|
||||
<view class="kpi-card">
|
||||
<!-- Header -->
|
||||
<view class="kpi-header">
|
||||
<text class="kpi-title">{{ title }}</text>
|
||||
|
||||
<view v-if="tagText" class="kpi-tag">
|
||||
<text class="kpi-tag-text">{{ tagText }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 可选:你想在右上角塞额外按钮/图标 -->
|
||||
<slot name="headerRight"></slot>
|
||||
</view>
|
||||
|
||||
<!-- Body -->
|
||||
<view class="kpi-body">
|
||||
<text class="kpi-main-value">{{ valuePrefix }}{{ valueText }}</text>
|
||||
|
||||
<!-- 中间“昨日 / 日环比”行(可完全替换) -->
|
||||
<view v-if="metaLeft || metaRight" class="kpi-meta">
|
||||
<text v-if="metaLeft" class="kpi-meta-text">{{ metaLeft }}</text>
|
||||
|
||||
<view v-if="metaRight" class="kpi-meta-right">
|
||||
<text class="kpi-meta-text">{{ metaRight }}</text>
|
||||
|
||||
<text
|
||||
v-if="trend !== 'none'"
|
||||
class="kpi-trend-arrow"
|
||||
:class="trendClass"
|
||||
>
|
||||
{{ trendArrow }}
|
||||
</text>
|
||||
</view>
|
||||
|
||||
<!-- 可选:完全自定义这行 -->
|
||||
<slot name="meta"></slot>
|
||||
</view>
|
||||
|
||||
<view class="kpi-divider"></view>
|
||||
|
||||
<!-- 底部一行:左文案 + 右数值 -->
|
||||
<view class="kpi-footer">
|
||||
<text class="kpi-footer-left">{{ footerLeftText }}</text>
|
||||
<text class="kpi-footer-right">{{ footerRightText }}</text>
|
||||
|
||||
<!-- 可选:完全自定义 footer -->
|
||||
<slot name="footer"></slot>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
// Header
|
||||
title: string
|
||||
tagText?: string
|
||||
|
||||
// Body main
|
||||
valueText: string
|
||||
valuePrefix?: string // 例如 "¥"
|
||||
|
||||
// Meta line (可替换)
|
||||
metaLeft?: string // 例如 "昨日 4"
|
||||
metaRight?: string // 例如 "日环比 0%"
|
||||
trend?: 'up' | 'down' | 'flat' | 'none' // none = 不显示箭头
|
||||
|
||||
// Footer
|
||||
footerLeftText: string // 例如 "本月订单量"
|
||||
footerRightText: string // 例如 "181单"
|
||||
}>(), {
|
||||
tagText: '今日',
|
||||
valuePrefix: '',
|
||||
metaLeft: '',
|
||||
metaRight: '',
|
||||
trend: 'none'
|
||||
})
|
||||
|
||||
const trendArrow = computed((): string => {
|
||||
if (props.trend === 'up') return '▲'
|
||||
if (props.trend === 'down') return '▼'
|
||||
return '•'
|
||||
})
|
||||
|
||||
const trendClass = computed((): string => {
|
||||
if (props.trend === 'up') return 'is-up'
|
||||
if (props.trend === 'down') return 'is-down'
|
||||
return 'is-flat'
|
||||
})
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.kpi-card{
|
||||
background-color:#ffffff;
|
||||
border:1px solid #ebeef5;
|
||||
border-radius:6px;
|
||||
padding:16px;
|
||||
box-shadow:0 2px 12px rgba(0,0,0,0.04);
|
||||
}
|
||||
|
||||
/* Header */
|
||||
.kpi-header{
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:space-between;
|
||||
gap:12px;
|
||||
|
||||
.kpi-title{
|
||||
font-size:14px;
|
||||
color:#303133;
|
||||
font-weight:600;
|
||||
}
|
||||
.kpi-tag{
|
||||
padding:2px 8px;
|
||||
border-radius:4px;
|
||||
border:1px solid #e1f3d8;
|
||||
background:#f0f9eb;
|
||||
}
|
||||
.kpi-tag-text{
|
||||
font-size:12px;
|
||||
color:#67c23a;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Body */
|
||||
.kpi-body{
|
||||
margin-top:10px;
|
||||
.kpi-main-value{
|
||||
font-size:32px;
|
||||
font-weight:600;
|
||||
color:#303133;
|
||||
line-height:40px;
|
||||
}
|
||||
|
||||
/* “昨日 / 日环比” */
|
||||
.kpi-meta{
|
||||
margin-top:8px;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:flex-start;
|
||||
gap:12px;
|
||||
flex-wrap:wrap;
|
||||
}
|
||||
.kpi-meta-text{
|
||||
font-size:12px;
|
||||
color:#909399;
|
||||
}
|
||||
.kpi-meta-right{
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:6px;
|
||||
}
|
||||
.kpi-trend-arrow{
|
||||
font-size:12px;
|
||||
}
|
||||
.kpi-trend-arrow.is-up{ color:#f56c6c; }
|
||||
.kpi-trend-arrow.is-down{ color:#67c23a; }
|
||||
.kpi-trend-arrow.is-flat{ color:#909399; }
|
||||
|
||||
.kpi-divider{
|
||||
height:1px;
|
||||
background:#ebeef5;
|
||||
margin:12px 0;
|
||||
}
|
||||
|
||||
/* Footer */
|
||||
.kpi-footer{
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:space-between;
|
||||
gap:12px;
|
||||
}
|
||||
.kpi-footer-left{
|
||||
font-size:12px;
|
||||
color:#909399;
|
||||
}
|
||||
.kpi-footer-right{
|
||||
font-size:12px;
|
||||
color:#909399;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -3,116 +3,58 @@
|
||||
<view class="dashboard-page">
|
||||
<!-- 第一行:4 个 KPI 卡片 -->
|
||||
<view class="kpi-cards-row">
|
||||
<!-- 销售额卡片 -->
|
||||
<view class="kpi-card">
|
||||
<view class="kpi-card-content">
|
||||
<view class="kpi-card-header">
|
||||
<text class="kpi-card-title">销售额</text>
|
||||
<view class="kpi-card-tag">
|
||||
<text class="kpi-tag-text">今日</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="kpi-card-value">
|
||||
<text class="kpi-value-number">¥{{ formatNumber(kpiData.sales.today) }}</text>
|
||||
<view class="kpi-value-trend" :class="{ 'up': kpiData.sales.change > 0, 'down': kpiData.sales.change < 0 }">
|
||||
<text class="iconfont" :class="{ 'icon-up': kpiData.sales.change > 0, 'icon-down': kpiData.sales.change < 0 }"></text>
|
||||
<text class="kpi-trend-text">{{ Math.abs(kpiData.sales.change) }}%</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="kpi-card-footer">
|
||||
<text class="kpi-footer-text">昨日:¥{{ formatNumber(kpiData.sales.yesterday) }}</text>
|
||||
<text class="kpi-footer-text">本月累计:¥{{ formatNumber(kpiData.sales.monthTotal) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="kpi-card-icon">
|
||||
<text class="iconfont icon-sales"></text>
|
||||
</view>
|
||||
</view>
|
||||
<KpiMiniCard
|
||||
title="销售额"
|
||||
tagText="今日"
|
||||
valuePrefix="¥"
|
||||
:valueText="String(formatNumber(kpiData.sales.today))"
|
||||
:metaLeft="`昨日 ${formatNumber(kpiData.sales.yesterday)}`"
|
||||
:metaRight="`日环比 ${Math.abs(kpiData.sales.change)}%`"
|
||||
:trend="kpiData.sales.change > 0 ? 'up' : (kpiData.sales.change < 0 ? 'down' : 'flat')"
|
||||
:footerLeftText="'本月销售额'"
|
||||
:footerRightText="`¥${formatNumber(kpiData.sales.monthTotal)}`"
|
||||
/>
|
||||
|
||||
<!-- 访问量卡片 -->
|
||||
<view class="kpi-card">
|
||||
<view class="kpi-card-content">
|
||||
<view class="kpi-card-header">
|
||||
<text class="kpi-card-title">访问量</text>
|
||||
<view class="kpi-card-tag">
|
||||
<text class="kpi-tag-text">今日</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="kpi-card-value">
|
||||
<text class="kpi-value-number">{{ formatNumber(kpiData.visits.today) }}</text>
|
||||
<view class="kpi-value-trend" :class="{ 'up': kpiData.visits.change > 0, 'down': kpiData.visits.change < 0 }">
|
||||
<text class="iconfont" :class="{ 'icon-up': kpiData.visits.change > 0, 'icon-down': kpiData.visits.change < 0 }"></text>
|
||||
<text class="kpi-trend-text">{{ Math.abs(kpiData.visits.change) }}%</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="kpi-card-footer">
|
||||
<text class="kpi-footer-text">昨日:{{ formatNumber(kpiData.visits.yesterday) }}</text>
|
||||
<text class="kpi-footer-text">本月累计:{{ formatNumber(kpiData.visits.monthTotal) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="kpi-card-icon">
|
||||
<text class="iconfont icon-visits"></text>
|
||||
</view>
|
||||
</view>
|
||||
<KpiMiniCard
|
||||
title="用户访问量"
|
||||
tagText="今日"
|
||||
:valueText="String(formatNumber(kpiData.visits.today))"
|
||||
:metaLeft="`昨日 ${formatNumber(kpiData.visits.yesterday)}`"
|
||||
:metaRight="`日环比 ${Math.abs(kpiData.visits.change)}%`"
|
||||
:trend="kpiData.visits.change > 0 ? 'up' : (kpiData.visits.change < 0 ? 'down' : 'flat')"
|
||||
footerLeftText="本月访问量"
|
||||
:footerRightText="`${formatNumber(kpiData.visits.monthTotal)}Pv`"
|
||||
/>
|
||||
|
||||
<!-- 订单量卡片 -->
|
||||
<view class="kpi-card">
|
||||
<view class="kpi-card-content">
|
||||
<view class="kpi-card-header">
|
||||
<text class="kpi-card-title">订单量</text>
|
||||
<view class="kpi-card-tag">
|
||||
<text class="kpi-tag-text">今日</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="kpi-card-value">
|
||||
<text class="kpi-value-number">{{ formatNumber(kpiData.orders.today) }}</text>
|
||||
<view class="kpi-value-trend" :class="{ 'up': kpiData.orders.change > 0, 'down': kpiData.orders.change < 0 }">
|
||||
<text class="iconfont" :class="{ 'icon-up': kpiData.orders.change > 0, 'icon-down': kpiData.orders.change < 0 }"></text>
|
||||
<text class="kpi-trend-text">{{ Math.abs(kpiData.orders.change) }}%</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="kpi-card-footer">
|
||||
<text class="kpi-footer-text">昨日:{{ formatNumber(kpiData.orders.yesterday) }}</text>
|
||||
<text class="kpi-footer-text">本月累计:{{ formatNumber(kpiData.orders.monthTotal) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="kpi-card-icon">
|
||||
<text class="iconfont icon-orders"></text>
|
||||
</view>
|
||||
</view>
|
||||
<KpiMiniCard
|
||||
title="订单量"
|
||||
tagText="今日"
|
||||
:valueText="String(formatNumber(kpiData.orders.today))"
|
||||
:metaLeft="`昨日 ${formatNumber(kpiData.orders.yesterday)}`"
|
||||
:metaRight="`日环比 ${Math.abs(kpiData.orders.change)}%`"
|
||||
:trend="kpiData.orders.change > 0 ? 'up' : (kpiData.orders.change < 0 ? 'down' : 'flat')"
|
||||
footerLeftText="本月订单量"
|
||||
:footerRightText="`${formatNumber(kpiData.orders.monthTotal)}单`"
|
||||
/>
|
||||
|
||||
<!-- 新增用户卡片 -->
|
||||
<view class="kpi-card">
|
||||
<view class="kpi-card-content">
|
||||
<view class="kpi-card-header">
|
||||
<text class="kpi-card-title">新增用户</text>
|
||||
<view class="kpi-card-tag">
|
||||
<text class="kpi-tag-text">今日</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="kpi-card-value">
|
||||
<text class="kpi-value-number">{{ formatNumber(kpiData.users.today) }}</text>
|
||||
<view class="kpi-value-trend" :class="{ 'up': kpiData.users.change > 0, 'down': kpiData.users.change < 0 }">
|
||||
<text class="iconfont" :class="{ 'icon-up': kpiData.users.change > 0, 'icon-down': kpiData.users.change < 0 }"></text>
|
||||
<text class="kpi-trend-text">{{ Math.abs(kpiData.users.change) }}%</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="kpi-card-footer">
|
||||
<text class="kpi-footer-text">昨日:{{ formatNumber(kpiData.users.yesterday) }}</text>
|
||||
<text class="kpi-footer-text">本月累计:{{ formatNumber(kpiData.users.monthTotal) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="kpi-card-icon">
|
||||
<text class="iconfont icon-users"></text>
|
||||
</view>
|
||||
</view>
|
||||
<KpiMiniCard
|
||||
title="新增用户"
|
||||
tagText="今日"
|
||||
:valueText="String(formatNumber(kpiData.users.today))"
|
||||
:metaLeft="`昨日 ${formatNumber(kpiData.users.yesterday)}`"
|
||||
:metaRight="`日环比 ${Math.abs(kpiData.users.change)}%`"
|
||||
:trend="kpiData.users.change > 0 ? 'up' : (kpiData.users.change < 0 ? 'down' : 'flat')"
|
||||
footerLeftText="本月新增用户"
|
||||
:footerRightText="`${formatNumber(kpiData.users.monthTotal)}人`"
|
||||
/>
|
||||
</view>
|
||||
|
||||
|
||||
<!-- 第二行:订单统计图表 -->
|
||||
<view class="chart-section">
|
||||
<view class="admin-card">
|
||||
<view class="admin-card-header">
|
||||
<text class="admin-card-title">订单统计</text>
|
||||
<text class="admin-card-title">订单</text>
|
||||
<view class="chart-controls">
|
||||
<button
|
||||
v-for="period in chartPeriods"
|
||||
@@ -172,6 +114,7 @@
|
||||
<script setup lang="uts">
|
||||
import { ref } from 'vue'
|
||||
import AdminLayout from '@/layouts/admin/index.uvue'
|
||||
import KpiMiniCard from './components/KpiMiniCard.uvue'
|
||||
|
||||
// KPI 数据
|
||||
const kpiData = ref({
|
||||
@@ -244,39 +187,60 @@ const changePeriod = (period: string) => {
|
||||
}
|
||||
|
||||
/* ===== KPI 卡片行 ===== */
|
||||
.kpi-cards-row {
|
||||
display: flex;
|
||||
gap: 24px;
|
||||
margin-bottom: 24px;
|
||||
flex-wrap: wrap;
|
||||
/* 第一行:4 个 KPI 卡片一行 */
|
||||
.kpi-cards-row{
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr)); /* 一行 4 列等分 */
|
||||
gap: 16px;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.kpi-card {
|
||||
flex: 1;
|
||||
min-width: 280px;
|
||||
/* 卡片本体:不要写死宽高 */
|
||||
.kpi-card{
|
||||
|
||||
background-color: #ffffff;
|
||||
border: 1px solid #e8e8e8;
|
||||
border-radius: 8px;
|
||||
padding: 24px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
width: 100%;
|
||||
height: 200px; /* 你可以改成 140/160,别写死 200px */
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 20rpx;
|
||||
min-width: 200rpx;
|
||||
}
|
||||
|
||||
/* 响应式:宽度不够时变 2 列 / 1 列(可选) */
|
||||
@media (max-width: 1200px){
|
||||
.kpi-cards-row{ grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
||||
}
|
||||
@media (max-width: 768px){
|
||||
.kpi-cards-row{ grid-template-columns: 1fr; }
|
||||
}
|
||||
|
||||
|
||||
.kpi-card-content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.kpi-card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.kpi-card-title {
|
||||
position: absolute;
|
||||
|
||||
top: 10rpx;
|
||||
left: 5rpx;
|
||||
font-size: 16px;
|
||||
color: #666666;
|
||||
margin-right: 12px;
|
||||
@@ -381,21 +345,24 @@ const changePeriod = (period: string) => {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 24px;
|
||||
|
||||
.admin-card-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #262626;
|
||||
}
|
||||
|
||||
.admin-card-body {
|
||||
padding: 0 24px 24px 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.admin-card-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #262626;
|
||||
}
|
||||
|
||||
.admin-card-body {
|
||||
padding: 0 24px 24px 24px;
|
||||
}
|
||||
|
||||
/* ===== 图表控件 ===== */
|
||||
.chart-controls {
|
||||
display: flex;
|
||||
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
@@ -1,365 +0,0 @@
|
||||
<template>
|
||||
<view class="marketing-management">
|
||||
<!-- 页面标题 -->
|
||||
<view class="page-header">
|
||||
<text class="page-title">营销管理</text>
|
||||
<text class="page-subtitle">管理营销活动、优惠券、直播等营销工具</text>
|
||||
</view>
|
||||
|
||||
<!-- 营销工具导航 -->
|
||||
<view class="marketing-tools">
|
||||
<view class="tool-grid">
|
||||
<view class="tool-item" @click="go('/pages/mall/admin/store-coupon')">
|
||||
<view class="tool-icon">🎫</view>
|
||||
<text class="tool-name">优惠券管理</text>
|
||||
<text class="tool-desc">创建和管理优惠券活动</text>
|
||||
</view>
|
||||
<view class="tool-item" @click="go('/pages/mall/admin/store-seckill')">
|
||||
<view class="tool-icon">⚡</view>
|
||||
<text class="tool-name">秒杀活动</text>
|
||||
<text class="tool-desc">管理限时秒杀活动</text>
|
||||
</view>
|
||||
<view class="tool-item" @click="go('/pages/mall/admin/store-bargain')">
|
||||
<view class="tool-icon">🪓</view>
|
||||
<text class="tool-name">砍价活动</text>
|
||||
<text class="tool-desc">管理砍价促销活动</text>
|
||||
</view>
|
||||
<view class="tool-item" @click="go('/pages/mall/admin/store-combination')">
|
||||
<view class="tool-icon">👥</view>
|
||||
<text class="tool-name">拼团活动</text>
|
||||
<text class="tool-desc">管理拼团购买活动</text>
|
||||
</view>
|
||||
<view class="tool-item" @click="go('/pages/mall/admin/live-broadcast')">
|
||||
<view class="tool-icon">📺</view>
|
||||
<text class="tool-name">直播管理</text>
|
||||
<text class="tool-desc">管理直播带货活动</text>
|
||||
</view>
|
||||
<view class="tool-item" @click="go('/pages/mall/admin/channel-code')">
|
||||
<view class="tool-icon">📱</view>
|
||||
<text class="tool-name">渠道码</text>
|
||||
<text class="tool-desc">生成和管理推广渠道码</text>
|
||||
</view>
|
||||
<view class="tool-item" @click="go('/pages/mall/admin/store-integral')">
|
||||
<view class="tool-icon">💎</view>
|
||||
<text class="tool-name">积分商品</text>
|
||||
<text class="tool-desc">管理积分兑换商品</text>
|
||||
</view>
|
||||
<view class="tool-item" @click="go('/pages/mall/admin/sign-in')">
|
||||
<view class="tool-icon">📅</view>
|
||||
<text class="tool-name">签到活动</text>
|
||||
<text class="tool-desc">管理用户签到奖励</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 营销数据统计 -->
|
||||
<view class="marketing-stats">
|
||||
<text class="section-title">营销数据概览</text>
|
||||
<view class="stats-grid">
|
||||
<view class="stat-card">
|
||||
<text class="stat-value">{{ stats.totalCoupons }}</text>
|
||||
<text class="stat-label">优惠券发放</text>
|
||||
</view>
|
||||
<view class="stat-card">
|
||||
<text class="stat-value">{{ stats.activeActivities }}</text>
|
||||
<text class="stat-label">进行中活动</text>
|
||||
</view>
|
||||
<view class="stat-card">
|
||||
<text class="stat-value">{{ stats.totalParticipants }}</text>
|
||||
<text class="stat-label">活动参与人数</text>
|
||||
</view>
|
||||
<view class="stat-card">
|
||||
<text class="stat-value">¥{{ stats.marketingRevenue }}</text>
|
||||
<text class="stat-label">营销收入</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 快捷操作 -->
|
||||
<view class="quick-actions">
|
||||
<text class="section-title">快捷操作</text>
|
||||
<view class="action-buttons">
|
||||
<button class="action-btn primary" @click="createActivity">创建新活动</button>
|
||||
<button class="action-btn secondary" @click="viewReports">查看营销报表</button>
|
||||
<button class="action-btn info" @click="manageCoupons">批量管理优惠券</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
|
||||
// 响应式数据
|
||||
const stats = ref({
|
||||
totalCoupons: 0,
|
||||
activeActivities: 0,
|
||||
totalParticipants: 0,
|
||||
marketingRevenue: '0.00'
|
||||
})
|
||||
|
||||
// 统一的导航方法
|
||||
const go = (url: string) => {
|
||||
// 1) 目标页面必须是非 tabBar 页面
|
||||
// 2) 必须在 pages.json / subPackages 注册
|
||||
uni.navigateTo({ url })
|
||||
}
|
||||
|
||||
// 快捷操作方法
|
||||
const createActivity = () => {
|
||||
uni.showActionSheet({
|
||||
itemList: ['优惠券活动', '秒杀活动', '砍价活动', '拼团活动', '直播活动'],
|
||||
success: (res) => {
|
||||
const activities = [
|
||||
'/pages/mall/admin/store-coupon',
|
||||
'/pages/mall/admin/store-seckill',
|
||||
'/pages/mall/admin/store-bargain',
|
||||
'/pages/mall/admin/store-combination',
|
||||
'/pages/mall/admin/live-broadcast'
|
||||
]
|
||||
if (activities[res.tapIndex]) {
|
||||
go(activities[res.tapIndex])
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const viewReports = () => {
|
||||
uni.showToast({
|
||||
title: '营销报表功能开发中',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
|
||||
const manageCoupons = () => {
|
||||
go('/pages/mall/admin/store-coupon')
|
||||
}
|
||||
|
||||
// 页面初始化
|
||||
onMounted(() => {
|
||||
loadMarketingStats()
|
||||
})
|
||||
|
||||
// 加载营销统计数据
|
||||
const loadMarketingStats = async () => {
|
||||
try {
|
||||
// 这里应该调用实际的API
|
||||
// 暂时使用模拟数据
|
||||
stats.value = {
|
||||
totalCoupons: 12580,
|
||||
activeActivities: 8,
|
||||
totalParticipants: 45620,
|
||||
marketingRevenue: '128500.00'
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载营销统计失败:', error)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.marketing-management {
|
||||
padding: 30rpx;
|
||||
background-color: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
// 页面头部
|
||||
.page-header {
|
||||
background-color: #fff;
|
||||
padding: 40rpx;
|
||||
border-radius: 16rpx;
|
||||
margin-bottom: 30rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
|
||||
.page-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #212529;
|
||||
display: block;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.page-subtitle {
|
||||
font-size: 26rpx;
|
||||
color: #6c757d;
|
||||
}
|
||||
}
|
||||
|
||||
// 营销工具网格
|
||||
.marketing-tools {
|
||||
background-color: #fff;
|
||||
padding: 30rpx;
|
||||
border-radius: 16rpx;
|
||||
margin-bottom: 30rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
|
||||
.tool-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.tool-item {
|
||||
width: calc(50% - 10rpx);
|
||||
background-color: #f8f9fa;
|
||||
padding: 30rpx 20rpx;
|
||||
border-radius: 12rpx;
|
||||
text-align: center;
|
||||
transition: all 0.2s;
|
||||
|
||||
&:hover {
|
||||
background-color: #e3f2fd;
|
||||
transform: translateY(-2rpx);
|
||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.tool-icon {
|
||||
font-size: 48rpx;
|
||||
margin-bottom: 15rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.tool-name {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
color: #212529;
|
||||
margin-bottom: 8rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.tool-desc {
|
||||
font-size: 22rpx;
|
||||
color: #6c757d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 营销数据统计
|
||||
.marketing-stats {
|
||||
background-color: #fff;
|
||||
padding: 30rpx;
|
||||
border-radius: 16rpx;
|
||||
margin-bottom: 30rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #212529;
|
||||
margin-bottom: 30rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.stats-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
flex: 1;
|
||||
min-width: 200rpx;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
padding: 30rpx 20rpx;
|
||||
border-radius: 12rpx;
|
||||
text-align: center;
|
||||
color: white;
|
||||
|
||||
.stat-value {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
display: block;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 24rpx;
|
||||
opacity: 0.9;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 快捷操作
|
||||
.quick-actions {
|
||||
background-color: #fff;
|
||||
padding: 30rpx;
|
||||
border-radius: 16rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #212529;
|
||||
margin-bottom: 30rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
flex: 1;
|
||||
min-width: 200rpx;
|
||||
padding: 20rpx;
|
||||
border-radius: 12rpx;
|
||||
font-size: 26rpx;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
|
||||
&.primary {
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
|
||||
&:hover {
|
||||
background-color: #0056b3;
|
||||
}
|
||||
}
|
||||
|
||||
&.secondary {
|
||||
background-color: #6c757d;
|
||||
color: white;
|
||||
|
||||
&:hover {
|
||||
background-color: #545b62;
|
||||
}
|
||||
}
|
||||
|
||||
&.info {
|
||||
background-color: #17a2b8;
|
||||
color: white;
|
||||
|
||||
&:hover {
|
||||
background-color: #138496;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 响应式设计
|
||||
@media (max-width: 750rpx) {
|
||||
.tool-grid {
|
||||
flex-direction: column;
|
||||
|
||||
.tool-item {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.stats-grid {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
flex-direction: column;
|
||||
|
||||
.action-btn {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
28
pages/mall/admin/marketing/coupon/list.uvue
Normal file
28
pages/mall/admin/marketing/coupon/list.uvue
Normal file
@@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<text class="title">优惠券列表</text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
// Minimal script
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.container {
|
||||
padding: 40rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 48rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.content {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
}
|
||||
</style>
|
||||
28
pages/mall/admin/marketing/coupon/receive.uvue
Normal file
28
pages/mall/admin/marketing/coupon/receive.uvue
Normal file
@@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<text class="title">用户领取记录</text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
// Minimal script
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.container {
|
||||
padding: 40rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 48rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.content {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
}
|
||||
</style>
|
||||
28
pages/mall/admin/marketing/points/index.uvue
Normal file
28
pages/mall/admin/marketing/points/index.uvue
Normal file
@@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<text class="title">积分管理</text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
// Minimal script
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.container {
|
||||
padding: 40rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 48rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.content {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
}
|
||||
</style>
|
||||
28
pages/mall/admin/marketing/signin/record.uvue
Normal file
28
pages/mall/admin/marketing/signin/record.uvue
Normal file
@@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<text class="title">签到记录</text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
// Minimal script
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.container {
|
||||
padding: 40rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 48rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.content {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
}
|
||||
</style>
|
||||
28
pages/mall/admin/marketing/signin/rule.uvue
Normal file
28
pages/mall/admin/marketing/signin/rule.uvue
Normal file
@@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<text class="title">签到规则</text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
// Minimal script
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.container {
|
||||
padding: 40rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 48rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.content {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user