Browse Source

style: 修改 汇率 消耗详情的代码格式,优化汇率输入错误的提示

feat:消耗明细金币总计(根据筛选)、排序功能
refactor: 重构充值审核,退款审核页面样式、字段 ,目前缺后端接口
lihui/feature-20250623144029-金币前端lihui
lihui 2 days ago
parent
commit
152b99adfc
  1. 389
      src/views/audit/rechargeAudit.vue
  2. 814
      src/views/audit/refundAudit.vue
  3. 121
      src/views/consume/coinConsumeDetail.vue
  4. 244
      src/views/managerecharge/rate.vue

389
src/views/audit/rechargeAudit.vue

@ -1,46 +1,119 @@
<script setup>
import { ref, onMounted, reactive, computed } from 'vue'
import ElementPlus from 'element-plus'
import { ElMessage, ElMessageBox } from 'element-plus'
import { AiFillRead } from 'vue-icons-plus/ai'
import axios from 'axios'
import {computed, onMounted, reactive, ref, watch} from 'vue'
import {ElMessage} from 'element-plus'
import request from '@/util/http'
import moment from 'moment'
//
const adminData = ref({})
const getAdminData = async function () {
try {
const result = await request({
url: '/admin/userinfo',
data: {}
})
adminData.value = result
console.log('用户信息', adminData.value)
} catch (error) {
console.log('请求失败', error)
/*
===================工具方法============================
*/
//
const trimJwCode = () => {
if (rechargeVo.value.jwcode) {
rechargeVo.value.jwcode = rechargeVo.value.jwcode.replace(/\s/g, '');
}
}
/*
===================数据============================
*/
//
const adminData = ref({})
//
const tableData = ref([])
// ======================================
const tableData1 = ref([])
// // todo
const tableData = ref([
{
name: '测试',
jwcode: 1001,
market: "地区1",
activity: "活动1",
money: 100, //
permanentGold: 100, //
freeGold: 50, //
taskGold: 10, //
remark: "备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注",//
reason: "驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由",//
payMode: "微信",//
voucher: "https://www.keaitupian.cn/cjpic/frombd/2/253/1659552792/3869332496.jpg",//
adminName: "提交人姓名", //
auditName: "审核人姓名",// //
payTime: "2025-6-28 14:31:20",//
createTime: "2025-6-29 14:31:20",//
auditStatus: 0, // 0123
},
{
name: '测试2',
jwcode: 1002,
market: "地区2",
activity: "活动2",
money: 200, //
permanentGold: 200, //
freeGold: 50, //
taskGold: 10, //
remark: "2备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注备注",//
reason: "2驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由驳回理由",//
payMode: "2微信",//
voucher: "https://www.keaitupian.cn/cjpic/frombd/2/253/1659552792/3869332496.jpg",//
adminName: "提交人姓名", //
auditName: "审核人姓名",// //
payTime: "3025-6-28 14:31:20",//
createTime: "3025-6-29 14:31:20",//
auditStatus: 1, // 0123
},
])
/*
name: '',
jwcode: null,
market: "",
activity: "",
money: null, //
permanentGold: null, //
freeGold: null, //
taskGold: null, //
remark: "",//
reason: "",//
payMode: "",//
voucher: "",//
/!* adminId: null, // 提交人id
auditId:null,// id*!/
adminName: "", //
auditName: "",// //
payTime: "",//
createTime: "",//
auditStatus: null, // 0123
*/
//
const rechargeVo = ref({
rechargeWay: '客服充值'
jwcode: null,//
activity: "", //
payMode: "",//
startTime: "", //
endTime: "", //
market: "",//
})
//
const getObj = ref({
pageNum: 1,
pageSize: 50
})
//
const total = ref(100)
const total = ref(50)
//
const getTime = ref([])
//
const activity = ref([])
//
const area = ref([])
const market = ref([])
//
const rejectVisible = ref(false)
//
@ -50,7 +123,7 @@ const passObj = ref({})
//
const activeName = ref('wait')
//
const payWay = [
const payMode = [
{
value: '微信',
label: '微信'
@ -74,17 +147,12 @@ const payWay = [
]
// ref
const Ref = ref(null)
//
//
const trueGold = ref(0)
const trueCount = ref(0)
const trueRGold = ref(0)
const trueFGold = ref(0)
//
const formattedTrueGold = computed(() => trueGold.value.toFixed(2))
const formattedTrueRGold = computed(() => trueRGold.value.toFixed(2))
const formattedTrueFGold = computed(() => trueFGold.value.toFixed(2))
//
const pendingCount = ref(0)
//
@ -103,46 +171,79 @@ const rejectedCount = ref(0)
const rejectedGold = ref(0)
const rejectedRGold = ref(0)
const rejectedFGold = ref(0)
//
const sortField = ref('')
const sortOrder = ref('')
//
const rules = reactive({
reason: [{required: true, message: '请输入驳回理由', trigger: 'blur'}]
})
/*
===================方法============================
*/
const getAdminData = async function () {
try {
const result = await request({
url: '/admin/userinfo',
data: {}
})
adminData.value = result
console.log('用户信息', adminData.value)
} catch (error) {
console.log('请求失败', error)
}
}
//
const get = async function (val) {
try {
//
if (adminData.value.area === '泰国') {
rechargeVo.value.areas = ['泰国', '越南']
}
//
if (typeof val === 'number') {
getObj.value.pageNum = val
}
//
if (getTime.value != null) {
if (getTime.value.startDate != '' && getTime.value.endDate != '') {
rechargeVo.value.startDate = getTime.value[0]
rechargeVo.value.endDate = getTime.value[1]
if (getTime.value.startTime != '' && getTime.value.endTime != '') {
rechargeVo.value.startTime = getTime.value[0]
rechargeVo.value.endTime = getTime.value[1]
}
} else {
rechargeVo.value.startDate = ''
rechargeVo.value.endDate = ''
rechargeVo.value.startTime = ''
rechargeVo.value.endTime = ''
}
rechargeVo.value.sortField = sortField.value
rechargeVo.value.sortOrder = sortOrder.value
console.log('搜索参数', getObj.value)
//
const result = await request({
url: '/recharge/recharge',
url: '/recharge/recharge', // todo
data: {
pageNum: getObj.value.pageNum,
pageSize: getObj.value.pageSize,
rechargeVo: { ...rechargeVo.value }
rechargeVo: { //
...rechargeVo.value,
sortField: sortField.value,
sortOrder: sortOrder.value
}
}
})
//
// rechargeVo.value
const rechargeVo1 = {...rechargeVo.value}
delete rechargeVo1.sortField
delete rechargeVo1.sortOrder
delete rechargeVo1.status
delete rechargeVo1.auditStatus
const result2 = await request({
url: '/recharge/recharge/RechargeA',
url: '/recharge/recharge/RechargeA', // todo
data: rechargeVo1
})
//
@ -189,6 +290,7 @@ const get = async function (val) {
console.log('请求失败', error)
}
}
//
const search = function () {
trimJwCode();
@ -197,28 +299,28 @@ const search = function () {
}
//
const reset = function () {
delete rechargeVo.value.activityId
delete rechargeVo.value.activity
delete rechargeVo.value.jwcode
delete rechargeVo.value.payWay
delete rechargeVo.value.area
delete rechargeVo.value.startDate
delete rechargeVo.value.endDate
delete rechargeVo.value.payMode
delete rechargeVo.value.market
delete rechargeVo.value.startTime
delete rechargeVo.value.endTime
getTime.value = {}
}
//
const getToday = function () {
const today = new Date()
const startDate = new Date(
const startTime = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate()
)
const endDate = new Date(
const endTime = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate() + 1
)
getTime.value = [startDate, endDate]
getTime.value = [startTime, endTime]
console.log('getTime', getTime.value)
get()
}
@ -259,10 +361,11 @@ const get7Days = function () {
}
//
const adminWait = async function () {
rechargeVo.value.status = 0
rechargeVo.value.auditStatus = 0
getObj.value.pageNum = 1
await get()
console.log('adminWait')
trueCount.value = pendingCount.value
trueGold.value = pendingGold.value
trueRGold.value = pendingRGold.value
@ -270,7 +373,7 @@ const adminWait = async function () {
}
//
const adminPass = async function () {
rechargeVo.value.status = 1
rechargeVo.value.auditStatus = 1
getObj.value.pageNum = 1
await get()
console.log('adminPass')
@ -281,7 +384,7 @@ const adminPass = async function () {
}
//
const adminReject = async function () {
rechargeVo.value.status = 2
rechargeVo.value.auditStatus = 2
getObj.value.pageNum = 1
await get()
console.log('adminReject')
@ -292,6 +395,7 @@ const adminReject = async function () {
}
const handleClick = function (tab, event) {
activeName.value = tab.props.name
if (tab.props.name === 'wait') {
adminWait()
} else if (tab.props.name === 'pass') {
@ -301,6 +405,17 @@ const handleClick = function (tab, event) {
}
}
// watch(activeName, (val) => {
// if (val === 'wait') {
// adminWait()
// } else if (val === 'pass') {
// adminPass()
// } else if (val === 'reject') {
// adminReject()
// }
// })
const getActivity = async function () {
try {
const result = await request({
@ -314,14 +429,14 @@ const getActivity = async function () {
}
}
//
const getArea = async function () {
const getMarket = async function () {
try {
const result = await request({
url: '/recharge/user/search',
url: 'http://192.168.8.247:8081/general/market',
data: {}
})
area.value = result.data
console.log('地区', area.value)
market.value = result.data
console.log('地区', market.value)
} catch (error) {
console.log('请求失败', error)
}
@ -334,6 +449,7 @@ const handleCurrentChange = function (val) {
getObj.value.pageNum = val
get()
}
// ====================================
//
const pass = function (row) {
@ -341,7 +457,7 @@ const pass = function (row) {
passObj.value = row
passObj.value.adminId = adminData.value.adminId
passObj.value.auditId = row.auditId
// passObj.value.status = 1
// passObj.value.auditStatus = 1
passObj.value.rechargeId = row.rechargeId
passObj.value.detailId = row.detailId
passObj.value.jwcode = row.jwcode
@ -351,12 +467,11 @@ const pass = function (row) {
console.log('通过对象', passObj.value)
}
//
const passConfirm = async function () {
try {
//
passObj.value.status = 1
passObj.value.auditStatus = 1
console.log('通过对象', passObj.value)
// POST
// passObj.value.flag = 0;
@ -393,8 +508,8 @@ const reject = function (row) {
//
rejectObj.value.adminId = adminData.value.adminId
rejectObj.value.auditId = row.auditId
rejectObj.value.status = 2
rejectObj.value.reson = ''
rejectObj.value.auditStatus = 2
rejectObj.value.reason = ''
rejectObj.value.rechargeId = row.rechargeId
rejectObj.value.detailId = row.detailId
console.log('驳回对象', rejectObj.value)
@ -430,21 +545,6 @@ const rejectConfirm = async function () {
})
}
//
const rules = reactive({
reson: [{ required: true, message: '请输入驳回理由', trigger: 'blur' }]
})
//
onMounted(async function () {
await getAdminData()
await getActivity()
await get()
await getArea()
})
//
const sortField = ref('')
const sortOrder = ref('')
//
const handleSortChange = (column) => {
console.log('排序字段:', column.prop)
@ -466,12 +566,59 @@ const handleSortChange = (column) => {
get()
}
//
const trimJwCode = () => {
if (rechargeVo.value.jwcode) {
rechargeVo.value.jwcode = rechargeVo.value.jwcode.replace(/\s/g, '');
}
}
//
const previewImage = (imageUrl) => {
// 使 element-plus el-image
const imageElement = document.createElement('img');
imageElement.src = imageUrl;
imageElement.style.maxWidth = '80vw';
imageElement.style.maxHeight = '80vh';
const viewer = document.createElement('div');
viewer.style.position = 'fixed';
viewer.style.top = '0';
viewer.style.left = '0';
viewer.style.width = '100vw';
viewer.style.height = '100vh';
viewer.style.backgroundColor = 'rgba(0, 0, 0, 0.7)';
viewer.style.display = 'flex';
viewer.style.justifyContent = 'center';
viewer.style.alignItems = 'center';
viewer.style.zIndex = '9999';
viewer.style.overflow = 'auto';
viewer.appendChild(imageElement);
document.body.appendChild(viewer);
viewer.addEventListener('click', () => {
document.body.removeChild(viewer);
});
};
/*
===================监听============================
*/
/*
===================计算属性============================
*/
//
const formattedTrueGold = computed(() => trueGold.value.toFixed(2))
const formattedTrueRGold = computed(() => trueRGold.value.toFixed(2))
const formattedTrueFGold = computed(() => trueFGold.value.toFixed(2))
/*
===================挂载============================
*/
//
onMounted(async function () {
await getAdminData()
await getActivity()
await get()
await getMarket()
})
</script>
<template>
@ -485,21 +632,22 @@ const trimJwCode = () => {
</el-col>
<el-col :span="6">
<el-text size="large">活动名称</el-text>
<el-select v-model="rechargeVo.activityId" placeholder="请选择活动名称" style="width: 240px" clearable>
<el-option v-for="item in activity" :key="item.activityId" :label="item.activityName" :value="item.activityId" />
<el-select v-model="rechargeVo.activity" placeholder="请选择活动名称" style="width: 240px" clearable>
<el-option v-for="item in activity" :key="item.activityId" :label="item.activityName"
:value="item.activityId"/>
</el-select>
</el-col>
<el-col :span="6">
<el-text size="large">支付方式</el-text>
<el-select v-model="rechargeVo.payWay" placeholder="请选择支付方式" style="width: 240px" clearable>
<el-option v-for="item in payWay" :key="item.value" :label="item.label" :value="item.value" />
<el-select v-model="rechargeVo.payMode" placeholder="请选择支付方式" style="width: 240px" clearable>
<el-option v-for="item in payMode" :key="item.value" :label="item.label" :value="item.value"/>
</el-select>
</el-col>
<el-col :span="6">
<div class="head-card-element" v-if="adminData.area == '总部'">
<div class="head-card-element" v-if="adminData.market == '总部'">
<el-text size="large">所属地区</el-text>
<el-select v-model="rechargeVo.area" placeholder="请选择所属地区" style="width: 240px" clearable>
<el-option v-for="item in area" :key="item" :label="item" :value="item" />
<el-select v-model="rechargeVo.market" placeholder="请选择所属地区" style="width: 240px" clearable>
<el-option v-for="item in market" :key="item" :label="item" :value="item"/>
</el-select>
</div>
</el-col>
@ -508,7 +656,7 @@ const trimJwCode = () => {
<el-col :span="12">
<div class="time-controls">
<div class="time-group">
<el-text size="large">添加时间</el-text>
<el-text size="large">充值时间</el-text>
<el-date-picker v-model="getTime" type="datetimerange" range-separator="" start-placeholder="起始时间"
end-placeholder="结束时间" style="width: 400px"/>
<el-button @click="getToday()" style="margin-left: 10px"> </el-button>
@ -534,35 +682,56 @@ const trimJwCode = () => {
<el-tab-pane label="已通过" name="pass"></el-tab-pane>
<el-tab-pane label="已驳回" name="reject"></el-tab-pane>
<div>
<div> <!--todo 改这里 总数的-->
总条数{{ trueCount }}&nbsp;&nbsp;&nbsp;&nbsp;
总金币数{{ formattedTrueGold }}金币&nbsp;&nbsp;&nbsp;&nbsp;
永久金币{{ formattedTrueRGold }}金币&nbsp;&nbsp;&nbsp;&nbsp;
免费金币{{ formattedTrueFGold }}金币
</div>
</el-tabs>
<!--表格-->
<div style="height: 540px; overflow-y: auto">
<el-table :data="tableData" style="width: 100%" height="540px" @sort-change="handleSortChange" :row-style="{ height: '50px' }">
<el-table :data="tableData" style="width: 100%" height="540px" @sort-change="handleSortChange"
:row-style="{ height: '50px' }">
<el-table-column type="index" label="序号" width="100px" fixed="left">
<template #default="scope">
<span>{{ scope.$index + 1 + (getObj.pageNum - 1) * getObj.pageSize }}</span>
</template>
</el-table-column>
<el-table-column fixed="left" prop="username" label="姓名" width="150px" />
<el-table-column fixed="left" prop="name" label="姓名" width="150px"/>
<el-table-column fixed="left" prop="jwcode" label="精网号" width="110px"/>
<el-table-column prop="area" label="所属地区" width="100px" />
<el-table-column prop="refundType" label="活动名称" width="100px" />
<el-table-column prop="refundGoods" label="充值金额" width="100px" />
<el-table-column prop="rechargeCoin" label="永久金币" width="110px" sortable="custom">
<template #default="scope">{{ scope.row.rechargeCoin }}</template>
<el-table-column prop="market" label="所属地区" width="100px"/>
<el-table-column prop="activity" label="活动名称" width="100px"/>
<el-table-column prop="money" label="充值金额" sortable="custom" width="110px"/>
<el-table-column prop="permanentGold" label="永久金币" width="110px" sortable="custom">
<template #default="scope">{{ scope.row.permanentGold }}</template>
</el-table-column>
<el-table-column prop="freeCoin" label="免费金币" sortable="custom" width="110px">
<template #default="scope">{{ scope.row.freeCoin }}</template>
<el-table-column prop="freeGold" label="免费金币" sortable="custom" width="110px">
<template #default="scope">{{ scope.row.freeGold }}</template>
</el-table-column>
<el-table-column prop="remark" label="备注" width="200px" show-overflow-tooltip/>
<el-table-column prop="freeCoin" label="支付凭证" width="110px" />
<el-table-column prop="payMode" label="支付方式" width="110px"/>
<el-table-column prop="voucher" label="支付凭证" width="110px">
<!-- 支付凭证列支持点击放大预览 -->
<template #default="scope">
<div v-if="scope.row.voucher" style="cursor: pointer;" @click="previewImage(scope.row.voucher)">
<img :src="scope.row.voucher" alt="支付凭证" style="width: 80px; height: auto;">
</div>
<div v-else>--</div>
</template>
</el-table-column>
<el-table-column prop="adminName" label="提交人" width="100px"/>
<el-table-column prop="status" label="付款时间" width="200px" >
<!--
字太多就悬停显示
-->
<el-table-column prop="reason" label="驳回理由" width="200px" show-overflow-tooltip/>
<el-table-column v-if="activeName!== 'wait'" prop="auditName" label="审核人" width="100px"/>
<el-table-column prop="payTime" sortable="custom" label="付款时间" width="200px">
<template #default="scope">
{{ moment(scope.row.createTime).format('YYYY-MM-DD HH:mm:ss') }}
</template>
@ -572,12 +741,13 @@ const trimJwCode = () => {
{{ moment(scope.row.createTime).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
<el-table-column fixed="right" prop="operation" label="操作" width="150px">
<el-table-column v-if="activeName === 'wait'"
fixed="right" prop="operation" label="操作" width="150px">
<template #default="scope">
<div class="operation">
<el-popconfirm title="确定要通过此条记录吗?" @confirm="passConfirm">
<template #reference>
<el-button :disabled="scope.row.status === 1 || scope.row.status === 2
<el-button :disabled="scope.row.auditStatus === 1 || scope.row.auditStatus === 2
? true
: false
" type="primary" text @click="pass(scope.row)">
@ -589,7 +759,7 @@ const trimJwCode = () => {
<el-button type="primary" size="small" @click="confirm">确定</el-button>
</template>
</el-popconfirm>
<el-button :disabled="scope.row.status === 1 || scope.row.status === 2
<el-button :disabled="scope.row.auditStatus === 1 || scope.row.auditStatus === 2
? true
: false
" type="primary" text @click="reject(scope.row)">
@ -603,7 +773,8 @@ const trimJwCode = () => {
<div class="pagination">
<el-pagination background :page-size="getObj.pageSize" :page-sizes="[5, 10, 20, 50, 100]"
layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="handlePageSizeChange"
layout="total, sizes, prev, pager, next, jumper" :total="total"
@size-change="handlePageSizeChange"
@current-change="handleCurrentChange"></el-pagination>
</div>
</el-card>
@ -613,8 +784,8 @@ const trimJwCode = () => {
<el-dialog v-model="rejectVisible" title="驳回理由" width="500" :before-close="closeRejectVisible">
<template #footer>
<el-form :model="rejectObj" ref="Ref" :rules="rules" label-width="auto" style="max-width: 600px">
<el-form-item prop="reson" label="驳回理由:">
<el-input v-model="rejectObj.reson" maxlength="150" show-word-limit style="width: 350px" type="textarea"
<el-form-item prop="reason" label="驳回理由:">
<el-input v-model="rejectObj.reason" maxlength="150" show-word-limit style="width: 350px" type="textarea"
placeholder="请输入内容"/>
</el-form-item>
</el-form>

814
src/views/audit/refundAudit.vue

@ -9,27 +9,39 @@
<el-input v-model="searchForm.jwcode" placeholder="请输入精网号" style="width: 240px" clearable/>
</el-col>
<el-col :span="6">
<el-text size="large">退款类型</el-text>
<el-select v-model="searchForm.refundType" placeholder="请选择" style="width: 240px" clearable>
<el-option label="商品退款" value="商品退款" />
<el-option label="退点啥??" value="退点啥??" />
<el-text size="large">活动名称</el-text>
<el-select v-model="searchForm.activity" placeholder="请选择活动名称" style="width: 240px" clearable>
<el-option v-for="item in activityOptions" :key="item.activityId" :label="item.activityName"
:value="item.activityId"/>
</el-select>
</el-col>
<el-col :span="6">
<el-text size="large">退款商品</el-text>
<el-select v-model="searchForm.refundGoods" placeholder="请选择退款商品" style="width: 240px" clearable>
<el-option v-for="item in productOptions" :key="item.productId" :label="item.productName"
:value="item.productId"/>
</el-select>
</el-col>
<el-col :span="6">
<el-text size="large">所属地区</el-text>
<el-select v-model="searchForm.area" placeholder="请选择" style="width: 240px" clearable>
<el-select v-model="searchForm.area" placeholder="请选择所属地区" style="width: 240px" clearable>
<el-option v-for="item in areaOptions" :key="item" :label="item" :value="item"/>
</el-select>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-text size="large">退款时间</el-text>
<el-date-picker v-model="dateRange" type="datetimerange" range-separator="" start-placeholder="开始日期"
end-placeholder="结束日期" style="width: 400px" />
<div class="time-controls">
<div class="time-group">
<el-text size="large">充值时间</el-text>
<el-date-picker v-model="dateRange" type="datetimerange" range-separator=""
start-placeholder="开始时间"
end-placeholder="结束时间" style="width: 400px"/>
<el-button @click="getToday()" style="margin-left: 10px"></el-button>
<el-button @click="getYesterday()" style="margin-left: 10px"></el-button>
<el-button @click="get7Days()" style="margin-left: 10px">近7天</el-button>
</div>
</div>
</el-col>
<el-col :span="6">
<el-button type="success" @click="resetSearch">重置</el-button>
@ -42,87 +54,129 @@
</el-row>
<el-card>
<el-tabs v-model="checkTab" @tab-change="switchTab">
<el-tab-pane label="待审核" name="1" />
<el-tab-pane label="已通过" name="2" />
<el-tab-pane label="已驳回" name="3" />
<el-tabs v-model="activeName" type="card" @tab-click="handleClick">
<el-tab-pane label="待审核" name="wait"></el-tab-pane>
<el-tab-pane label="已通过" name="pass"></el-tab-pane>
<el-tab-pane label="已驳回" name="reject"></el-tab-pane>
</el-tabs>
<div class="stats-info">
退款记录条数: {{ stats.totalItems }}&nbsp;&nbsp;&nbsp;&nbsp;
退款金币总数: {{ stats.totalCoins }}&nbsp;&nbsp;&nbsp;&nbsp;
永久金币: {{ stats.permanentCoins }}&nbsp;&nbsp;&nbsp;&nbsp;
免费金币: {{ stats.freeCoins }}&nbsp;&nbsp;&nbsp;&nbsp;
任务金币: {{ stats.taskCoins }}
<div>
总条数{{ stats.totalItems }}&nbsp;&nbsp;&nbsp;&nbsp;
退款总金币数{{ stats.totalCoins }}金币&nbsp;&nbsp;&nbsp;&nbsp;
永久金币{{ stats.permanentCoins }}金币&nbsp;&nbsp;&nbsp;&nbsp;
免费金币{{ stats.freeCoins }}金币&nbsp;&nbsp;&nbsp;&nbsp;
任务金币{{ stats.taskCoins }}金币
</div>
<el-table :data="tableData" height="540px" @sort-change="handleSortChange">
<el-table-column type="index" label="序号" width="60" />
<el-table-column prop="username" label="姓名" width="120" />
<el-table-column prop="jwcode" label="精网号" width="120" />
<el-table-column prop="area" label="所属地区" width="120" />
<el-table-column prop="refundType" label="退款类型" width="120" />
<el-table-column prop="refundMethod" label="退款方式" width="120" />
<el-table-column prop="refundGoods" label="退款商品" width="120" />
<el-table-column prop="refundAmount" label="退款金额" width="120" sortable="custom">
<template #default="{ row }">
{{ row.rechargeCoin + row.freeCoin + row.taskCoin }}
<div style="height: 540px; overflow-y: auto">
<el-table :data="tableData" style="width: 100%" height="540px" @sort-change="handleSortChange"
:row-style="{ height: '50px' }">
<el-table-column type="index" label="序号" width="100px" fixed="left">
<template #default="scope">
<span>{{ scope.$index + 1 + (pagination.pageNum - 1) * pagination.pageSize }}</span>
</template>
</el-table-column>
<el-table-column prop="rechargeCoin" label="永久金币" width="120" sortable="custom" />
<el-table-column prop="freeCoin" label="免费金币" width="120" sortable="custom" />
<el-table-column prop="taskCoin" label="任务金币" width="120" sortable="custom" />
<el-table-column prop="remark" label="备注" width="150" show-overflow-tooltip /><!-- 当内容过长被隐藏时显示 tooltip -->
<el-table-column prop="adminName" label="提交人" width="120" />
<el-table-column v-if="checkTab === 'rejected'" prop="reason" label="驳回理由" width="150" show-overflow-tooltip />
<el-table-column v-if="checkTab !== 'pending'" prop="auditName" label="审核人" width="120" />
<el-table-column prop="createTime" label="提交时间" width="180" sortable="custom">
<template #default="{ row }">
{{ moment(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}
<el-table-column fixed="left" prop="name" label="姓名" width="150px"/>
<el-table-column fixed="left" prop="jwcode" label="精网号" width="110px"/>
<el-table-column prop="market" label="所属地区" width="100px"/>
<el-table-column prop="refundType" label="退款类型" width="100px">
<template #default="scope">商品退款</template>
</el-table-column>
<el-table-column prop="refundModel" label="退款方式" width="100px"/>
<el-table-column prop="goodsName" label="退款商品" width="100px"/>
<el-table-column prop="money" label="退款金额" width="110px" sortable="custom">
<template #default="scope">{{ scope.row.money }}</template>
</el-table-column>
<el-table-column prop="permanentGold" label="永久金币" width="110px" sortable="custom">
<template #default="scope">{{ scope.row.permanentGold }}</template>
</el-table-column>
<el-table-column prop="freeGold" label="免费金币" sortable="custom" width="110px">
<template #default="scope">{{ scope.row.freeGold }}</template>
</el-table-column>
<el-table-column prop="taskGold" label="任务金币" sortable="custom" width="110px">
<template #default="scope">{{ scope.row.taskGold }}</template>
</el-table-column>
<el-table-column prop="remark" label="备注" width="200px" show-overflow-tooltip/>
<el-table-column prop="adminName" label="提交人" width="100px"/>
<el-table-column v-if="activeName!== 'wait'" prop="auditName" label="审核人" width="100px"/>
<el-table-column v-if="activeName === 'reject'" prop="reason" label="驳回理由" width="200px"
show-overflow-tooltip/>
<el-table-column prop="createTime" sortable="custom" label="提交时间" width="200px">
<template #default="scope">
{{ moment(scope.row.createTime).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
<el-table-column v-if="checkTab !== 'pending'" prop="auditTime" label="审核时间" width="180" sortable="custom">
<template #default="{ row }">
{{ row.auditTime ? moment(row.auditTime).format('YYYY-MM-DD HH:mm:ss') : '--' }}
<el-table-column v-if="activeName!== 'wait'" sortable="custom" prop="auditTime" label="审核时间" width="200px" default-sort="descending">
<template #default="scope">
{{ scope.row.auditTime ? moment(scope.row.auditTime).format('YYYY-MM-DD HH:mm:ss') : '--' }}
</template>
</el-table-column>
<el-table-column label="操作" width="150" fixed="right" v-if="checkTab === 'pending'">
<template #default="{ row }">
<el-button type="success" size="small" @click="handleAction('approve', row)">通过</el-button>
<el-button type="danger" size="small" @click="handleAction('reject', row)">驳回</el-button>
<el-table-column v-if="activeName === 'wait'"
fixed="right" prop="operation" label="操作" width="150px">
<template #default="scope">
<div class="operation">
<el-popconfirm title="确定要通过此条记录吗?" @confirm="passConfirm(scope.row)">
<template #reference>
<el-button :disabled="scope.row.auditStatus === 1 || scope.row.auditStatus === 2
? true
: false
" type="primary" text>
通过
</el-button>
</template>
<template #actions="{ confirm, cancel }">
<el-button size="small" @click="cancel">取消</el-button>
<el-button type="primary" size="small" @click="confirm">确定</el-button>
</template>
</el-popconfirm>
<el-button :disabled="scope.row.auditStatus === 1 || scope.row.auditStatus === 2
? true
: false
" type="primary" text @click="reject(scope.row)">
驳回
</el-button>
</div>
</template>
</el-table-column>
</el-table>
</div>
<div class="pagination">
<el-pagination v-model:current-page="pagination.pageNum" v-model:page-size="pagination.pageSize"
:total="pagination.total" :page-sizes="[10, 20, 50, 100]" layout="total, sizes, prev, pager, next, jumper"
:total="pagination.total" :page-sizes="[5, 10, 20, 50, 100]"
layout="total, sizes, prev, pager, next, jumper"
@size-change="handlePagination('size', $event)" @current-change="handlePagination('page', $event)"
class="pagination"/>
</div>
</el-card>
<!-- 驳回弹出框 -->
<el-dialog v-model="rejectDialog" title="驳回理由" width="500px">
<el-form :model="rejectForm">
<el-form-item label="驳回理由">
<el-input v-model="rejectForm.reason" type="textarea" :rows="4" placeholder="请输入驳回理由" maxlength="200"
show-word-limit />
<el-dialog v-model="rejectVisible" title="驳回理由" width="500" :before-close="closeRejectVisible">
<template #footer>
<el-form :model="rejectObj" ref="Ref" :rules="rules" label-width="auto" style="max-width: 600px">
<el-form-item prop="reason" label="驳回理由:">
<el-input v-model="rejectObj.reason" maxlength="150" show-word-limit style="width: 350px" type="textarea"
placeholder="请输入内容"/>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="rejectDialog=false">取消</el-button>
<el-button type="primary" @click="rejectRefund">确定</el-button>
<div class="dialog-footer">
<el-button @click="closeRejectVisible()">取消</el-button>
<el-button type="primary" @click="rejectConfirm()"> 确定</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import request from '@/util/http'
import {onMounted, reactive, ref} from 'vue'
import {ElMessage} from 'element-plus'
import request from '@/util/http'
import moment from 'moment'
/*
================数据=========================
*/
//
const STATUS = {
PENDING: 0, //
@ -130,29 +184,107 @@ const STATUS = {
REJECTED: 2 //
}
//
//
const searchForm = ref({
jwcode: '',
refundType: '',
refundGoods: '',
area: '',
startDate: '',
endDate: ''
jwcode: null, //
activity: "", //
refundGoods: "", // 退
market: "", //
startTime: "", //
endTime: "" //
})
const checkTab = ref(1) // STATUS123statusInteger
const dateRange = ref([])
//
const pagination = ref({
pageNum: 1,
pageSize: 50,
total: 0
})
const tableData = ref([])
//
const dateRange = ref([])
// // todo
const tableData = ref([
{
name: '张三',
jwcode: 1001,
market: '北京市',
refundType: '商品退款',
refundModel: '部分退款',
goodsName: '手机',
money: 250,
permanentGold: 200,
freeGold: 30,
taskGold: 20,
remark: '用户反馈商品有瑕疵,申请部分退款',
adminName: '李管理员',
auditName: '',
createTime: '2025-06-28 10:30:00',
auditTime: '',
auditStatus: 0, //
refundId: 1001,
detailId: 10001,
auditId: 100001
},
{
name: '李四',
jwcode: 1002,
market: '上海市',
refundType: '商品退款',
refundModel: '全额退款',
goodsName: '耳机',
money: 120,
permanentGold: 100,
freeGold: 20,
taskGold: 0,
remark: '用户改变主意,不想要了',
adminName: '王管理员',
auditName: '赵审核员',
createTime: '2025-06-27 15:45:00',
auditTime: '2025-06-28 09:15:00',
auditStatus: 1, //
refundId: 1002,
detailId: 10002,
auditId: 100002
},
{
name: '王五',
jwcode: 1003,
market: '广州市',
refundType: '商品退款',
refundModel: '部分退款',
goodsName: '充电器',
money: 80,
permanentGold: 60,
freeGold: 20,
taskGold: 0,
remark: '商品包装损坏',
reason: '包装损坏属于物流问题,建议用户联系物流公司索赔',
adminName: '孙管理员',
auditName: '钱审核员',
createTime: '2025-06-26 09:20:00',
auditTime: '2025-06-27 11:30:00',
auditStatus: 2, //
refundId: 1003,
detailId: 10003,
auditId: 100003
}
])
//
const activityOptions = ref([])
//
const productOptions = ref([])
//
const areaOptions = ref([])
//
const adminInfo = ref({})
//
const stats = ref({
totalItems: 0,
totalCoins: 0,
@ -160,27 +292,82 @@ const stats = ref({
freeCoins: 0,
taskCoins: 0
})
//
const rejectDialog = ref(false) //
const rejectForm = ref({ reason: '' })
const currentRecord = ref(null)
//
const rejectVisible = ref(false)
//
const rejectObj = ref({})
//
const passObj = ref({})
//
const activeName = ref('wait')
//
const refundMode = [
{
value: '部分退款',
label: '部分退款'
},
{
value: '全额退款',
label: '全额退款'
}
]
// ref
const Ref = ref(null)
//
const sortField = ref('')
const sortOrder = ref('')
//
const rules = reactive({
reason: [{required: true, message: '请输入驳回理由', trigger: 'blur'}]
})
/*
======================方法==========================
*/
//
const fetchAdminInfo = async () => {
const getAdminData = async function () {
try {
const res = await request({ url: '/admin/userinfo' })
adminInfo.value = res
if (res.area !== '总部') {
searchForm.value.area = res.area
const result = await request({
url: '/admin/userinfo',
data: {}
})
adminInfo.value = result
console.log('用户信息', adminInfo.value)
} catch (error) {
console.log('请求失败', error)
}
}
//
const getActivity = async function () {
try {
const result = await request({
url: '/recharge/activity/select',
data: {}
})
activityOptions.value = result.data
console.log('activity', activityOptions.value)
} catch (error) {
console.error('获取用户信息失败', error)
console.log('请求失败', error)
}
}
//
const fetchProducts = async () => {
const getProducts = async () => {
try {
const res = await request({ url: '/product' })
const res = await request({
url: '/product' // todo
})
productOptions.value = res.data || []
} catch (error) {
console.error('获取商品列表失败', error)
@ -188,18 +375,39 @@ const fetchProducts = async () => {
}
//
const fetchAreas = async () => {
const getMarket = async () => {
try {
const result = await request({ url: 'http://192.168.8.247:8081/general/market' })
const result = await request({
url: 'http://192.168.8.247:8081/general/market' // todo
})
areaOptions.value = result.data || []
} catch (error) {
console.error('获取地区列表失败', error)
}
}
const get = async () => {
console.log('===========================================' + checkTab.value)
//
const get = async function (val) {
try {
//
if (typeof val === 'number') {
pagination.value.pageNum = val
}
//
if (dateRange.value != null) {
if (dateRange.value.length === 2) {
searchForm.value.startTime = moment(dateRange.value[0]).format('YYYY-MM-DD HH:mm:ss')
searchForm.value.endTime = moment(dateRange.value[1]).format('YYYY-MM-DD HH:mm:ss')
}
} else {
searchForm.value.startTime = ''
searchForm.value.endTime = ''
}
searchForm.value.sortField = sortField.value
searchForm.value.sortOrder = sortOrder.value
console.log('搜索参数', pagination.value)
const params = {
pageNum: pagination.value.pageNum,
pageSize: pagination.value.pageSize,
@ -208,109 +416,186 @@ const get = async () => {
status: getCurrentStatus()
}
}
//
if (dateRange.value?.length === 2) {
params.detail.startDate = moment(dateRange.value[0]).format('YYYY-MM-DD HH:mm:ss')
params.detail.endDate = moment(dateRange.value[1]).format('YYYY-MM-DD HH:mm:ss')
}
const res = await request({
url: '/audit/audit/refund',
const result = await request({
url: '/audit/audit/refund', // todo
data: params
})
tableData.value = res.data?.list || []
pagination.value.total = res.data?.total || 0
fetchStats()
} catch (error) {
console.error('获取数据失败', error)
}
}
const fetchStats = async () => {
try {
const params = { ...searchForm.value, status: getCurrentStatus() }
const res = await request({
url: '/refund/RefundA',
data: params
//
// searchForm.value
const searchForm1 = {...searchForm.value}
delete searchForm1.sortField
delete searchForm1.sortOrder
delete searchForm1.status
const result2 = await request({
url: '/refund/RefundA', // todo
data: searchForm1
})
if (res.data) {
const data = res.data
stats.value = {
totalItems: data.raudit || 0,
totalCoins: data.sumRaudit || 0,
permanentCoins: data.permanentCoins || 0,
freeCoins: data.freeCoins || 0,
taskCoins: data.taskCoins || 0
//
if (result2.data) {
result2.data.forEach((item) => {
switch (item.auditStatus) {
case '待审核':
stats.value.totalItems = item.raudit || 0
stats.value.totalCoins = item.sumRaudit || 0
stats.value.permanentCoins = item.sumRaudit1 || 0
stats.value.freeCoins = item.sumRaudit2 || 0
stats.value.taskCoins = item.sumRaudit3 || 0
break
case '已通过':
stats.value.totalItems = item.raudit || 0
stats.value.totalCoins = item.sumRaudit || 0
stats.value.permanentCoins = item.sumRaudit1 || 0
stats.value.freeCoins = item.sumRaudit2 || 0
stats.value.taskCoins = item.sumRaudit3 || 0
break
case '已驳回':
stats.value.totalItems = item.raudit || 0
stats.value.totalCoins = item.sumRaudit || 0
stats.value.permanentCoins = item.sumRaudit1 || 0
stats.value.freeCoins = item.sumRaudit2 || 0
stats.value.taskCoins = item.sumRaudit3 || 0
break
}
})
}
console.log('搜索对象', pagination.value)
//
tableData.value = result.data.list
console.log('tableData', tableData.value)
//
pagination.value.total = result.data.total
console.log('total', pagination.value.total)
} catch (error) {
console.error('获取统计信息失败', error)
console.log('请求失败', error)
}
}
const handleSearch = () => {
//
const handleSearch = function () {
pagination.value.pageNum = 1
get()
}
const resetSearch = () => {
//
const resetSearch = function () {
searchForm.value = {
jwcode: '',
refundType: '',
refundGoods: '',
area: adminInfo.value.area === '总部' ? '' : adminInfo.value.area,
startDate: '',
endDate: ''
jwcode: null,
activity: "",
refundGoods: "",
market: "",
startTime: "",
endTime: ""
}
dateRange.value = []
handleSearch()
}
// moment(param).format('YYYY-MM-DD HH:mm:ss')
//
const getToday = () => {
const getToday = function () {
const today = new Date()
const start = moment(new Date(today.getFullYear(), today.getMonth(), today.getDate(), 0, 0, 0)).format('YYYY-MM-DD HH:mm:ss')
const end = moment(new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1, 0, 0, 0)).format('YYYY-MM-DD HH:mm:ss')
dateRange.value = [start, end]
const startTime = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate()
)
const endTime = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate() + 1
)
dateRange.value = [startTime, endTime]
console.log('dateRange', dateRange.value)
get()
}
//
const getYesterday = () => {
const getYesterday = function () {
const yesterday = new Date()
yesterday.setDate(yesterday.getDate() - 1)
const start = new Date(yesterday.getFullYear(), yesterday.getMonth(), yesterday.getDate(), 0, 0, 0)
const end = new Date(yesterday.getFullYear(), yesterday.getMonth(), yesterday.getDate() + 1, 0, 0, 0)
dateRange.value = [moment(start).format('YYYY-MM-DD HH:mm:ss'), moment(end).format('YYYY-MM-DD HH:mm:ss')]
const startDate = new Date(
yesterday.getFullYear(),
yesterday.getMonth(),
yesterday.getDate()
)
const endDate = new Date(
yesterday.getFullYear(),
yesterday.getMonth(),
yesterday.getDate() + 1
)
dateRange.value = [startDate, endDate]
console.log('dateRange', dateRange.value)
get()
}
// 7
const get7Days = () => {
const get7Days = function () {
const today = new Date()
const start = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 6, 0, 0, 0)
const end = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1, 0, 0, 0)
dateRange.value = [start,end]//
const startDate = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate() - 6
)
const endDate = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate() + 1
)
dateRange.value = [startDate, endDate]
console.log('dateRange', dateRange.value)
get()
}
const switchTab = (tab) => {
checkTab.value = tab
pagination.value.pageNum = 1
get()
//
const handleClick = function (tab, event) {
activeName.value = tab.props.name
if (tab.props.name === 'wait') {
adminWait()
} else if (tab.props.name === 'pass') {
adminPass()
} else if (tab.props.name === 'reject') {
adminReject()
}
}
//
const getCurrentStatus = () => {
switch (checkTab.value) {
case 'pending': return STATUS.PENDING
case 'approved': return STATUS.APPROVED
case 'rejected': return STATUS.REJECTED
default: return ''
switch (activeName.value) {
case 'wait':
return STATUS.PENDING
case 'pass':
return STATUS.APPROVED
case 'reject':
return STATUS.REJECTED
default:
return ''
}
}
//
const adminWait = async function () {
searchForm.value.status = STATUS.PENDING
pagination.value.pageNum = 1
await get()
console.log('adminWait')
}
//
const adminPass = async function () {
searchForm.value.status = STATUS.APPROVED
pagination.value.pageNum = 1
await get()
console.log('adminPass')
}
//
const adminReject = async function () {
searchForm.value.status = STATUS.REJECTED
pagination.value.pageNum = 1
await get()
console.log('adminReject')
}
const handlePagination = (type, val) => {
@ -322,88 +607,209 @@ const handlePagination = (type, val) => {
get()
}
const handleAction = (type, row) => {
currentRecord.value = row
if (type === 'reject') {
rejectForm.value.reason = ''
rejectDialog.value = true
} else if (type === 'approve') {
approveRefund()
}
}
//
const pass = function (row) {
//
passObj.value = row
passObj.value.adminId = adminInfo.value.adminId
passObj.value.auditId = row.auditId
passObj.value.auditStatus = 1
passObj.value.refundId = row.refundId
passObj.value.detailId = row.detailId
passObj.value.jwcode = row.jwcode
passObj.value.paidGold = row.paidGold
passObj.value.freeGold = row.freeGold
passObj.value.adminName = adminInfo.value.adminName
const approveRefund = async () => {
try {
const params = {
adminId: adminInfo.value.adminId,
auditId: currentRecord.value.auditId,
status: STATUS.APPROVED,
refundId: currentRecord.value.refundId
console.log('通过对象', passObj.value)
}
await request({
url: '/audit/audit/edit',
data: params
//
const passConfirm = async function (row) {
try {
pass(row)
//
passObj.value.auditStatus = 1
console.log('通过对象', passObj.value)
// POST
// passObj.value.flag = 0;
const result = await request({
url: '/audit/audit/goldedit', // todo
data: passObj.value
})
ElMessage.success('退款已批准')
console.log('请求成功', result)
get()
//
ElMessage({
type: 'success',
message: '通过成功!'
})
} catch (error) {
console.error('批准失败', error)
ElMessage.error('操作失败')
console.error('请求失败', error);
ElMessage({
type: 'error',
message: '出错了,不知道咋回事'
});
}
}
const rejectRefund = async () => {
if (!rejectForm.value.reason) {
ElMessage.warning('请输入驳回理由')
return
//
const openRejectVisible = function () {
rejectVisible.value = true
}
try {
const params = {
adminId: adminInfo.value.adminId,
auditId: currentRecord.value.auditId,
status: STATUS.REJECTED,
refundId: currentRecord.value.refundId,
reason: rejectForm.value.reason
//
const closeRejectVisible = function () {
rejectVisible.value = false
}
await request({
url: '/audit/audit/edit',
data: params
})
//
const reject = function (row) {
//
rejectObj.value.adminId = adminInfo.value.adminId
rejectObj.value.auditId = row.auditId
rejectObj.value.auditStatus = 2
rejectObj.value.reason = ''
rejectObj.value.refundId = row.refundId
rejectObj.value.detailId = row.detailId
console.log('驳回对象', rejectObj.value)
openRejectVisible()
}
ElMessage.success('退款已驳回')
rejectDialog.value = false
//
const rejectConfirm = async function () {
Ref.value.validate(async (valid) => {
if (valid) {
try {
console.log('驳回对象', rejectObj.value)
// POST
const result = await request({
url: '/audit/audit/goldedit',// todo
data: rejectObj.value
})
console.log('请求成功', result)
get()
closeRejectVisible()//
ElMessage({
type: 'success',
message: '驳回成功!'
})
} catch (error) {
console.error('驳回失败', error)
ElMessage.error('操作失败')
console.log('请求失败', error)
}
} else {
ElMessage({
type: 'error',
message: '请检查输入内容'
})
}
})
}
onMounted(async () => {
await fetchAdminInfo()//
await fetchProducts()
await fetchAreas()
//
const handleSortChange = (column) => {
console.log('排序字段:', column.prop)
console.log('排序方式:', column.order)
if (column.prop === 'money') {
sortField.value = 'recharge_coin'
} else if (column.prop === 'freeGold') {
sortField.value = 'free_gold'
} else if (column.prop === 'createTime') {
sortField.value = 'create_time'
} else if (column.prop === 'auditTime') {
sortField.value = 'audit_time'
} else if (column.prop === 'permanentGold') {
sortField.value = 'permanent_gold'
} else if (column.prop === 'taskGold') {
sortField.value = 'task_gold'
}
sortOrder.value = column.order === 'ascending' ? 'ASC' : 'DESC'
get()
}
/*
======================挂载=========================
*/
//
onMounted(async function () {
await getAdminData()
await getActivity()
await getProducts()
await getMarket()
await get()
})
</script>
<style scoped>
.quickly-buttons {
margin-left: 10px;
.pagination {
display: flex;
}
.stats-info {
padding: 3px;
background-color: #f5f7fa;
.operation {
display: flex;
}
.pagination {
margin-top: 20px;
justify-content: flex-end;
.green-dot {
background-color: #67C23A;
}
.grey-dot {
background-color: #909399;
}
.red-dot {
background-color: #F56C6C;
}
.time-controls {
display: flex;
align-items: center;
}
.time-group {
display: flex;
align-items: center;
gap: 10px;
}
.quick-buttons {
display: flex;
align-items: center;
}
.status {
display: flex;
align-items: center;
/* 确保子元素垂直居中对齐 */
gap: 6px;
/* 设置圆点和文字之间的间距 */
}
.green-dot,
.grey-dot,
.red-dot {
display: inline-block;
width: 8px;
height: 8px;
border-radius: 50%;
flex-shrink: 0;
/* 防止圆点在空间不足时缩小 */
margin: 0;
/* 移除原有的 margin-right */
}
/* 备注列样式 */
.remark-cell {
display: block;
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* 设置单元格内容溢出隐藏 */
.el-table .el-table__cell {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
</style>

121
src/views/consume/coinConsumeDetail.vue

@ -5,31 +5,20 @@ import request from '@/util/http'
//
/*
====================工具方法==============================
*/
//
const formatTime = (val) => val ? dayjs(val).format('YYYY-MM-DD HH:mm:ss') : ''
//
/*
====================数据=================================
*/
//
const adminData = ref({})
const getAdminData = async function () {
try {
const result = await request({
url: '/admin/userinfo',
data: {}
})
adminData.value = result
console.log('请求成功', result)
console.log('用户信息', adminData.value)
} catch (error) {
console.log('请求失败', error)
}
}
//
const tableData = ref([])
// ======================================
// consumeUser
const consumeUser = ref({
@ -40,8 +29,12 @@ const consumeUser = ref({
startTime: '',
endTime: '',
goodsName: ""
goodsName: '',
})
//
const getObj = ref({
pageNum: 1,
@ -98,13 +91,35 @@ const totalGold = ref(0)
const permanentGolds = ref(0)
const freeGolds = ref(0)
const taskGolds = ref(0)
//
const goods = ref([])
//
const sumGold = computed(() => permanentGolds.value + freeGolds.value + taskGolds.value)
//
const totalGoldSearch = ref({
payPlatform: "",
market: "",
startTime: "",
endTime: "",
goodsName: ""
})
/*
====================方法=================================
*/
//
const getAdminData = async function () {
try {
const result = await request({
url: '/admin/userinfo',
data: {}
})
adminData.value = result
console.log('请求成功', result)
console.log('用户信息', adminData.value)
} catch (error) {
console.log('请求失败', error)
}
}
// =========================================================================================================================================================
//
const ConsumeSelectBy = async function (val) {
try {
@ -135,29 +150,38 @@ const ConsumeSelectBy = async function (val) {
// POST
const result = await request({
// url: 'consumeUser/selectBy',
url: 'http://192.168.8.247:8081/consume/selectBy',
data: {
pageNum: getObj.value.pageNum,
pageSize: getObj.value.pageSize,
consumeUser: consumeUser.value
consumeUser: {
...consumeUser.value,
sortField: sortField.value,
sortOrder: sortOrder.value
}
}
})
console.log('请求成功2', sortField)
//
// detail.value
const detailWithoutSort = {...consumeUser.value}
delete detailWithoutSort.sortField
delete detailWithoutSort.sortOrder
//
//
totalGoldSearch.value.startTime = consumeUser.value.startTime
totalGoldSearch.value.endTime = consumeUser.value.endTime
totalGoldSearch.value.payPlatform = consumeUser.value.payPlatform
totalGoldSearch.value.market = consumeUser.value.market
totalGoldSearch.value.goodsName = consumeUser.value.goodsName
//
const resultTotalGold = await request({
// url: 'http://192.168.8.247:8081/consume/statsGold',
url: 'http://192.168.8.247:8081/consume/statsGold',
// data: {
// pageNum: getObj.value.pageNum,
// pageSize: getObj.value.pageSize,
// consumeUser: consumeUser.value
// }
data: totalGoldSearch.value
})
@ -292,9 +316,7 @@ const get7Days = function () {
console.log('getTime', getTime.value)
ConsumeSelectBy()
}
//
const goods = ref([])
//
const getGoods = async function () {
try {
// POST
@ -335,19 +357,18 @@ const getMarket = async function () {
}
}
//
const handleSortChange = (column) => {
console.log('排序字段:', column.prop)
console.log('排序方式:', column.order)
if (column.prop === 'permanentGold') {
sortField.value = 'recharge_coin'
sortField.value = 'permanentGold'
} else if (column.prop === 'taskGold') {
sortField.value = 'task_coin'
sortField.value = 'taskGold'
} else if (column.prop === 'freeGold') {
sortField.value = 'free_coin'
sortField.value = 'freeGold'
} else if (column.prop === 'createTime') {
sortField.value = 'create_time'
sortField.value = 'createTime'
}
sortOrder.value = column.order === 'ascending' ? 'DESC' : 'ASC'
ConsumeSelectBy()
@ -388,7 +409,23 @@ const checkNumber = function () {
})
}
}
//
/*
====================计算属性=================================
*/
//
const sumGold = computed(() => permanentGolds.value + freeGolds.value + taskGolds.value)
/*
====================监听=================================
*/
/*
====================挂载=================================
*/
onMounted(async function () {
await getAdminData()
await ConsumeSelectBy()
@ -610,7 +647,7 @@ onMounted(async function () {
</template>
</el-table-column>
<el-table-column
prop="taskCold"
prop="taskGold"
label="任务金币"
sortable="“custom”"
width="110px"

244
src/views/managerecharge/rate.vue

@ -3,32 +3,27 @@ import {onMounted, reactive, ref} from 'vue'
import {ElMessage, ElMessageBox} from 'element-plus'
import request from '@/util/http'
/*
====================工具方法=========================
*/
/*
====================数据===================================
*/
//
const adminData = ref({
adminId: '',
name: ''
})
const getAdminData = async function () {
try {
const result = await request({
url: '/admin/userinfo',
data: {}
})
adminData.value = result
rateEdit.value.adminId = adminData.value.adminId
console.log('请求成功', result)
} catch (error) {
console.log('请求失败', error)
}
}
//
const regeEdit = ref(false)
// (id )
const editFormRef = ref(null)
//
const tableData = ref([])
@ -40,7 +35,92 @@ const getObj = ref({
const total = ref(0)
//
const rateEdit = ref({
id: null,
rateName: '',
num: null,
adminId: null,
updateTime: Date.now(),
})
//
const rateNames = [
{
value: 'USD',
label: 'USD'
},
{
value: 'HKD',
label: 'HKD'
},
{
value: 'THB',
label: 'THB'
},
{
value: 'VND',
label: 'VND'
},
{
value: 'CAD',
label: 'CAD'
},
{
value: 'MYR',
label: 'MYR'
},
{
value: 'KRW',
label: 'KRW'
},
{
value: 'JPY',
label: 'JPY'
},
{
value: 'CNY',
label: 'CNY'
}
]
//
const checkFreeGoldRadio = function (rule, value, callback) {
if (value == '0' || value == null || value == '') {
callback(new Error('请输入汇率比'))
} else if (value < 0 || isNaN(value)) {
callback(new Error('请输入正确的格式'))
} else {
callback()
}
}
//
const rules = reactive({
rateName: [{required: true, message: '请选择货币名称', trigger: 'blur'}],
num: [{validator: checkFreeGoldRadio, trigger: 'blur'}],
})
//
const formSize = ref('default')
/*
====================方法=========================
*/
//
const getAdminData = async function () {
try {
const result = await request({
url: '/admin/userinfo',
data: {}
})
adminData.value = result
rateEdit.value.adminId = adminData.value.adminId
console.log('请求成功', result)
} catch (error) {
console.log('请求失败', error)
}
}
//
const getAllRate = async function (val) {
try {
//
@ -72,26 +152,19 @@ const getAllRate = async function (val) {
}
}
//
const handlePageSizeChange = function (val) {
getObj.value.pageSize = val
getAllRate()
}
//
const handleCurrentChange = function (val) {
getObj.value.pageNum = val
getAllRate()
}
//
const rateEdit = ref({
id: null,
rateName: '',
num: null,
adminId: null,
updateTime: Date.now(),
})
//
//id
const getEditData = async function (row) {
try {
console.log('搜索参数', getObj.value)
@ -116,7 +189,7 @@ const getEditData = async function (row) {
console.log('请求失败', error)
}
}
//
const editRate = async function () {
try {
console.log('搜索参数', rateEdit.value)
@ -132,6 +205,8 @@ const editRate = async function () {
console.log('请求失败', error)
}
}
//
const edit = () => {
ElMessageBox.confirm('确认修改?')
.then(() => {
@ -149,61 +224,14 @@ const cancelEdit = () => {
}
//
const handleEditDialogClose = () => {
if (editFormRef.value) {
getAllRate()
}
}
//
onMounted(async function () {
await getAllRate()
await getAdminData()
})
//
const options = [
{
value: 'USD',
label: 'USD'
},
{
value: 'HKD',
label: 'HKD'
},
{
value: 'THB',
label: 'THB'
},
{
value: 'VND',
label: 'VND'
},
{
value: 'CAD',
label: 'CAD'
},
{
value: 'MYR',
label: 'MYR'
},
{
value: 'KRW',
label: 'KRW'
},
{
value: 'JPY',
label: 'JPY'
},
{
value: 'CNY',
label: 'CNY'
}
]
//
function formatDate(value) {
if (!value) return ''
const date = new Date(value)
@ -217,51 +245,55 @@ function formatDate(value) {
}
const checkFreeGoldRadio = function (rule, value, callback) {
if (value == '0' || value == null || value == '') {
callback(new Error('请输入汇率比'))
} else if (value < 0 || isNaN(value)) {
callback(new Error('请输入正确的格式'))
} else {
callback()
}
}
const rules = reactive({
rateName: [{required: true, message: '请选择货币名称', trigger: 'blur'}],
num: [{validator: checkFreeGoldRadio, trigger: 'blur'}],
})
//
function handleInput(value) {
//
let validValue = value.replace(/[^\d.]/g, '');
// 使
if (value.includes('。') || /[^\d.]/g.test(value)) {
ElMessage.warning('请输入正确的符号');
// value = value.replace('', '.');
}
//
const parts = validValue.split('.');
const parts = value.split('.');
if (parts.length > 2) {
validValue = parts[0] + '.' + parts.slice(1).join('');
ElMessage.warning('请输入正确格式');
value = parts[0] + '.' + parts.slice(1).join('');
ElMessage.warning('只能包含一个小数点');
}
// 7
const [integerPart, decimalPart = ''] = validValue.split('.');
if (decimalPart.length > 7) {
validValue = `${integerPart}.${decimalPart.slice(0, 7)}`;
ElMessage.warning('最多只能输入7位小数');
//
if (value.startsWith('-')) {
ElMessage.warning('不允许输入负数');
value = value.substring(1);
}
//
const isValidFormat = /^\d+(\.\d{0,7})?$/.test(validValue);
if (value && !isValidFormat) {
ElMessage.warning('请输入正确的数字格式');
// 0
if (value.startsWith('.')) {
value = '0' + value;
ElMessage.info('已自动补充前导0');
}
//
rateEdit.value.num = validValue;
return validValue;
rateEdit.value.num = value;
return value;
}
//
const formSize = ref('default')
/*
====================监听=========================
*/
/*
====================挂载=========================
*/
//
onMounted(async function () {
await getAllRate()
await getAdminData()
})
</script>
@ -362,7 +394,7 @@ const formSize = ref('default')
style="width: 240px"
>
<el-option
v-for="item in options"
v-for="item in rateNames"
:key="item.value"
:label="item.label"
:value="item.value"

Loading…
Cancel
Save