Files
huangjingfen/pro_v3.5.1/view/admin/src/pages/hjf/pointsLog/index.vue
apple f6227c0253 feat: 黄精粉前端功能集成 + 个人中心/资产/公排页面优化 + 去除admin copyright
主要改动:
- 个人中心: 去除HjfMemberBadge徽章, 会员等级改显示vip_name,
  "我的资产"/"公排查询"导航项改为与member-points一致风格
- 我的资产页面: 去除HjfMemberBadge, 美化卡片圆角和阴影
- 公排查询页面: 美化顶部渐变和订单卡片样式
- Admin登录页和后台布局: 彻底删除footer copyright信息
- 新增黄精粉业务页面/组件/API/Mock数据(Phase 1)
- 新增PHP环境配置文档和启动脚本

Made-with: Cursor
2026-03-13 00:49:22 +08:00

361 lines
8.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<!-- 积分释放日志 -->
<div>
<!-- 搜索区 -->
<Card :bordered="false" dis-hover class="ivu-mt" :padding="0">
<div class="new_card_pd">
<Form
ref="formValidate"
:label-width="labelWidth"
:label-position="labelPosition"
inline
class="tabform"
@submit.native.prevent
>
<FormItem label="昵称/ID">
<Input
v-model="formValidate.keyword"
placeholder="请输入用户昵称或ID"
class="input-add"
clearable
/>
</FormItem>
<FormItem label="类型:">
<Select
v-model="formValidate.type"
placeholder="全部类型"
class="input-add"
clearable
>
<Option value="release">释放</Option>
<Option value="reward">奖励</Option>
<Option value="consume">消费</Option>
</Select>
</FormItem>
<FormItem label="时间:">
<DatePicker
:editable="false"
:value="timeVal"
format="yyyy/MM/dd"
type="daterange"
placement="bottom-start"
placeholder="自定义日期范围"
class="input-add"
:options="dateOptions"
@on-change="onChangeTime"
/>
</FormItem>
<FormItem>
<Button type="primary" class="mr14" @click="handleSearch">查询</Button>
<Button @click="handleReset">重置</Button>
</FormItem>
</Form>
</div>
</Card>
<!-- 今日统计 -->
<Card :bordered="false" dis-hover class="ivu-mt">
<div class="statistics-bar">
<div class="stat-item">
<span class="stat-label">今日释放总量</span>
<span class="stat-value stat-value--primary">{{ statistics.total_released_today | numFormat }}</span>
<span class="stat-unit">积分</span>
</div>
<div class="stat-divider" />
<div class="stat-item">
<span class="stat-label">今日释放用户数</span>
<span class="stat-value">{{ statistics.total_users_released | numFormat }}</span>
<span class="stat-unit"></span>
</div>
</div>
</Card>
<!-- 数据表格 -->
<Card :bordered="false" dis-hover class="ivu-mt">
<Table
ref="table"
:columns="columns"
:data="tabList"
:loading="loading"
no-data-text="暂无数据"
no-filtered-data-text="暂无筛选结果"
>
<!-- 用户信息列 -->
<template slot-scope="{ row }" slot="user">
<div class="user-info">
<div class="user-name">{{ row.nickname }}</div>
<div class="user-meta">
<span class="user-phone">{{ row.phone }}</span>
<span class="user-id">UID: {{ row.uid }}</span>
</div>
</div>
</template>
<!-- 积分数量列 -->
<template slot-scope="{ row }" slot="points">
<span :class="pointsClass(row.type)">{{ pointsPrefix(row.type) }}{{ row.points | numFormat }}</span>
</template>
<!-- 类型列 -->
<template slot-scope="{ row }" slot="type">
<Tag :color="typeColor(row.type)">{{ row.type_text }}</Tag>
</template>
<!-- 状态列 -->
<template slot-scope="{ row }" slot="status">
<Badge
:status="row.status === 1 ? 'success' : 'processing'"
:text="row.status_text"
/>
</template>
</Table>
<!-- 分页 -->
<div class="acea-row row-right page">
<Page
:total="total"
:current="formValidate.page"
:page-size="formValidate.limit"
show-elevator
show-total
@on-change="pageChange"
/>
</div>
</Card>
</div>
</template>
<script>
import { mapState } from 'vuex';
import { pointsReleaseLogApi } from '@/api/hjfPoints.js';
const DATE_SHORTCUTS = [
{
text: '今天',
value() {
const d = new Date();
d.setHours(0, 0, 0, 0);
return [d, new Date()];
}
},
{
text: '近7天',
value() {
const end = new Date();
const start = new Date();
start.setDate(start.getDate() - 6);
start.setHours(0, 0, 0, 0);
return [start, end];
}
},
{
text: '近1个月',
value() {
const end = new Date();
const start = new Date();
start.setMonth(start.getMonth() - 1);
start.setHours(0, 0, 0, 0);
return [start, end];
}
}
];
export default {
name: 'HjfPointsLog',
filters: {
numFormat(val) {
const n = Number(val);
if (isNaN(n)) return '0';
return n.toLocaleString('zh-CN');
}
},
data() {
return {
timeVal: [],
total: 0,
loading: false,
tabList: [],
statistics: {
total_released_today: 0,
total_users_released: 0
},
formValidate: {
keyword: '',
type: '',
date_range: '',
page: 1,
limit: 20
},
dateOptions: { shortcuts: DATE_SHORTCUTS },
columns: [
{
title: '用户信息',
slot: 'user',
minWidth: 200
},
{
title: '积分数量',
slot: 'points',
minWidth: 120
},
{
title: '类型',
slot: 'type',
minWidth: 100
},
{
title: '状态',
slot: 'status',
minWidth: 100
},
{
title: '时间',
key: 'add_time',
minWidth: 170
}
]
};
},
computed: {
...mapState('admin/layout', ['isMobile']),
labelWidth() {
return this.isMobile ? undefined : 80;
},
labelPosition() {
return this.isMobile ? 'top' : 'right';
}
},
mounted() {
this.getList();
},
methods: {
getList() {
this.loading = true;
pointsReleaseLogApi(this.formValidate)
.then(res => {
const data = res.data;
this.tabList = data.list || [];
this.total = data.count || 0;
if (data.statistics) {
this.statistics = data.statistics;
}
})
.catch(err => {
this.$Message.error((err && err.msg) || '加载失败,请重试');
})
.finally(() => {
this.loading = false;
});
},
handleSearch() {
this.formValidate.page = 1;
this.getList();
},
handleReset() {
this.timeVal = [];
this.formValidate.keyword = '';
this.formValidate.type = '';
this.formValidate.date_range = '';
this.formValidate.page = 1;
this.getList();
},
onChangeTime(e) {
this.timeVal = e;
this.formValidate.date_range = e[0] ? e.join('-') : '';
this.formValidate.page = 1;
this.getList();
},
pageChange(index) {
this.formValidate.page = index;
this.getList();
},
typeColor(type) {
const map = { release: 'green', reward: 'blue', consume: 'orange' };
return map[type] || 'default';
},
pointsClass(type) {
return type === 'consume' ? 'points-consume' : 'points-income';
},
pointsPrefix(type) {
return type === 'consume' ? '-' : '+';
}
}
};
</script>
<style scoped lang="stylus">
.statistics-bar
display flex
align-items center
padding 8px 0
.stat-item
display flex
align-items baseline
gap 6px
.stat-label
font-size 13px
color #808695
.stat-value
font-size 22px
font-weight 600
color #2d2d2d
.stat-value--primary
color #19be6b
.stat-unit
font-size 12px
color #aaa
.stat-divider
width 1px
height 32px
background #e8eaec
margin 0 32px
.user-info
line-height 1.4
.user-name
font-weight 500
color #2d2d2d
.user-meta
font-size 12px
color #999
.user-phone
margin-right 8px
.points-income
font-weight 600
color #19be6b
.points-consume
font-weight 600
color #ed4014
.tabform .ivu-form-item
margin-bottom 10px
.page
margin-top 16px
</style>