javacodeadmin/ruoyi-ui/src/views/system/Users/index.vue

1150 lines
34 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 class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="昵称" prop="name">
<el-input
v-model="queryParams.name"
placeholder="请输入昵称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="电话" prop="phone">
<el-input
v-model="queryParams.phone"
placeholder="请输入电话"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable>
<el-option
v-for="dict in dict.type.users_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['system:users:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['system:users:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['system:users:remove']"
>删除</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="usersList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="ID" align="center" width="55" prop="id" />
<el-table-column label="昵称" align="center" prop="name" />
<el-table-column label="电话" align="center" prop="phone" />
<el-table-column label="头像" align="center" prop="avatar" width="100">
<template slot-scope="scope">
<image-preview :src="scope.row.avatar" :width="50" :height="50"/>
</template>
</el-table-column>
<el-table-column label="会员状态" align="center" prop="ismember">
<template slot-scope="scope">
<span>{{ scope.row.ismember === 1 ? '是' : '否' }}</span>
</template>
</el-table-column>
<el-table-column label="会员开始时间" align="center" prop="memberBegin" width="160">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.memberBegin, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="会员结束时间" align="center" prop="memberEnd" width="160">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.memberEnd, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="消费金" align="center" prop="consumption">
<template slot-scope="scope">
<el-button type="text" @click="showBenefitLogs(scope.row.id, 2)">
¥{{ parseFloat(scope.row.consumption || 0).toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) }}
</el-button>
</template>
</el-table-column>
<el-table-column label="服务金" align="center" prop="servicefee">
<template slot-scope="scope">
<el-button type="text" @click="showBenefitLogs(scope.row.id, 1)" style="color: #E6A23C; font-weight: bold; font-size: 14px;">
¥{{ formatMoney(scope.row.servicefee) }}
</el-button>
</template>
</el-table-column>
<el-table-column label="余额" align="center" prop="balance">
<template slot-scope="scope">
<el-button type="text" @click="showBalanceLogs(scope.row.id)" :style="{ color: scope.row.balance > 0 ? '#67C23A' : '#E6A23C', fontWeight: 'bold', fontSize: '14px' }">
¥{{ formatMoney(scope.row.balance) }}
</el-button>
</template>
</el-table-column>
<el-table-column label="状态" align="center" prop="status">
<template slot-scope="scope">
<dict-tag :options="dict.type.users_status" :value="scope.row.status"/>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createdAt" width="160">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createdAt, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['system:users:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['system:users:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改用户列表对话框 -->
<el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-form-item label="ID" v-if="form.id">
<el-input v-model="form.id" disabled />
</el-form-item>
<el-form-item label="昵称" prop="name">
<el-input v-model="form.name" placeholder="请输入昵称" />
</el-form-item>
<el-form-item label="电话" prop="phone">
<el-input v-model="form.phone" placeholder="请输入电话" />
</el-form-item>
<el-form-item label="头像" prop="avatar">
<image-upload v-model="form.avatar" :limit="1"/>
</el-form-item>
<el-row>
<el-col :span="12">
<el-form-item label="可用积分">
<div class="integral-input">
<el-button icon="el-icon-minus" @click="decreaseIntegral"></el-button>
<el-input-number
v-model="form.integral"
:min="0"
:controls="false"
placeholder="请输入可用积分" />
<el-button icon="el-icon-plus" @click="increaseIntegral"></el-button>
</div>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="累计积分">
<div class="integral-input">
<el-button icon="el-icon-minus" @click="decreaseTotalIntegral"></el-button>
<el-input-number
v-model="form.totalIntegral"
:min="0"
:controls="false"
placeholder="请输入累计积分" />
<el-button icon="el-icon-plus" @click="increaseTotalIntegral"></el-button>
</div>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="创建时间" prop="createdAt" >
<el-date-picker clearable
disabled
v-model="form.createdAt"
type="date"
value-format="yyyy-MM-dd"
placeholder="自动获取">
</el-date-picker>
</el-form-item>
<el-form-item label="修改时间" prop="updatedAt" disabled>
<el-date-picker clearable
disabled
v-model="form.updatedAt"
type="date"
value-format="yyyy-MM-dd"
placeholder="自动获取">
</el-date-picker>
</el-form-item>
<el-form-item label="生日" prop="birthday">
<el-date-picker
v-model="form.birthday"
type="date"
value-format="yyyy-MM-dd"
placeholder="生日">
</el-date-picker>
</el-form-item>
<el-row>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
<el-button icon="el-icon-refresh" @click="resetForm('form')">重置</el-button>
</div>
</el-dialog>
<!-- 日志记录弹窗 -->
<el-dialog :title="logTitle" :visible.sync="logVisible" width="1000px" append-to-body>
<!-- 统计信息卡片 -->
<el-row :gutter="16" class="mb8">
<el-col :span="8">
<el-card shadow="hover" class="summary-card income-card">
<div class="summary-content">
<div class="summary-icon">
<i class="el-icon-plus"></i>
</div>
<div class="summary-info">
<div class="summary-title">总收入</div>
<div class="summary-value">¥{{ formatMoney(totalIncome) }}</div>
</div>
</div>
</el-card>
</el-col>
<el-col :span="8">
<el-card shadow="hover" class="summary-card expense-card">
<div class="summary-content">
<div class="summary-icon">
<i class="el-icon-minus"></i>
</div>
<div class="summary-info">
<div class="summary-title">总支出</div>
<div class="summary-value">¥{{ formatMoney(totalExpense) }}</div>
</div>
</div>
</el-card>
</el-col>
<el-col :span="8">
<el-card shadow="hover" class="summary-card net-card">
<div class="summary-content">
<div class="summary-icon">
<i class="el-icon-d-arrow-right"></i>
</div>
<div class="summary-info">
<div class="summary-title">净收入</div>
<div class="summary-value" :class="{ 'negative': totalIncome - totalExpense < 0 }">
¥{{ formatMoney(totalIncome - totalExpense) }}
</div>
</div>
</div>
</el-card>
</el-col>
</el-row>
<!-- 筛选工具栏 -->
<el-row :gutter="10" class="mb8">
<el-col :span="6">
<el-select v-model="logFilter.type" placeholder="变动类型" clearable @change="filterLogs">
<el-option label="全部" value=""></el-option>
<el-option label="收入" value="1"></el-option>
<el-option label="支出" value="2"></el-option>
</el-select>
</el-col>
<el-col :span="6" v-if="currentType === null">
<el-select v-model="logFilter.consumptionType" placeholder="消费类别" clearable @change="filterLogs">
<el-option label="全部" value=""></el-option>
<el-option label="商城消费" value="0"></el-option>
<el-option label="服务类消费" value="1"></el-option>
<el-option label="其他消费" value="2"></el-option>
</el-select>
</el-col>
<el-col :span="8">
<el-date-picker
v-model="logFilter.dateRange"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="yyyy-MM-dd"
@change="filterLogs"
>
</el-date-picker>
</el-col>
<el-col :span="4">
<el-button type="primary" icon="el-icon-search" @click="filterLogs">筛选</el-button>
</el-col>
</el-row>
<!-- 表格 -->
<el-table
v-loading="logLoading"
:data="filteredLogList"
style="width: 100%"
:row-class-name="tableRowClassName"
stripe
border
>
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column label="变动类型" align="center" width="80">
<template slot-scope="scope">
<el-tag
:type="getChangeTypeTag(scope.row)"
size="small"
>
{{ getChangeTypeText(scope.row) }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="变动金额" align="center" width="120">
<template slot-scope="scope">
<span
:class="{
'amount-positive': getAmountValue(scope.row) > 0,
'amount-negative': getAmountValue(scope.row) < 0
}"
class="amount-text"
>
{{ getAmountValue(scope.row) > 0 ? '+' : '' }}¥{{ Math.abs(getAmountValue(scope.row)).toFixed(2) }}
</span>
</template>
</el-table-column>
<el-table-column label="变动前金额" align="center" width="120">
<template slot-scope="scope">
<span class="amount-text">¥{{ getBeforeAmount(scope.row) }}</span>
</template>
</el-table-column>
<el-table-column label="变动后金额" align="center" width="120">
<template slot-scope="scope">
<span class="amount-text">¥{{ getAfterAmount(scope.row) }}</span>
</template>
</el-table-column>
<el-table-column label="关联订单" align="center" width="100" v-if="currentType !== null">
<template slot-scope="scope">
<el-button
v-if="scope.row.orderid"
type="text"
size="small"
@click="viewOrder(scope.row.orderid)"
>
#{{ scope.row.orderid }}
</el-button>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="订单金额" align="center" width="100" v-if="currentType !== null">
<template slot-scope="scope">
<span v-if="scope.row.ordermoney">¥{{ parseFloat(scope.row.ordermoney).toFixed(2) }}</span>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="消费类别" align="center" width="100" v-if="currentType === null">
<template slot-scope="scope">
<el-tag
:type="getConsumptionTypeTag(scope.row.consumptiontype)"
size="small"
>
{{ getConsumptionTypeText(scope.row.consumptiontype) }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="变动说明" align="center" prop="reamk" min-width="200" :show-overflow-tooltip="true">
<template slot-scope="scope">
<div class="remark-content">
<i class="el-icon-info"></i>
{{ scope.row.reamk || scope.row.remark || '无备注' }}
</div>
</template>
</el-table-column>
<el-table-column label="变动时间" align="center" width="160">
<template slot-scope="scope">
<div class="time-content">
<i class="el-icon-time"></i>
{{ formatDateTime(scope.row) }}
</div>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="80" fixed="right">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-view"
@click="viewLogDetail(scope.row)"
>
详情
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<pagination
v-show="logTotal>0"
:total="logTotal"
:page.sync="logQuery.pageNum"
:limit.sync="logQuery.pageSize"
@pagination="getLogList"
/>
<!-- 操作按钮 -->
<div slot="footer" class="dialog-footer">
<el-button @click="exportLogs" type="primary" plain>
<i class="el-icon-download"></i>
导出记录
</el-button>
<el-button @click="logVisible = false">关闭</el-button>
</div>
</el-dialog>
<!-- 日志详情弹窗 -->
<el-dialog title="记录详情" :visible.sync="logDetailVisible" width="600px" append-to-body>
<el-descriptions :column="2" border>
<el-descriptions-item label="记录ID">{{ logDetail.id }}</el-descriptions-item>
<el-descriptions-item label="变动类型">
<el-tag :type="getChangeTypeTag(logDetail)" size="small">
{{ getChangeTypeText(logDetail) }}
</el-tag>
</el-descriptions-item>
<el-descriptions-item label="变动金额">
<span :class="{
'amount-positive': getAmountValue(logDetail) > 0,
'amount-negative': getAmountValue(logDetail) < 0
}">
{{ getAmountValue(logDetail) > 0 ? '+' : '' }}¥{{ Math.abs(getAmountValue(logDetail)).toFixed(2) }}
</span>
</el-descriptions-item>
<el-descriptions-item label="变动前金额">
¥{{ getBeforeAmount(logDetail) }}
</el-descriptions-item>
<el-descriptions-item label="变动后金额">
¥{{ getAfterAmount(logDetail) }}
</el-descriptions-item>
<el-descriptions-item label="关联订单" v-if="logDetail.orderid">
<el-button type="text" @click="viewOrder(logDetail.orderid)">#{{ logDetail.orderid }}</el-button>
</el-descriptions-item>
<el-descriptions-item label="订单金额" v-if="logDetail.ordermoney">
¥{{ parseFloat(logDetail.ordermoney).toFixed(2) }}
</el-descriptions-item>
<el-descriptions-item label="消费类别" v-if="logDetail.consumptiontype !== undefined">
<el-tag :type="getConsumptionTypeTag(logDetail.consumptiontype)" size="small">
{{ getConsumptionTypeText(logDetail.consumptiontype) }}
</el-tag>
</el-descriptions-item>
<el-descriptions-item label="变动时间" :span="2">
{{ formatDateTime(logDetail) }}
</el-descriptions-item>
<el-descriptions-item label="变动说明" :span="2">
{{ logDetail.reamk || logDetail.remark || '无备注' }}
</el-descriptions-item>
</el-descriptions>
</el-dialog>
</div>
</template>
<script>
import { listUsers, getUsers, delUsers, addUsers, updateUsers, getUserDataList, getBenefitLogs, getBalanceLogs } from "@/api/system/users"
export default {
name: "Users",
dicts: ['users_status', 'sys_yes_no'],
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
userDataList: [],
// 用户列表表格数据
usersList: [],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10,
type: '1',
name: null,
phone: null,
status: null,
},
// 表单参数
form: {
birthday: null,
ismember: 0,
member_begin: null,
member_end: null,
consumption: 0,
servicefee: 0,
balance: 0
},
// 表单校验
rules: {
name: [
{ required: true, message: "昵称不能为空", trigger: "blur" }
],
phone: [
{ required: true, message: "电话不能为空", trigger: "blur" }
],
status: [
{ required: true, message: "1:启用 0关闭不能为空", trigger: "change" }
],
ismember: [
{ required: true, message: "请选择会员状态", trigger: "change" }
],
consumption: [
{ required: true, message: "消费金不能为空", trigger: "blur" }
],
servicefee: [
{ required: true, message: "服务金不能为空", trigger: "blur" }
],
balance: [
{ required: true, message: "余额不能为空", trigger: "blur" }
]
},
// 日志记录相关
logVisible: false,
logLoading: false,
logTitle: '',
logList: [],
logTotal: 0,
currentUserId: null,
currentType: null,
logQuery: {
pageNum: 1,
pageSize: 10
},
// 日志详情弹窗
logDetailVisible: false,
logDetail: {},
// 筛选条件
logFilter: {
type: '',
consumptionType: '',
dateRange: []
},
// 统计数据
totalIncome: 0,
totalExpense: 0,
// 原始日志数据
originalLogList: [],
// 筛选后的日志数据
filteredLogList: []
}
},
created() {
this.getList()
},
methods: {
/** 查询用户列表列表 */
getList() {
this.loading = true
listUsers(this.queryParams).then(response => {
this.usersList = response.rows
this.total = response.total
this.loading = false
})
},
// 增减积分方法
increaseIntegral() {
this.form.integral = Number(this.form.integral || 0) + 1
},
decreaseIntegral() {
if (this.form.integral > 0) {
this.form.integral = Number(this.form.integral) - 1
}
},
increaseTotalIntegral() {
this.form.totalIntegral = Number(this.form.totalIntegral || 0) + 1
},
decreaseTotalIntegral() {
if (this.form.totalIntegral > 0) {
this.form.totalIntegral = Number(this.form.totalIntegral) - 1
}
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
id: null,
name: null,
nickname: null,
phone: null,
password: null,
rememberToken: null,
openid: null,
avatar: null,
type: null,
workerTime: null,
integral: null,
totalIntegral: null,
status: null,
level: null,
commission: null,
totalComm: null,
margin: null,
jobNumber: null,
prohibitTime: null,
prohibitTimeNum: null,
toa: null,
serviceCityPid: null,
serviceCityIds: null,
skillIds: null,
propose: null,
loginStatus: null,
isStop: null,
middleAuth: null,
createdAt: null,
updatedAt: null,
birthday: null,
balance: 0
}
this.resetForm("form")
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm")
this.handleQuery()
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = "添加用户列表"
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const id = row.id || this.ids
getUsers(id).then(response => {
this.form = response.data
this.open = true
this.title = "修改用户列表"
})
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
updateUsers(this.form).then(response => {
this.$modal.msgSuccess("修改成功")
this.open = false
this.getList()
})
} else {
addUsers(this.form).then(response => {
this.$modal.msgSuccess("新增成功")
this.open = false
this.getList()
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids
this.$modal.confirm('是否确认删除用户列表编号为"' + ids + '"的数据项?').then(function() {
return delUsers(ids)
}).then(() => {
this.getList()
this.$modal.msgSuccess("删除成功")
}).catch(() => {})
},
/** 导出按钮操作 */
handleExport() {
this.download('system/users/export', {
...this.queryParams
}, `users_${new Date().getTime()}.xlsx`)
},
/** 显示日志记录 */
showBenefitLogs(userId, type) {
this.currentUserId = userId;
this.currentType = type;
this.logTitle = type === 1 ? '服务金变动记录' : '消费金变动记录';
this.logVisible = true;
this.resetLogFilters();
this.getLogList();
},
/** 获取日志列表 */
getLogList() {
this.logLoading = true;
getBenefitLogs(this.currentUserId, this.currentType, {
pageNum: this.logQuery.pageNum,
pageSize: this.logQuery.pageSize
}).then(response => {
this.logList = response.rows;
this.originalLogList = response.rows;
this.logTotal = response.total;
this.calculateStatistics();
this.applyFilters();
this.logLoading = false;
}).catch(() => {
this.logLoading = false;
});
},
/** 获取余额变动日志列表 */
getBalanceLogList() {
this.logLoading = true;
getBalanceLogs(this.currentUserId, {
pageNum: this.logQuery.pageNum,
pageSize: this.logQuery.pageSize
}).then(response => {
this.logList = response.rows;
this.originalLogList = response.rows;
this.logTotal = response.total;
this.calculateStatistics();
this.applyFilters();
this.logLoading = false;
}).catch(() => {
this.logLoading = false;
});
},
/** 计算统计数据 */
calculateStatistics() {
let income = 0;
let expense = 0;
this.originalLogList.forEach(item => {
const amount = this.getAmountValue(item);
if (amount > 0) {
income += amount;
} else {
expense += Math.abs(amount);
}
});
this.totalIncome = income;
this.totalExpense = expense;
},
/** 应用筛选条件 */
applyFilters() {
let filtered = [...this.originalLogList];
// 按类型筛选
if (this.logFilter.type) {
filtered = filtered.filter(item => {
const amount = this.getAmountValue(item);
if (this.logFilter.type === '1') {
return amount > 0; // 收入
} else if (this.logFilter.type === '2') {
return amount < 0; // 支出
}
return true;
});
}
// 按消费类别筛选(仅余额变动)
if (this.logFilter.consumptionType && this.currentType === null) {
filtered = filtered.filter(item => {
return item.consumptiontype === parseInt(this.logFilter.consumptionType);
});
}
// 按日期范围筛选
if (this.logFilter.dateRange && this.logFilter.dateRange.length === 2) {
const startDate = new Date(this.logFilter.dateRange[0]);
const endDate = new Date(this.logFilter.dateRange[1]);
endDate.setHours(23, 59, 59, 999);
filtered = filtered.filter(item => {
const itemDate = new Date(item.createTime || item.createdAt || item.dotime || item.consumptiontime);
return itemDate >= startDate && itemDate <= endDate;
});
}
this.filteredLogList = filtered;
},
// 筛选日志
filterLogs() {
this.applyFilters();
},
// 导出日志
exportLogs() {
const params = {
userId: this.currentUserId,
type: this.currentType,
...this.logFilter,
pageNum: this.logQuery.pageNum,
pageSize: this.logQuery.pageSize
};
this.download('system/users/exportBenefitLogs', params, `${this.logTitle}_${new Date().getTime()}.xlsx`);
},
// 查看订单
viewOrder(orderId) {
this.$router.push({ path: '/order/detail', query: { id: orderId } });
},
// 查看日志详情
viewLogDetail(row) {
this.logDetail = row;
this.logDetailVisible = true;
},
// 获取变动类型标签
getChangeTypeTag(row) {
if (this.currentType === null) {
return 'info'; // 余额变动
}
if (row.type === 1) { // 服务金变动
return 'success';
} else { // 消费金变动
return 'danger';
}
},
// 获取变动类型文本
getChangeTypeText(row) {
if (this.currentType === null) {
return '余额变动';
}
if (row.type === 1) {
return '服务金变动';
} else {
return '消费金变动';
}
},
// 获取变动金额
getAmountValue(row) {
if (this.currentType === null) {
// 余额变动
if (row.consumptionmoney) {
return row.type === 1 ? row.consumptionmoney : -row.consumptionmoney;
}
return 0;
}
// 服务金/消费金变动
if (row.money) {
return row.ordertype === 1 ? row.money : -row.money;
}
return 0;
},
// 获取变动前金额
getBeforeAmount(row) {
if (this.currentType === null) {
// 余额变动
return parseFloat(row.beformoney || 0).toFixed(2);
}
// 服务金/消费金变动
return parseFloat(row.beformoney || 0).toFixed(2);
},
// 获取变动后金额
getAfterAmount(row) {
if (this.currentType === null) {
// 余额变动
return parseFloat(row.aftermoney || 0).toFixed(2);
}
// 服务金/消费金变动
return parseFloat(row.aftremoney || 0).toFixed(2);
},
// 获取消费类别标签
getConsumptionTypeTag(type) {
if (type === 0) {
return 'info'; // 商城消费
} else if (type === 1) {
return 'success'; // 服务类消费
} else {
return 'warning'; // 其他消费
}
},
// 获取消费类别文本
getConsumptionTypeText(type) {
if (type === 0) {
return '商城消费';
} else if (type === 1) {
return '服务类消费';
} else {
return '其他消费';
}
},
// 格式化日期时间
formatDateTime(row) {
const dateTime = row.createTime || row.createdAt || row.dotime || row.consumptiontime;
return this.parseTime(dateTime, '{y}-{m}-{d} {h}:{i}:{s}');
},
/** 显示余额变动记录 */
showBalanceLogs(userId) {
this.currentUserId = userId;
this.currentType = null;
this.logTitle = '余额变动记录';
this.logVisible = true;
this.resetLogFilters();
this.getBalanceLogList();
},
/** 重置日志筛选条件 */
resetLogFilters() {
this.logFilter = {
type: '',
consumptionType: '',
dateRange: []
};
this.logQuery.pageNum = 1;
},
// 表格行样式
tableRowClassName({ row, rowIndex }) {
const amount = this.getAmountValue(row);
if (amount > 0) {
return 'success-row';
} else if (amount < 0) {
return 'warning-row';
}
return '';
},
// 格式化金额
formatMoney(value) {
if (value === null || value === undefined) {
return '0.00';
}
return parseFloat(value).toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
}
}
}
</script>
<style scoped>
.avatar-upload-box {
width: 100%;
min-height: 200px;
border: 2px dashed #dcdfe6;
border-radius: 6px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: #f5f7fa;
cursor: pointer;
transition: all 0.3s;
}
.avatar-upload-box:hover {
border-color: #409eff;
background-color: #ecf5ff;
}
.upload-tip {
margin-top: 10px;
color: #909399;
font-size: 14px;
}
.integral-input {
display: flex;
align-items: center;
}
.integral-input .el-input-number {
margin: 0 5px;
flex: 1;
}
.integral-input .el-button {
padding: 8px;
}
.el-input-number.is-controls-right .el-input__inner {
padding-left: 15px;
padding-right: 15px;
text-align: center;
}
.el-button--text {
font-weight: normal;
line-height: 1;
}
.el-button--text:hover {
color: #409EFF;
background-color: transparent;
}
/* 新增样式 */
.summary-card {
display: flex;
align-items: center;
padding: 8px 12px;
border-radius: 4px;
box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.06);
min-height: 60px;
}
.summary-content {
display: flex;
align-items: center;
}
.summary-icon {
font-size: 18px;
margin-right: 8px;
color: #409eff;
}
.summary-info {
display: flex;
flex-direction: column;
}
.summary-title {
font-size: 12px;
color: #606266;
margin-bottom: 2px;
}
.summary-value {
font-size: 16px;
font-weight: bold;
color: #303133;
}
.income-card .summary-icon {
color: #67c23a;
}
.expense-card .summary-icon {
color: #f56c6c;
}
.net-card .summary-icon {
color: #e6a23c;
}
.negative {
color: #f56c6c;
}
.amount-text {
font-size: 16px;
font-weight: bold;
}
.amount-positive {
color: #67c23a;
}
.amount-negative {
color: #f56c6c;
}
.remark-content {
color: #909399;
font-size: 14px;
display: flex;
align-items: center;
}
.remark-content .el-icon-info {
margin-right: 5px;
color: #909399;
}
.time-content {
color: #909399;
font-size: 14px;
display: flex;
align-items: center;
}
.time-content .el-icon-time {
margin-right: 5px;
color: #909399;
}
.el-table .el-table__row--striped td {
background-color: #f5f7fa;
}
.el-table .el-table__row--striped:hover td {
background-color: #ecf5ff;
}
.el-table .el-table__row--striped.el-table__row--striped--hover td {
background-color: #ecf5ff;
}
</style>