sql数据流,amdin业务逻辑接入
This commit is contained in:
@@ -5,10 +5,12 @@
|
||||
<view class="filter-card border-shadow">
|
||||
<view class="filter-item">
|
||||
<text class="label-txt">时间选择:</text>
|
||||
<view class="date-picker-mock">
|
||||
<text class="calendar-ic">📅</text>
|
||||
<text class="date-range">2026/01/05 - 2026/02/03</text>
|
||||
</view>
|
||||
<AnalyticsDateRangePicker
|
||||
:initialStartDate="startDate"
|
||||
:initialEndDate="endDate"
|
||||
@apply="onApplyRange"
|
||||
@clear="onClearRange"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -19,7 +21,7 @@
|
||||
<text class="sc-icon">💠</text>
|
||||
</view>
|
||||
<view class="sc-right">
|
||||
<text class="sc-val">744904340.25</text>
|
||||
<text class="sc-val">{{ statsTotal.current.toFixed(2) }}</text>
|
||||
<text class="sc-label">当前积分</text>
|
||||
</view>
|
||||
</view>
|
||||
@@ -28,7 +30,7 @@
|
||||
<text class="sc-icon">🪙</text>
|
||||
</view>
|
||||
<view class="sc-right">
|
||||
<text class="sc-val">59026484</text>
|
||||
<text class="sc-val">{{ statsTotal.income.toFixed(2) }}</text>
|
||||
<text class="sc-label">累计总积分</text>
|
||||
</view>
|
||||
</view>
|
||||
@@ -37,7 +39,7 @@
|
||||
<text class="sc-icon">💎</text>
|
||||
</view>
|
||||
<view class="sc-right">
|
||||
<text class="sc-val">3189</text>
|
||||
<text class="sc-val">{{ statsTotal.expend.toFixed(2) }}</text>
|
||||
<text class="sc-label">累计消耗积分</text>
|
||||
</view>
|
||||
</view>
|
||||
@@ -141,43 +143,102 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
import { ref } from 'vue'
|
||||
import { ref, onMounted, reactive } from 'vue'
|
||||
import AnalyticsPieChart from '@/components/analytics/AnalyticsPieChart.uvue'
|
||||
import AnalyticsMultiLineChart from '@/components/analytics/AnalyticsMultiLineChart.uvue'
|
||||
import AnalyticsDateRangePicker from '@/components/analytics/AnalyticsDateRangePicker.uvue'
|
||||
import { fetchIntegralStats, IntegralStats } from '@/services/admin/marketingService.uts'
|
||||
|
||||
const dates = ['01-05', '01-06', '01-07', '01-08', '01-09', '01-10', '01-11', '01-12', '01-13', '01-14', '01-15', '01-16', '01-17', '01-18', '01-19', '01-20', '01-21', '01-22', '01-23', '01-24', '01-25', '01-26', '01-27', '01-28', '01-29', '01-30', '01-31', '02-01', '02-02', '02-03']
|
||||
const startDate = ref('')
|
||||
const endDate = ref('')
|
||||
const isLoading = ref(false)
|
||||
|
||||
const trendSeries = [
|
||||
{
|
||||
name: '积分积累',
|
||||
data: [120, 132, 101, 134, 90, 230, 210, 182, 191, 234, 290, 330, 310, 220, 182, 191, 234, 290, 330, 310, 220, 182, 191, 234, 290, 330, 310, 220, 182, 191],
|
||||
color: '#409eff'
|
||||
},
|
||||
{
|
||||
name: '积分消耗',
|
||||
data: [220, 182, 191, 234, 290, 330, 310, 120, 132, 101, 134, 90, 230, 210, 120, 132, 101, 134, 90, 230, 210, 120, 132, 101, 134, 90, 230, 210, 120, 132],
|
||||
color: '#19be6b'
|
||||
}
|
||||
]
|
||||
const statsTotal = reactive({
|
||||
current: 0,
|
||||
income: 0,
|
||||
expend: 0
|
||||
})
|
||||
|
||||
const dates = ref<string[]>([])
|
||||
const trendSeries = ref<any[]>([])
|
||||
|
||||
const sourceStyle = ref('pie')
|
||||
const consumeStyle = ref('pie')
|
||||
|
||||
const sourceData = [
|
||||
{ label: '后台赠送', value: 59021632, percent: 100, color: '#778899' },
|
||||
{ label: '签到获得', value: 3620, percent: 0, color: '#FFB980' },
|
||||
{ label: '九宫格抽奖', value: 0, percent: 0, color: '#FF7F50' },
|
||||
{ label: '商品赠送', value: 0, percent: 0, color: '#5AB1EF' },
|
||||
{ label: '订单赠送', value: 0, percent: 0, color: '#2EC7C9' }
|
||||
]
|
||||
const sourceData = ref<any[]>([])
|
||||
const consumeData = ref<any[]>([])
|
||||
|
||||
const consumeData = [
|
||||
{ label: '订单抵扣', value: 3051, percent: 95.7, color: '#5AB1EF' },
|
||||
{ label: '九宫格抽奖', value: 138, percent: 4.3, color: '#2EC7C9' },
|
||||
{ label: '兑换商品', value: 0, percent: 0, color: '#FF7F50' },
|
||||
{ label: '后台减少', value: 0, percent: 0, color: '#FFB980' },
|
||||
{ label: '退款退回', value: 0, percent: 0, color: '#D87A80' }
|
||||
]
|
||||
onMounted(() => {
|
||||
// 默认最近 30 天
|
||||
const end = new Date()
|
||||
const start = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000)
|
||||
startDate.value = start.toISOString().substring(0, 10)
|
||||
endDate.value = end.toISOString().substring(0, 10)
|
||||
|
||||
loadData()
|
||||
})
|
||||
|
||||
async function loadData() {
|
||||
isLoading.value = true
|
||||
try {
|
||||
const st = startDate.value ? (startDate.value + ' 00:00:00') : null
|
||||
const et = endDate.value ? (endDate.value + ' 23:59:59') : null
|
||||
|
||||
const res = await fetchIntegralStats(st!, et!)
|
||||
if (res != null) {
|
||||
// 1. 核心指标
|
||||
statsTotal.current = res.totals.current
|
||||
statsTotal.income = res.totals.income
|
||||
statsTotal.expend = res.totals.expend
|
||||
|
||||
// 2. 趋势图
|
||||
dates.value = res.trend.map(t => t.date_group)
|
||||
trendSeries.value = [
|
||||
{
|
||||
name: '积分积累',
|
||||
data: res.trend.map(t => t.income),
|
||||
color: '#409eff'
|
||||
},
|
||||
{
|
||||
name: '积分消耗',
|
||||
data: res.trend.map(t => t.expend),
|
||||
color: '#19be6b'
|
||||
}
|
||||
]
|
||||
|
||||
// 3. 来源与消耗分布
|
||||
sourceData.value = res.sources.map(s => ({
|
||||
label: s.label,
|
||||
value: s.value,
|
||||
percent: s.percent,
|
||||
color: '#409eff' // 这里可以根据类型映射不同颜色
|
||||
}))
|
||||
|
||||
consumeData.value = res.consumes.map(c => ({
|
||||
label: c.label,
|
||||
value: c.value,
|
||||
percent: c.percent,
|
||||
color: '#19be6b'
|
||||
}))
|
||||
}
|
||||
} catch (e) {
|
||||
uni.showToast({ title: '加载统计失败', icon: 'none' })
|
||||
} finally {
|
||||
isLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function onApplyRange(payload : any) {
|
||||
startDate.value = payload?.start ?? ''
|
||||
endDate.value = payload?.end ?? ''
|
||||
loadData()
|
||||
}
|
||||
|
||||
function onClearRange() {
|
||||
startDate.value = ''
|
||||
endDate.value = ''
|
||||
loadData()
|
||||
}
|
||||
|
||||
const toggleSourceStyle = () => {
|
||||
sourceStyle.value = sourceStyle.value === 'pie' ? 'list' : 'pie'
|
||||
|
||||
Reference in New Issue
Block a user