Browse Source

再试一下

lihuilin 1 week ago
parent
commit
9d01673fdf
  1. 18
      src/router/index.js
  2. 316
      src/views/audit/rechargeAudit.vue
  3. 1151
      src/views/audit/refundAudit.vue
  4. 639
      src/views/consume/coinConsume.vue
  5. 9
      src/views/index.vue
  6. 79
      src/views/login.vue
  7. 232
      src/views/managerecharge/rate.vue
  8. 702
      src/views/recharge/coinRecharge.vue
  9. 2
      src/views/refund/beanRefund.vue
  10. 797
      src/views/refund/coinRefund.vue
  11. 798
      src/views/usergold/index.vue
  12. 1482
      src/views/workspace/index.vue

18
src/router/index.js

@ -18,14 +18,7 @@ const router = createRouter({
// 退款审核
{ path: '/refundAudit', name: "refundAudit", component: () => import("../views/audit/refundAudit.vue") },
// 金币消耗
{ path: '/coinConsume', name: "coinConsume", component: () => import("../views/consume/coinConsume.vue"),
children: [
// 金币新增消耗
{ path: 'add', name: "addCoinConsume", component: () => import("../views/consume/addCoinConsume.vue") },
// 金币消耗明细详情
{ path: 'detail', name: "coinConsumeDetail", component: () => import("../views/consume/coinConsumeDetail.vue") }
]
},
{ path: '/coinConsume', name: "coinConsume", component: () => import("../views/consume/coinConsume.vue") },
// 金豆消耗
{ path: '/beanConsume', name: "beanConsume", component: () => import("../views/consume/beanConsume.vue") },
// 汇率管理
@ -39,14 +32,7 @@ const router = createRouter({
// 金豆退款
{ path: '/beanRefund', name: "beanRefund", component: () => import("../views/refund/beanRefund.vue") },
// 客户账户明细
{ path: '/usergold', name: "usergold", component: () => import("../views/usergold/clientCount.vue"),
children: [
// 金币明细
{ path: 'detail', name: "clientCountDetail", component: () => import("../views/usergold/clientCountDetail.vue") },
// 金币余额
{ path: 'balance', name: "clientCountBalance", component: () => import("../views/usergold/clientCountBalance.vue") },
]
},
{ path: '/usergold', name: "usergold", component: () => import("../views/usergold/index.vue") },
// 权限管理
{ path: '/permissions', name: "permissions", component: () => import("../views/permissions/index.vue") },
// 没有权限

316
src/views/audit/rechargeAudit.vue

@ -7,32 +7,6 @@ import axios from 'axios'
import request from '@/util/http'
import moment from 'moment'
//
//
const columnOptions = ref([
{ prop: 'username', label: '姓名', width: 125 },
{ prop: 'jwcode', label: '精网号', width: 125 },
{ prop: 'area', label: '所属地区', width: 125 },
{ prop: 'activityName', label: '活动名称', width: 150 },
{ prop: 'rechargeGold', label: '充值金额', width: 125, sortable: true },
{ prop: 'rechargeWay', label: '充值方式', width: 125 },
{ prop: 'paidGold', label: '永久金币', width: 125, sortable: true },
{ prop: 'freeGold', label: '免费金币', width: 125, sortable: true },
{ prop: 'remark', label: '备注', width: 200, showOverflowTooltip: true },
{ prop: 'payWay', label: '支付方式', width: 125 },
{ prop: 'rechargeVoucher', label: '支付凭证', width: 125 },
{ prop: 'name', label: '提交人', width: 125 },
{ prop: 'status', label: '审核状态', width: 125 },
{ prop: 'reson', label: '驳回理由', width: 200 },
{ prop: 'rechargeTime', label: '交款时间', width: 200, sortable: true },
{ prop: 'createTime', label: '提交时间', width: 200, sortable: true },
{ prop: 'auditTime', label:'审核时间', width:200, sortable:true}
])
//
const defaultColumns = ['username', 'jwcode', 'area', 'activityName', 'rechargeGold', 'rechargeWay', 'paidGold', 'freeGold',
'remark', 'payWay', 'rechargeVoucher', 'name', 'status', 'reson', 'rechargeTime', 'createTime', 'auditTime']
const selectedColumns = ref([...defaultColumns])
//
const adminData = ref({})
const getAdminData = async function () {
@ -42,7 +16,6 @@ const getAdminData = async function () {
data: {}
})
adminData.value = result
console.log('请求成功', result)
console.log('用户信息', adminData.value)
} catch (error) {
console.log('请求失败', error)
@ -52,7 +25,6 @@ const getAdminData = async function () {
//
const tableData = ref([])
// ======================================
// rechargeVo
const rechargeVo = ref({
rechargeWay: '客服充值'
})
@ -67,22 +39,16 @@ const total = ref(100)
const getTime = ref([])
//
const activity = ref([])
//
const allData = ref([])
//
const area = ref([])
// ======================================
//
const rejectVisible = ref(false)
//
const rejectObj = ref({})
//
const passObj = ref({})
//
const activeName = ref('all')
//
const activeName = ref('wait')
//
const payWay = [
{
@ -106,23 +72,16 @@ const payWay = [
label: '借记卡'
}
]
// //
// const tableHeight = computed(function () {
// return (getObj.value.pageSize + 2) * 60 + "px";
// });
// 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))
@ -144,15 +103,12 @@ const rejectedCount = ref(0)
const rejectedGold = ref(0)
const rejectedRGold = ref(0)
const rejectedFGold = ref(0)
// ==============================================================
//
const get = async function (val) {
try {
//
if (adminData.value.area === '泰国') {
rechargeVo.value.areas = ['泰国', '越南']
} else if (adminData.value.area !== '总部') {
rechargeVo.value.area = adminData.value.area
}
//
if (typeof val === 'number') {
@ -171,7 +127,6 @@ const get = async function (val) {
rechargeVo.value.sortField = sortField.value
rechargeVo.value.sortOrder = sortOrder.value
console.log('搜索参数', getObj.value)
// POST
const result = await request({
url: '/recharge/recharge',
data: {
@ -181,16 +136,15 @@ const get = async function (val) {
}
})
//
// rechargeVo.value
const detailWithoutSort = { ...rechargeVo.value }
delete detailWithoutSort.sortField
delete detailWithoutSort.sortOrder
delete detailWithoutSort.status
// rechargeVo.value
const rechargeVo1 = { ...rechargeVo.value }
delete rechargeVo1.sortField
delete rechargeVo1.sortOrder
delete rechargeVo1.status
const result2 = await request({
url: '/recharge/recharge/RechargeA',
data: detailWithoutSort
data: rechargeVo1
})
// result2.data[i].flag="" totalData.value = result2.data[i]0
//
if (result2.data) {
result2.data.forEach((item) => {
@ -220,16 +174,11 @@ const get = async function (val) {
}
trueGold.value = pendingGold.value + approvedGold.value + rejectedGold.value
trueCount.value =
pendingCount.value + approvedCount.value + rejectedCount.value
trueRGold.value =
pendingRGold.value + approvedRGold.value + rejectedRGold.value
trueFGold.value =
pendingFGold.value + approvedFGold.value + rejectedFGold.value
trueCount.value = pendingCount.value + approvedCount.value + rejectedCount.value
trueRGold.value = pendingRGold.value + approvedRGold.value + rejectedRGold.value
trueFGold.value = pendingFGold.value + approvedFGold.value + rejectedFGold.value
//
console.log('请求成功', result)
console.log('这是分页', getObj.value)
console.log('搜索对象', getObj.value)
//
tableData.value = result.data.list
console.log('tableData', tableData.value)
@ -238,7 +187,6 @@ const get = async function (val) {
console.log('total', total.value)
} catch (error) {
console.log('请求失败', error)
//
}
}
//
@ -309,13 +257,6 @@ const get7Days = function () {
console.log('getTime', getTime.value)
get()
}
//
const adminAll = function () {
console.log('adminAll')
rechargeVo.value.status = ''
getObj.value.pageNum = 1
get()
}
//
const adminWait = async function () {
rechargeVo.value.status = 0
@ -349,11 +290,9 @@ const adminReject = async function () {
trueRGold.value = rejectedRGold.value
trueFGold.value = rejectedFGold.value
}
//
const handleClick = function (tab, event) {
if (tab.props.name === 'all') {
adminAll()
} else if (tab.props.name === 'wait') {
if (tab.props.name === 'wait') {
adminWait()
} else if (tab.props.name === 'pass') {
adminPass()
@ -361,67 +300,30 @@ const handleClick = function (tab, event) {
adminReject()
}
}
//
const getActivity = async function () {
try {
// POST
const result = await request({
url: '/recharge/activity/select',
data: {}
})
//
console.log('请求成功', result)
//
activity.value = result.data
console.log('activity', activity.value)
} catch (error) {
console.log('请求失败', error)
//
}
}
//
//
const getArea = async function () {
try {
// POST
const result = await request({
url: '/recharge/user/search',
data: {}
})
//
console.log('请求成功', result)
//
area.value = result.data
console.log('地区', area.value)
} catch (error) {
console.log('请求失败', error)
//
}
}
//
const checkNumber = function () {
if (typeof parseInt(getObj.value.pageNum) === 'number') {
console.log('总共有多少页' + Math.ceil(total.value / getObj.value.pageSize))
if (
getObj.value.pageNum > 0 &&
getObj.value.pageNum <= Math.ceil(total.value / getObj.value.pageSize)
) {
console.log('输入的数字合法')
getObj.value.pageNum = parseInt(getObj.value.pageNum)
get()
} else {
//
ElMessage({
type: 'error',
message: '请检查输入内容'
})
}
} else {
//
ElMessage({
type: 'error',
message: '请检查输入内容'
})
}
}
const handlePageSizeChange = function (val) {
@ -462,10 +364,7 @@ const passConfirm = async function () {
url: '/audit/audit/goldedit',
data: passObj.value
})
//
console.log('请求成功', result)
//
get()
//
ElMessage({
@ -512,24 +411,17 @@ const rejectConfirm = async function () {
url: '/audit/audit/goldedit',
data: rejectObj.value
})
//
console.log('请求成功', result)
//
get()
//
closeRejectVisible()
//
closeRejectVisible()//
ElMessage({
type: 'success',
message: '驳回成功!'
})
} catch (error) {
console.log('请求失败', error)
//
}
} else {
//
ElMessage({
type: 'error',
message: '请检查输入内容'
@ -539,7 +431,6 @@ const rejectConfirm = async function () {
}
//
const rules = reactive({
reson: [{ required: true, message: '请输入驳回理由', trigger: 'blur' }]
})
@ -568,7 +459,7 @@ const handleSortChange = (column) => {
sortField.value = 'create_time'
} else if (column.prop === 'paidGold') {
sortField.value = 'paid_gold'
}else if (column.prop === 'auditTime') {
} else if (column.prop === 'auditTime') {
sortField.value = 'audit_time'
}
sortOrder.value = column.order === 'ascending' ? 'ASC' : 'DESC'
@ -586,35 +477,27 @@ const trimJwCode = () => {
<template>
<el-row>
<el-col>
<el-card style="margin-bottom: 20px">
<el-row style="margin-bottom: 10px">
<el-card style="margin-bottom: 5px">
<el-row style="margin-bottom: 5px">
<el-col :span="6">
<div class="head-card-element">
<el-text class="mx-1" size="large">精网号</el-text>
<el-text size="large">精网号</el-text>
<el-input v-model="rechargeVo.jwcode" placeholder="请输入精网号" style="width: 240px" clearable />
</div>
</el-col>
<el-col :span="6">
<div class="head-card-element">
<el-text class="mx-1" 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-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>
</div>
</el-col>
<el-col :span="6">
<div class="head-card-element">
<el-text class="mx-1" size="large">支付方式</el-text>
<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>
</div>
</el-col>
<el-col :span="6">
<div class="head-card-element" v-if="adminData.area == '总部'">
<el-text class="mx-1" size="large">所属地区</el-text>
<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>
@ -622,38 +505,22 @@ const trimJwCode = () => {
</el-col>
</el-row>
<el-row>
<el-col :span="16">
<div class="time-controls">
<div class="time-group">
<el-text class="mx-1" 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>
<el-button @click="getYesterday()" style="margin-left: 10px"> </el-button>
<el-button @click="get7Days()" style="margin-left: 10px"> 近7天 </el-button>
<el-col :span="12">
<div class="time-controls">
<div class="time-group">
<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>
<el-button @click="getYesterday()" style="margin-left: 10px"> </el-button>
<el-button @click="get7Days()" style="margin-left: 10px"> 近7天 </el-button>
</div>
</div>
</div>
</el-col>
</el-col>
<el-col :span="8">
<el-button @click="reset()" type="success" style="margin-right: 10px">重置</el-button>
<el-col :span="8">
<el-button @click="reset()" type="success">重置</el-button>
<el-button type="primary" @click="search()">查询</el-button>
</el-col>
</el-row>
<el-row>
<el-col :span="21">
<div style="margin-top: 10px">
<el-text class="mx-1" size="large">请选择您想看到的数据</el-text>
<el-select v-model="selectedColumns" multiple placeholder="请选择您想看到的数据" size="large" style="width: 800px">
<el-option v-for="item in columnOptions" :key="item.prop" :label="item.label" :value="item.prop" />
</el-select>
</div>
</el-col>
</el-row>
</el-card>
@ -662,71 +529,49 @@ const trimJwCode = () => {
<el-row>
<el-col>
<el-card>
<el-tabs v-model="activeName" type="card" class="demo-tabs" @tab-click="handleClick">
<el-tab-pane label="全部" name="all"></el-tab-pane>
<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>
<div>
总条数{{ trueCount }}总金币数{{
formattedTrueGold
}}金币永久金币{{ formattedTrueRGold }}金币免费金币{{ formattedTrueFGold }}金币
总条数{{ 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-column type="index" label="序号" width="100px" fixed="left">
<template #default="scope">
<span>{{
scope.$index + 1 + (getObj.pageNum - 1) * getObj.pageSize
}}</span>
<span>{{ scope.$index + 1 + (getObj.pageNum - 1) * getObj.pageSize }}</span>
</template>
</el-table-column>
<!-- 动态列 -->
<template v-for="col in columnOptions" :key="col.prop">
<el-table-column v-if="selectedColumns.includes(col.prop)" :prop="col.prop" :label="col.label"
:width="col.width" :sortable="col.sortable ? 'custom' : false"
:show-overflow-tooltip="true" >
<template #default="scope">
<!-- 特殊列模板 -->
<template v-if="col.prop === 'rechargeTime'">
{{ moment(scope.row.rechargeTime).format('YYYY-MM-DD HH:mm:ss') }}
</template>
<template v-else-if="col.prop === 'createTime'">
{{ moment(scope.row.createTime).format('YYYY-MM-DD HH:mm:ss') }}
</template>
<template v-else-if="col.prop === 'auditTime'">
{{ scope.row.auditTime ? moment(scope.row.auditTime).format('YYYY-MM-DD HH:mm:ss') : '----' }}
</template>
<template v-else-if="col.prop === 'remark'">
<span>{{ scope.row[col.prop] }}</span>
</template>
<template v-else-if="col.prop === 'rechargeVoucher'">
<el-image :src="scope.row.rechargeVoucher" style="width: 50px; height: 50px" />
</template>
<template v-else-if="col.prop === 'status'">
<div class="status">
<span :class="{
'green-dot': scope.row.status === 1,
'grey-dot': scope.row.status === 0,
'red-dot': scope.row.status === 2
}"></span>
<span>{{
scope.row.status === 1 ? '已通过' :
scope.row.status === 0 ? '待审核' : '已驳回'
}}</span>
</div>
</template>
<template v-else-if="['paidGold', 'freeGold'].includes(col.prop)">
{{ scope.row[col.prop] / 100 }}
</template>
<span v-else>
{{ scope.row[col.prop] }}
</span>
</template>
<el-table-column fixed="left" prop="username" 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>
<el-table-column prop="freeCoin" label="免费金币" sortable="custom" width="110px">
<template #default="scope">{{ scope.row.freeCoin }}</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="adminName" label="提交人" width="100px" />
<el-table-column prop="status" label="付款时间" width="200px" >
<template #default="scope">
{{ moment(scope.row.createTime).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
</template>
<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 fixed="right" prop="operation" label="操作" width="150px">
<template #default="scope">
<div class="operation">
@ -741,9 +586,7 @@ const trimJwCode = () => {
</template>
<template #actions="{ confirm, cancel }">
<el-button size="small" @click="cancel">取消</el-button>
<el-button type="primary" size="small" @click="confirm">
确定
</el-button>
<el-button type="primary" size="small" @click="confirm">确定</el-button>
</template>
</el-popconfirm>
<el-button :disabled="scope.row.status === 1 || scope.row.status === 2
@ -758,7 +601,6 @@ const trimJwCode = () => {
</el-table>
</div>
<!-- 分页 -->
<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"
@ -768,7 +610,6 @@ const trimJwCode = () => {
</el-col>
</el-row>
<!-- 驳回弹出框 -->
<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">
@ -825,17 +666,23 @@ const trimJwCode = () => {
.status {
display: flex;
align-items: center; /* 确保子元素垂直居中对齐 */
gap: 6px; /* 设置圆点和文字之间的间距 */
align-items: center;
/* 确保子元素垂直居中对齐 */
gap: 6px;
/* 设置圆点和文字之间的间距 */
}
.green-dot, .grey-dot, .red-dot {
.green-dot,
.grey-dot,
.red-dot {
display: inline-block;
width: 8px;
height: 8px;
border-radius: 50%;
flex-shrink: 0; /* 防止圆点在空间不足时缩小 */
margin: 0; /* 移除原有的 margin-right */
flex-shrink: 0;
/* 防止圆点在空间不足时缩小 */
margin: 0;
/* 移除原有的 margin-right */
}
/* 备注列样式 */
@ -846,6 +693,7 @@ const trimJwCode = () => {
text-overflow: ellipsis;
white-space: nowrap;
}
/* 设置单元格内容溢出隐藏 */
.el-table .el-table__cell {
overflow: hidden;

1151
src/views/audit/refundAudit.vue
File diff suppressed because it is too large
View File

639
src/views/consume/coinConsume.vue

@ -1,61 +1,602 @@
<template>
<div>
<!-- 这里放置标签切换的按钮 -->
<el-button-group>
<!-- 切换后状态显示 primary 样式否则是默认样式 -->
<el-button
:type="activeTab === 'add' ? 'primary' : 'default'"
@click="goToAdd"
>
新增消耗
</el-button>
<el-button
:type="activeTab === 'detail' ? 'primary' : 'default'"
@click="goToDetail"
>
金币消耗明细
</el-button>
</el-button-group>
<!-- 渲染子路由组件 -->
<router-view></router-view>
</div>
</template>
<script setup>
import { ref, watch } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import { reactive, onMounted } from "vue";
import { ref, computed, watch } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { Plus } from "@element-plus/icons-vue";
import axios from "axios";
import moment from "moment";
import _ from "lodash";
import request from "@/util/http";
//
const trimJwCode = () => {
if (addConsume.value.jwcode) {
addConsume.value.jwcode = addConsume.value.jwcode.replace(/\s/g, '');
}
}
//
const adminData = ref({});
const getAdminData = async function () {
try {
const result = await request({
url: "/admin/userinfo",
data: {},
});
adminData.value = result;
addConsume.value.adminId = adminData.value.adminId;
addConsume.value.name = adminData.value.name;
console.log("请求成功", result);
console.log("用户信息", adminData.value);
} catch (error) {
console.log("请求失败", error);
}
};
const router = useRouter();//
const route = useRoute();//
// activeTab
const activeTab = ref(route.name === 'coinConsumeDetail' ? 'detail' : 'add');
//coinConsumeDetaildetailadd
//coinConsumeadd
//
const addConsume = ref({
freeCoin: 0,
rechargeCoin: 0,
taskCoin: 0,
updateType: "1",
indexName: "", //
});
//
const add = async function () {
try {
// 使
addConsume.value.rechargeCoin = Number(addConsume.value.rechargeCoin * 100);
addConsume.value.freeCoin = Number(addConsume.value.freeCoin * 100);
addConsume.value.taskCoin = Number(addConsume.value.taskCoin * 100);
addConsume.value.productName = indexs.value.productName;
// POST
const result = await request({
url: "/consume/add",
data: addConsume.value,
});
if (result.code === 0) {
ElMessage.error(result.msg);
return;
} else {
ElMessage.success("添加成功");
}
//
addConsume.value = {};
addConsume.value.adminId = adminData.value.adminId;
addConsume.value.adminName = adminData.value.adminName;
addConsume.value.updateType = "1";
addConsume.value.freeCoin = 0;
addConsume.value.rechargeCoin = 0;
addConsume.value.taskCoin = 0;
indexs.value = {};
console.log("请求成功", result);
user.value = {};
} catch (error) {
console.log("请求失败", error);
ElMessage.error("添加失败,请检查输入内容是否正确");
//
}
};
const addBefore = () => {
Ref.value.validate(async (valid) => {
if (valid) {
ElMessageBox.confirm("确认添加?")
.then(() => {
addConsume.value.freeCoin = Number(-addConsume.value.freeCoin);
addConsume.value.rechargeCoin = Number(
-addConsume.value.rechargeCoin
);
addConsume.value.taskCoin = Number(-addConsume.value.taskCoin);
add();
console.log("添加成功");
imageUrl.value = "";
addConsume.value = {};
})
.catch(() => {
console.log("取消添加");
});
} else {
//
ElMessage({
type: "error",
message: "请检查输入内容",
});
}
});
};
//
//
const Ref = ref(null);
const goToAdd = () => {
// activeTab add
activeTab.value = 'add';
router.push({ name: 'addCoinConsume' });
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({
jwcode: [{ required: true, message: "请输入精网号", trigger: "blur" }],
productName: [{ required: true, message: "请选择消费商品", trigger: "change" }], // change
taskCoin: [{ required: true, message: "请输入任务金币", trigger: "blur" }],
freeCoin: [{ required: true, message: "请输入免费金币", trigger: "blur" }],
rechargeCoin: [
{ required: true, message: "请输入免费金币", trigger: "blur" },
],
allGold: [
{ required: true, message: "消费金币总数不能为空", trigger: "blur" },
{ validator: checkFreeGoldRadio, trigger: "blur" },
],
indexName: [
{
required: true,
validator: (rule, value, callback) => {
if (isHC.value === 1 && !value) {
callback(new Error("请选择指标"));
} else {
callback();
}
},
trigger: ["change", "blur"],
},
]
});
//
const delteConsume = function () {
addConsume.value = {};
addConsume.value.adminId = adminData.value.adminId;
addConsume.value.adminName = adminData.value.adminName;
addConsume.value.updateType = "1";
addConsume.value.freeCoin = 0;
addConsume.value.rechargeCoin = 0;
addConsume.value.taskCoin = 0;
indexs.value = {};
isHC.value = 0;
};
//
const user = ref({
firstRechargeTime: "",
});
const getUser = async function (jwcode) {
trimJwCode();
try {
// POST
const result = await request({
url: "/recharge/user",
data: {
jwcode: addConsume.value.jwcode,
area: adminData.value.area,
},
});
console.log("请求成功", result);
const goToDetail = () => {
// activeTab detail
activeTab.value = 'detail';
router.push({ name: 'coinConsumeDetail' });
if (result.code === 0) {
ElMessage.error(result.msg);
} else {
user.value = result.data;
user.value.A =
Number(user.value.pendingRechargeTimes) +
Number(user.value.pendingSpendTimes);
console.log("用户信息", user.value);
ElMessage.success(result.msg);
}
} catch (error) {
console.log("请求失败", error);
ElMessage.error("查询失败,请检查精网号是否正确");
//
}
};
// activeTab
watch(() => route.name, (newName) => {
if (newName === 'addCoinConsume') {
activeTab.value = 'add';
} else if (newName === 'coinConsumeDetail') {
activeTab.value = 'detail';
//
//
const userGold = ref({});
const getUserGold = async function (jwcode) {
trimJwCode();
try {
// POST
const result = await request({
url: "/recharge/user",
data: {
jwcode: addConsume.value.jwcode,
area: adminData.value.area,
},
});
//
console.log("请求成功", result);
if (result.code === 0) {
//ElMessage.error(result.msg);
} else {
//
userGold.value = result.data;
addConsume.value.username = result.data.name;
addConsume.value.area = result.data.area;
// ElMessage.success(result.msg);
}
} catch (error) {
console.log("请求失败", error);
//ElMessage.error("");
addConsume.value.jwcode = "";
//
}
});
};
//
if (route.name === 'coinConsume') {
router.push({ name: 'addCoinConsume' });
function calculateCoins() {
if (
(userGold.value.coreJb +
userGold.value.free6 +
userGold.value.free12 +
userGold.value.buyJb) /
100 <
addConsume.value.allGold
) {
addConsume.value.allGold = 0;
addConsume.value.taskCoin = 0;
addConsume.value.freeCoin = 0;
addConsume.value.rechargeCoin = 0;
ElMessage.error("金币不足,请充值");
return;
}
//
else {
// allGold
const originalAllGold = addConsume.value.allGold;
// todayTasktodayFree
const todayTask =
typeof userGold.value.coreJb === "number"
? userGold.value.coreJb / 100
: 0;
const todayFree =
typeof (userGold.value.free6 + userGold.value.free12) === "number"
? (userGold.value.free6 + userGold.value.free12) / 100
: 0;
//
addConsume.value.taskCoin = Math.min(originalAllGold, todayTask);
let remainingGold = originalAllGold - addConsume.value.taskCoin;
addConsume.value.freeCoin = Math.min(remainingGold, todayFree);
remainingGold -= addConsume.value.freeCoin;
addConsume.value.rechargeCoin = remainingGold; //
// allGold
addConsume.value.allGold = originalAllGold;
// taskCoin, freeCoin, rechargeCoinNaN0
if (isNaN(addConsume.value.taskCoin)) addConsume.value.taskCoin = 0;
if (isNaN(addConsume.value.freeCoin)) addConsume.value.freeCoin = 0;
if (isNaN(addConsume.value.rechargeCoin)) addConsume.value.rechargeCoin = 0;
console.log("计算结果", addConsume.value);
}
}
//
const goods = ref([]);
const getGoods = async function () {
try {
// POST
const result = await request({
url: "/product",
data: {},
});
//
console.log("请求成功", result);
//
goods.value = result.data;
} catch (error) {
console.log("请求失败", error);
//
}
};
//
const index = ref([]);
const getIndexs = async function (type) {
try {
// POST
const result = await request({
url: "/product/index",
data: {
type: type,
},
});
//
console.log("请求成功", result);
//
index.value = result.data;
} catch (error) {
console.log("请求失败", error);
//
}
};
//
const isHC = ref(0);
// const handleProductSelect = (productName) => {
// //
// // indexs.value.productName = productName;
// if (productName === "homilychart") {
// isHC.value = 1;
// addConsume.value.productName = "homilychart"; //
// addConsume.value.indexName = ""; //
// } else {
// isHC.value = 0;
// addConsume.value.productName = productName;
// addConsume.value.indexName = "";
// }
// };
const indexs = ref([]);
// const handleIndexSelect = () => {
// if (isHC.value === 1 && addConsume.value.indexName) {
// addConsume.value.productName = "homilychart" + addConsume.value.indexName;
// }
// };
//
const queryProductSearch = (queryString, cb) => {
const results = queryString
? goods.value.filter(item =>
item.name.toLowerCase().includes(queryString.toLowerCase())
)
: goods.value;
cb(results);
};
//
const queryIndexSearch = (queryString, cb) => {
const results = queryString
? index.value.filter(item => // indexData index
item.name.toLowerCase().includes(queryString.toLowerCase())
)
: index.value;
cb(results);
};
//
const handleProductSelect = async (selectedItem) => {
const productName = typeof selectedItem === 'string'
? selectedItem
: selectedItem?.name || '';
if (productName === "homilychart") {
isHC.value = 1;
addConsume.value.productName = "homilychart";
addConsume.value.indexName = "";
//
await getIndexs("homilychart");
} else {
isHC.value = 0;
addConsume.value.productName = productName;
addConsume.value.indexName = "";
}
};
//
const handleIndexSelect = (selectedItem) => {
if (isHC.value === 1) {
const indexName = typeof selectedItem === 'string'
? selectedItem
: selectedItem?.name || '';
//
addConsume.value.indexName = indexName;
}
};
//
const handleIndexBlur = (e) => {
if (isHC.value === 1 && e.target.value) {
//
addConsume.value.indexName = e.target.value;
}
};
//
onMounted(async function () {
await getAdminData();
await getGoods();
await getIndexs(1);
});
const handleSelectBlur = (value) => {
//
// v-model
if (value) {
//
if (addConsume.value.productName === value) {
addConsume.value.productName = value;
}
//
else if (indexs.value.name === value) {
indexs.value.name = value;
}
}
};
</script>
<template>
<div style="margin-bottom: 20px; font-weight: bolder">新增消费</div>
<el-form :model="addConsume" ref="Ref" :rules="rules" label-width="auto" style="max-width: 750px;" class="form-style">
<el-form-item prop="jwcode" label="精网号">
<el-input v-model="addConsume.jwcode" style="width: 220px" @change="getUserGold(addConsume.jwcode)" />
<el-button type="primary" @click="getUser(addConsume.jwcode)" style="margin-left: 20px">查询</el-button>
</el-form-item>
<div style="display: flex; align-items: center; gap: 20px;">
<el-form-item prop="productName" label="商品名称" style="flex: 1; margin-right: 0px">
<el-autocomplete v-model="addConsume.productName" :fetch-suggestions="queryProductSearch" placeholder="请输入或选择商品"
style="width: 300px" @select="handleProductSelect" value-key="name" clearable :trigger-on-focus="true">
<template #default="{ item }">
<div>{{ item.name }}</div>
</template>
</el-autocomplete>
</el-form-item>
<!-- 指标选择 -->
<el-form-item prop="indexName" label="指标" v-if="isHC == 1" style="flex: 1;margin-left: -20px">
<el-autocomplete v-model="addConsume.indexName" :fetch-suggestions="queryIndexSearch" placeholder="请输入或选择指标"
style="width: 140px" @select="handleIndexSelect" @blur="handleIndexBlur" value-key="name"
:disabled="isHC !== 1" clearable free-solo allow-create>
<template #default="{ item }">
<div>{{ item.name }}</div>
</template>
</el-autocomplete>
</el-form-item>
<el-form-item label="指标" v-else style="flex:1;margin-left: -5px;">
<el-input disabled placeholder="无" style="width: 100px" />
</el-form-item>
</div>
<el-form-item prop="allGold" label="消费金币总数">
<el-input v-model="addConsume.allGold" style="width: 100px" @change="calculateCoins()" />
</el-form-item>
<div style="display: flex; align-items: center">
<el-form-item prop="rechargeCoin" label="永久金币" style="float: left">
<el-input disabled v-model="addConsume.rechargeCoin" style="width: 100px; margin-left: -5px" />
<p style="margin-right: 0px"></p>
</el-form-item>
<el-form-item prop="freeCoin" label="免费金币" style="float: left; margin-left: -20px">
<el-input disabled v-model="addConsume.freeCoin" style="width: 100px; margin-left: -5px" />
<p style="margin-right: 0px"></p>
</el-form-item>
<el-form-item prop="taskCoin" label="任务金币" style="margin-left: -20px">
<el-input disabled v-model="addConsume.taskCoin" style="width: 100px; margin-left: -5px" />
<p style="margin-right: 20px"></p>
</el-form-item>
</div>
<el-form-item prop="remark" label="备注">
<el-input v-model="addConsume.remark" style="width: 300px" :rows="2" maxlength="100" show-word-limit type="textarea" />
</el-form-item>
<el-form-item prop="commitName" label="提交人">
<el-input style="width: 300px" :value="adminData.name" disabled placeholder="提交人姓名" />
</el-form-item>
<el-button type="success" @click="delteConsume" style="margin-left: 280px">重置</el-button>
<el-button type="primary" @click="addBefore"> 提交 </el-button>
</el-form>
<el-card style="width: 850px; float: right" class="customer-info">
<el-form :model="user" label-width="auto" style="max-width: 1200px" label-position="left">
<el-text size="large" style="margin-left: 20px">客户信息</el-text>
<el-row style="margin-top: 20px">
<el-col :span="10">
<el-form-item label="姓名:">
<p>{{ user.name }}</p>
</el-form-item>
</el-col>
<el-col :span="14">
<el-form-item label="历史金币总数">
<!-- 检查 user.totalRechargeGold 是否为有效的数字 -->
<p v-if="!isNaN(Number(user.totalRechargeGold))">
{{ Number(user.totalRechargeGold / 100) }}
</p>
<!-- 如果不是有效的数字显示默认值 -->
<p v-else></p>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label="精网号">
<p>{{ user.jwcode }}</p>
</el-form-item>
</el-col>
<el-col :span="14">
<el-form-item label="当前金币总数" style="width: 500px">
<span style="color: #2fa1ff; margin-right: 5px" v-if="user.buyJb !== undefined">{{
(user.buyJb + user.free6 + user.free12 + user.coreJb) / 100
}}</span>
<span style="display: inline; white-space: nowrap; color: #b1b1b1" v-if="user.buyJb !== undefined">(永久金币:{{
user.buyJb / 100 }};免费金币:{{
(user.free6 + user.free12) / 100
}};任务金币:{{ user.coreJb / 100 }})</span>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label="首次充值日期">
<p v-if="user.firstRechargeDate">
{{ moment(user.firstRechargeDate).format("YYYY-MM-DD HH:mm:ss") }}
</p>
</el-form-item>
</el-col>
<el-col :span="14">
<el-form-item label="充值次数">
<p style="color: #2fa1ff">{{ user.rechargeTimes }}</p>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label="消费次数">
<p style="color: #2fa1ff">{{ user.spendTimes }}</p>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label="所属门店">
<p>{{ adminData.area }}</p>
</el-form-item>
</el-col>
<el-col :span="14">
<!-- <el-form-item label="待审核">
<p style="color: #2fa1ff">
{{ user.A }}
</p>
</el-form-item> -->
</el-col>
</el-row>
</el-form>
</el-card>
</template>
<style scoped>
p {
margin: 0px;
}
.el-form-item {
margin-left: 50px;
}
/* 上传图片的格式 */
.avatar-uploader .avatar {
width: 50px;
height: 50px;
display: block;
}
</style>
<style>
.avatar-uploader .el-upload {
border: 1px dashed var(--el-border-color);
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
transition: var(--el-transition-duration-fast);
}
.avatar-uploader .el-upload:hover {
border-color: var(--el-color-primary);
}
.el-icon.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 50px;
height: 50px;
text-align: center;
}
.form-style {
margin-top: 50px;
max-width: 50%;
float: left;
}
.form-style2 {
max-width: 60%;
}
p {
font-size: 13px;
transform: scale(1);
}
</style>

9
src/views/index.vue

@ -7,7 +7,7 @@ import { VscGlobe } from 'vue-icons-plus/vsc'
import { ElMessage, ElMessageBox } from 'element-plus'
import axios from 'axios'
import API from '@/util/http'
import dmmn from '../assets/blue.png'
import dmmn from '../assets/avator.png'
import { useRoute } from 'vue-router'
const router = useRouter()
@ -31,8 +31,6 @@ const getAdminData = async function () {
}
//
const areas = ref([])
//
const currentArea = ref('全部')
const getAreas = async function () {
try {
@ -74,10 +72,6 @@ onMounted(async function () {
//
getAreas()
})
//
const changeDataByArea = (item) => {
currentArea.value = item
}
//
const isCollapse = ref(false)
const handleOpen = (key, keyPath) => {
@ -231,7 +225,6 @@ const handleClose = (key, keyPath) => {
</el-header>
<!-- 修改 el-main 样式 -->
<el-main style="margin-top: 60px">
<!-- 60px el-header 的大致高度可根据实际情况调整 -->
<router-view></router-view>
</el-main>
</el-container>

79
src/views/login.vue

@ -27,10 +27,6 @@ getMachineId()
const router = useRouter() //
let formData = new FormData()
// FormData
// formData.append("jwcode", form.value.jwcode);
// formData.append("password", form.value.password);
const form = ref({ jwcode: '', password: '', token: '', machineId: machineId })
//
const login = async function () {
@ -63,7 +59,6 @@ const login = async function () {
} catch (error) {
console.log('请求失败', error)
ElMessage.error('登录失败,请检查账号密码')
//
}
}
@ -71,17 +66,9 @@ const login = async function () {
</script>
<template>
<el-row class="login-page">
<img
:span="12"
src="../assets/background.jpg"
alt="logo"
class="bg"
fit="fit"
/>
<!-- <div style="height: 100vh; width: 1000px" class="container"></div> -->
<img :span="12" src="../assets/background.jpg" alt="logo" class="bg" fit="fit" />
<el-col :span="6" :offset="3" class="form">
<!-- 登录表单 -->
<el-form :model="form" size="large" autocomplete="off" >
<el-form :model="form" size="large" autocomplete="off">
<el-form-item>
<h1 style="color: #409eff">金币系统登录</h1>
</el-form-item>
@ -89,37 +76,19 @@ const login = async function () {
<el-input v-model="form.jwcode" placeholder="请输入精网号" @keyup.enter="login"></el-input>
</el-form-item>
<el-form-item prop="password" @keyup.enter="login">
<el-input
v-model="form.password"
type="password"
placeholder="请输入密码"
/>
<el-input v-model="form.password" type="password" placeholder="请输入密码" />
</el-form-item>
<el-form-item class="flex"> </el-form-item>
<!-- 登录按钮 -->
<el-form-item>
<button type="button" class="button" @click="login()">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
height="30"
width="24"
>
<path
fill="white"
d="M23.15 2.587L18.21 0.210001C17.9308 0.075557 17.6167 0.031246 17.3113 0.083204C17.0058 0.135162 16.724 0.280818 16.505 0.500001L7.04499 9.13L2.92499 6.002C2.73912 5.86101 2.50976 5.78953 2.27669 5.79994C2.04363 5.81035 1.82156 5.902 1.64899 6.059L0.326993 7.261C0.223973 7.35465 0.141644 7.46878 0.0852761 7.59608C0.0289081 7.72339 -0.00025659 7.86106 -0.000350724 8.00028C-0.000444857 8.1395 0.0285336 8.27721 0.0847294 8.40459C0.140925 8.53197 0.2231 8.64621 0.325993 8.74L3.89899 12L0.325993 15.26C0.2231 15.3538 0.140925 15.468 0.0847294 15.5954C0.0285336 15.7228 -0.000444857 15.8605 -0.000350724 15.9997C-0.00025659 16.1389 0.0289081 16.2766 0.0852761 16.4039C0.141644 16.5312 0.223973 16.6454 0.326993 16.739L1.64999 17.94C1.82256 18.097 2.04463 18.1887 2.27769 18.1991C2.51076 18.2095 2.74012 18.138 2.92599 17.997L7.04599 14.869L16.506 23.499C16.7248 23.7182 17.0064 23.8639 17.3117 23.9159C17.6171 23.9679 17.931 23.9235 18.21 23.789L23.152 21.412C23.4062 21.2893 23.6207 21.0973 23.7707 20.8581C23.9207 20.619 24.0002 20.3423 24 20.06V3.939C24 3.65647 23.9203 3.37967 23.7699 3.14048C23.6195 2.90129 23.4046 2.70943 23.15 2.587ZM18.004 17.448L10.826 12L18.004 6.552V17.448Z"
></path>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" height="30" width="24">
<path fill="white"
d="M23.15 2.587L18.21 0.210001C17.9308 0.075557 17.6167 0.031246 17.3113 0.083204C17.0058 0.135162 16.724 0.280818 16.505 0.500001L7.04499 9.13L2.92499 6.002C2.73912 5.86101 2.50976 5.78953 2.27669 5.79994C2.04363 5.81035 1.82156 5.902 1.64899 6.059L0.326993 7.261C0.223973 7.35465 0.141644 7.46878 0.0852761 7.59608C0.0289081 7.72339 -0.00025659 7.86106 -0.000350724 8.00028C-0.000444857 8.1395 0.0285336 8.27721 0.0847294 8.40459C0.140925 8.53197 0.2231 8.64621 0.325993 8.74L3.89899 12L0.325993 15.26C0.2231 15.3538 0.140925 15.468 0.0847294 15.5954C0.0285336 15.7228 -0.000444857 15.8605 -0.000350724 15.9997C-0.00025659 16.1389 0.0289081 16.2766 0.0852761 16.4039C0.141644 16.5312 0.223973 16.6454 0.326993 16.739L1.64999 17.94C1.82256 18.097 2.04463 18.1887 2.27769 18.1991C2.51076 18.2095 2.74012 18.138 2.92599 17.997L7.04599 14.869L16.506 23.499C16.7248 23.7182 17.0064 23.8639 17.3117 23.9159C17.6171 23.9679 17.931 23.9235 18.21 23.789L23.152 21.412C23.4062 21.2893 23.6207 21.0973 23.7707 20.8581C23.9207 20.619 24.0002 20.3423 24 20.06V3.939C24 3.65647 23.9203 3.37967 23.7699 3.14048C23.6195 2.90129 23.4046 2.70943 23.15 2.587ZM18.004 17.448L10.826 12L18.004 6.552V17.448Z">
</path>
</svg>
<p class="text">登录</p>
</button>
<!-- <el-button
class="button"
type="primary"
auto-insert-space
@click="login()"
>登录</el-button
> -->
</el-form-item>
</el-form>
</el-col>
@ -161,7 +130,6 @@ const login = async function () {
}
}
/* From Uiverse.io by kamehame-ha */
.button {
height: 50px;
display: flex;
@ -201,21 +169,6 @@ const login = async function () {
fill: #007acc;
}
/* .box {
padding: 20px;
border-radius: 10px;
background-color: #fff;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
} */
/* From Uiverse.io by marsella_3472 */
/*
More comprehensive version at shenanigans.shoghisimon.ca/collection/css
*/
/* From Uiverse.io by SelfMadeSystem */
.container {
width: 100%;
height: 100%;
@ -224,20 +177,4 @@ More comprehensive version at shenanigans.shoghisimon.ca/collection/css
linear-gradient(in oklch longer hue -2deg, #a00, #a00);
background-size: 100% 2px, 100% 100%, 100% 100%;
}
</style>
<!-- 这是补救
const run = () => {
const width = window.innerWidth;
const height = window.innerHeight;
const chartNode = document.querySelector("main");
drawChart.default(chartNode,data,width,height);
};
window.addEventListener("resize", run);
document.addEventListener("DOMContentLoaded", run);
</script>
</body>
</html>
-->
</style>

232
src/views/managerecharge/rate.vue

@ -70,7 +70,7 @@ const getYesterday = () => {
search()
}
// 7
// 7
const get7Days = () => {
const today = new Date()
const start = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 6, 0, 0, 0)
@ -156,7 +156,7 @@ const addRate = async function () {
})
if (result.code == 0) {
ElMessage.error(result.msg)
}else{
} else {
ElMessage({
type: 'success',
message: '新增汇率成功'
@ -407,7 +407,7 @@ const rules = reactive({
//
const handledelete = function () {
timeRange.value={}
timeRange.value = {}
getObj.value.pageNum = 1
}
//
@ -479,26 +479,17 @@ function handleInput(value) {
</script>
<template>
<!-- 这是主页面 -->
<el-row>
<el-col>
<el-card>
<!-- 这是时间 -->
<div class="demo-range">
<el-row>
<el-col :span="9">
<el-form-item>
<el-text class="mx-1" size="large">时间范围</el-text>
<el-date-picker
v-model="timeRange"
type="datetimerange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
style="width: 300px"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
/>
<el-date-picker v-model="timeRange" type="datetimerange" range-separator="" start-placeholder="开始日期"
end-placeholder="结束日期" style="width: 300px" format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss" />
</el-form-item>
</el-col>
<el-col :span="4">
@ -507,15 +498,8 @@ function handleInput(value) {
<el-button @click="get7Days">近7天</el-button>
</el-col>
<el-col :span="4">
<el-button
class="button-item"
type="success"
@click="handledelete()"
>重置</el-button>
<el-button
type="primary"
@click="search"
>查询</el-button>
<el-button class="button-item" type="success" @click="handledelete()">重置</el-button>
<el-button type="primary" @click="search">查询</el-button>
</el-col>
</el-row>
</div>
@ -526,28 +510,13 @@ function handleInput(value) {
<el-row>
<el-col>
<el-card class="box-card" style="max-width: 100%">
<!-- 添加 -->
<div class="add-item">
<el-button
style="color: #048efb; border: 1px solid #048efb"
@click="regeAdd = true"
>新增汇率</el-button
>
<el-button style="color: #048efb; border: 1px solid #048efb" @click="regeAdd = true">新增汇率</el-button>
</div>
<!-- 表格 -->
<div>
<el-table
:data="tableData"
v-if="(tableData.flag = 1)"
:height="tableHeight"
style="width: 100%"
>
<el-table-column
type="index"
label="序号"
width="100px"
fixed="left"
>
<el-table :data="tableData" v-if="(tableData.flag = 1)" :height="tableHeight" style="width: 100%">
<el-table-column type="index" label="序号" width="100px" fixed="left">
<template #default="scope">
<span>{{
scope.$index + 1 + (getObj.pageNum - 1) * getObj.pageSize
@ -568,62 +537,22 @@ function handleInput(value) {
<span>{{ formatDate(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column prop="adminName" label="提交人" :span="1" />
<el-table-column prop="status" label="状态">
<template #default="scope">
<span v-if="scope.row.status === 1">
<div class="status">
<span class="green-dot"></span>
<span>使用中</span>
</div>
</span>
<span v-if="scope.row.status === 0">
<div class="status">
<span class="red-dot"></span>
<span>未开始</span>
</div>
</span>
<span v-if="scope.row.status === 2">
<div class="status">
<span class="grey-dot"></span>
<span>已过期</span>
</div>
</span>
</template>
</el-table-column>
<el-table-column prop="startTime" label="持续时间" :span="10">
<template #default="scope">
<span>{{ formatDateTwe(scope.row.startTime) }}</span>
<span>---</span>
<span>{{ formatDateTwe(scope.row.endTime) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" :span="3">
<template #default="scope">
<el-button
type="text"
@click="
() => {
regeEdit = true
getEditData(scope.row)
}
"
>编辑</el-button
>
<el-popconfirm
title="确定将此条活动删除吗?"
@confirm="delConfirm"
>
<el-button type="text" @click="
() => {
regeEdit = true
getEditData(scope.row)
}
">编辑</el-button>
<el-popconfirm title="确定将此条活动删除吗?" @confirm="delConfirm">
<template #reference>
<el-button 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(scope.row)"
>
<el-button type="primary" size="small" @click="confirm(scope.row)">
确定
</el-button>
</template>
@ -634,58 +563,26 @@ function handleInput(value) {
</div>
<!-- 分页 -->
<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"
@current-change="handleCurrentChange"
></el-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"
@current-change="handleCurrentChange"></el-pagination>
</div>
</el-card>
</el-col>
</el-row>
<!-- 这是添加弹窗 -->
<el-dialog
v-model="regeAdd"
title="新增汇率"
width="500"
:close-on-click-modal="false"
>
<el-dialog v-model="regeAdd" title="新增汇率" width="500" :close-on-click-modal="false">
<template #footer>
<el-form
ref="Ref"
style="max-width: 600px"
:model="rateAdd"
:rules="rules"
label-width="auto"
class="demo-ruleForm"
:size="formSize"
status-icon
>
<el-form ref="Ref" style="max-width: 600px" :model="rateAdd" :rules="rules" label-width="auto"
class="demo-ruleForm" :size="formSize" status-icon>
<el-form-item prop="currency" label="货币名称:">
<el-select
v-model.number="rateAdd.currency"
placeholder="请选择"
style="width: 240px"
>
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
<el-select v-model.number="rateAdd.currency" placeholder="请选择" style="width: 240px">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item prop="exchangeRate" label="汇率:">
<el-input
v-model="rateAdd.exchangeRate"
@update:modelValue="handleInput"
style="width: 120px"
/>
<el-input v-model="rateAdd.exchangeRate" @update:modelValue="handleInput" style="width: 120px" />
<p class="unit">:1</p>
<p>
(提示当前规则每 {{ rateAdd.exchangeRate }}
@ -696,23 +593,12 @@ function handleInput(value) {
<el-input :value="adminData.name" disabled style="width: 240px" />
</el-form-item>
<el-form-item prop="startTime" label="开始时间:">
<el-date-picker
v-model="rateAdd.startTime"
type="date"
placeholder="请选择时间"
:default-value="new Date()"
@change="handleStartTimeChange"
value-format="YYYY-MM-DD"
/>
<el-date-picker v-model="rateAdd.startTime" type="date" placeholder="请选择时间" :default-value="new Date()"
@change="handleStartTimeChange" value-format="YYYY-MM-DD" />
</el-form-item>
<el-form-item prop="endTime" label="结束时间:">
<el-date-picker
v-model="rateAdd.endTime"
type="date"
placeholder="请选择时间"
:default-value="new Date()"
value-format="YYYY-MM-DD"
/>
<el-date-picker v-model="rateAdd.endTime" type="date" placeholder="请选择时间" :default-value="new Date()"
value-format="YYYY-MM-DD" />
</el-form-item>
<el-form-item>
<div class="dialog-footer">
@ -725,35 +611,13 @@ function handleInput(value) {
</el-dialog>
<!-- 这是编辑弹窗 -->
<el-dialog
v-model="regeEdit"
title="修改汇率"
width="500"
:close-on-click-modal="false"
>
<el-dialog v-model="regeEdit" title="修改汇率" width="500" :close-on-click-modal="false">
<template #footer>
<el-form
ref="ruleFormRef"
style="max-width: 600px"
:model="rateEdit"
:rules="rules"
label-width="auto"
class="demo-ruleForm"
:size="formSize"
status-icon
>
<el-form ref="ruleFormRef" style="max-width: 600px" :model="rateEdit" :rules="rules" label-width="auto"
class="demo-ruleForm" :size="formSize" status-icon>
<el-form-item label="货币名称:">
<el-select
v-model="rateEdit.currency"
placeholder="请选择"
style="width: 240px"
>
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
<el-select v-model="rateEdit.currency" placeholder="请选择" style="width: 240px">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="汇率:">
@ -768,22 +632,12 @@ function handleInput(value) {
<el-input disabled :value="adminData.name" style="width: 240px" />
</el-form-item>
<el-form-item label="开始时间:">
<el-date-picker
v-model="rateEdit.startTime"
type="date"
placeholder="请选择时间"
:default-value="new Date()"
value-format="YYYY-MM-DD"
/>
<el-date-picker v-model="rateEdit.startTime" type="date" placeholder="请选择时间" :default-value="new Date()"
value-format="YYYY-MM-DD" />
</el-form-item>
<el-form-item label="结束时间:">
<el-date-picker
v-model="rateEdit.endTime"
type="date"
placeholder="请选择时间"
:default-value="new Date()"
value-format="YYYY-MM-DD"
/>
<el-date-picker v-model="rateEdit.endTime" type="date" placeholder="请选择时间" :default-value="new Date()"
value-format="YYYY-MM-DD" />
</el-form-item>
<el-form-item>
<div class="dialog-footer">
@ -840,9 +694,11 @@ p {
.el-card {
padding: 0px;
}
.pagination {
display: flex;
}
.status {
display: flex;
}

702
src/views/recharge/coinRecharge.vue

@ -1,18 +1,14 @@
<script setup>
import { ref, onMounted, reactive, computed, watch, nextTick } from 'vue'
import ElementPlus from 'element-plus'
import { ElMessage,ElMessageBox } from 'element-plus'
import { AiFillRead } from 'vue-icons-plus/ai'
import { ElMessage } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'
import axios from 'axios'
import { ElMessageBox } from 'element-plus'
import API from '@/util/http'
import request from '@/util/http'
import moment from 'moment'
import { range, re } from 'mathjs'
import { utils, read } from 'xlsx'
import throttle from 'lodash/throttle'
//------------------------------------------------------------------------------
//
const trimJwCode = () => {
if (addRecharge.value.jwcode) {
@ -33,13 +29,11 @@ const beforeAvatarUpload = (file) => {
}
return (isJPG || isPNG) && isLt2M
}
const imageUrl = ref('')//url
const rechargeVoucher = ref('')//
const Rate = ref()//
//
const adminData = ref({})//
//
const imageUrl = ref('')
const rechargeVoucher = ref('')
const Rate = ref()
const adminData = ref({})
const getAdminData = async function () {
try {
const result = await API({
@ -49,8 +43,8 @@ const getAdminData = async function () {
adminData.value = result
addRecharge.value.adminId = adminData.value.adminId
addRecharge.value.area = adminData.value.area
console.log('管理员信息请求成功', result)
// console.log('', user.value),user.value
console.log('请求成功', result)
console.log('用户信息', user.value)
} catch (error) {
console.log('请求失败', error)
}
@ -80,7 +74,7 @@ const add = async function () {
return
}
//
console.log('/recharge/recharge/add请求成功', result)
console.log('请求成功', result)
//
ElMessage.success('添加成功')
//
@ -234,7 +228,7 @@ const getActivity = async function () {
})
//
console.log('请求成功activity', result)
console.log('请求成功', result)
//
activity.value = result.data
console.log('活动信息', activity.value)
@ -258,7 +252,7 @@ const getCurrency = async function () {
console.log('货币请求成功', result)
//
currency.value = result.data
console.log('currency', currency.value)
console.log('tableData', currency.value)
// UI
} catch (error) {
console.log('请求失败', error)
@ -356,7 +350,7 @@ const getJwcodeList = async function () {
jwcodeSet = new Set(jwcodeList.value)
console.log('精网号set', jwcodeSet)
} catch (error) {
console.log('请求失败jwcodelist', error)
console.log('请求失败', error)
//
}
}
@ -382,6 +376,7 @@ const validateInput = function (row, index) {
//
const batchRechargeVisible = ref(false)
const i = ref(1)
const delObj = ref({})
const batchDelObj = ref([])
const resetObj = ref({})
//
@ -858,360 +853,20 @@ const batchSettingConfirm = function () {
closeBatchSettingVisible()
}
//-------------------------------------------------------------------------------
//*
//
//
const tableData = ref([])
//=========================================
//recharge
const rechargeVo = ref({
adminId: adminData.value.adminId
})
//
const getObj = ref({
pageNum: 1,
pageSize: 50
})
//
const total = ref(100)
//
const getTime = ref([])
// *
//
const allData = ref([])
//
const area = ref([])
//
const activeName = ref('all')
//
const rechargeWay = [
{
value: '客户储值',
label: '客户储值'
},
{
value: '平台充值',
label: '平台充值'
}
]
//
const payWay = [
{
value: '现金',
label: '现金'
},
{
value: '支票',
label: '支票'
},
{
value: '刷卡',
label: '刷卡'
},
{
value: '其他(各地区电子支付)',
label: '其他(各地区电子支付)'
}
]
// ==========================================================
//
const delObj = ref({})
//
//
const trueGold = ref(0)
const trueRGold = ref(0)
const trueFGold = ref(0)
// ===========================================================================
//
const get = async function (val) {
try {
//
if (adminData.value.area === '泰国') {
rechargeVo.value.areas = ['泰国', '越南']
} else if (adminData.value.area !== '总部') {
rechargeVo.value.area = adminData.value.area
}
//
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]
}
} else {
rechargeVo.value.startDate = ''
rechargeVo.value.endDate = ''
}
//
rechargeVo.value.sortField = sortField.value
rechargeVo.value.sortOrder = sortOrder.value
console.log('搜索参数', getObj.value)
// POST
const result = await API({
url: '/recharge/recharge',
data: { ...getObj.value, rechargeVo: { ...rechargeVo.value } }
})
console.log('请求成功get',result)
//
trueGold.value = 0
trueRGold.value = 0
trueFGold.value = 0
if (result.data && result.data.list) {
result.data.list.forEach((item) => {
trueGold.value += item.paidGold || 0
trueRGold.value += item.paidGold || 0
trueFGold.value += item.freeGold || 0
})
}
//
console.log('请求成功', result)
//
tableData.value = result.data.list
console.log('tableData', tableData.value)
//
total.value = result.data.total
console.log('total', total.value)
} catch (error) {
console.log('请求失败get', error)
//
}
}
//
const search = function () {
getObj.value.pageNum = 1
get()
}
//
const reset = function () {
delete rechargeVo.value.jwcode
delete rechargeVo.value.activityId
delete rechargeVo.value.rechargeWay
delete rechargeVo.value.area
delete rechargeVo.value.startDate
delete rechargeVo.value.endDate
delete sortField.value
delete sortOrder.value
getTime.value = []
}
//
const sortField = ref('')
const sortOrder = ref('')
//
const handleSortChange = (column) => {
get()
console.log('排序字段:', column.prop)
console.log('排序方式:', column.order)
if (column.prop === 'paidGold') {
sortField.value = 'recharge_gold'
} else if (column.prop === 'freeGold') {
sortField.value = 'free_gold'
} else if (column.prop === 'rechargeTime') {
sortField.value = 'recharge_time'
} else if (column.prop === 'createTime') {
sortField.value = 'create_time'
}
sortOrder.value = column.order === 'ascending' ? 'ASC' : 'DESC'
console.log('传递给后端的排序字段:', sortField.value)
console.log('传递给后端的排序方式:', sortOrder.value)
get()
}
//
const getToday = function () {
const today = new Date()
const startDate = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate()
)
const endDate = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate() + 1
)
getTime.value = [startDate, endDate]
console.log('getTime', getTime.value)
get()
}
const handlePageSizeChange = function (val) {
getObj.value.pageSize = val
get()
}
const handleCurrentChange = function (val) {
getObj.value.pageNum = val
get()
}
//
const getYesterday = function () {
const yesterday = new Date()
yesterday.setDate(yesterday.getDate() - 1)
const startDate = new Date(
yesterday.getFullYear(),
yesterday.getMonth(),
yesterday.getDate()
)
const endDate = new Date(
yesterday.getFullYear(),
yesterday.getMonth(),
yesterday.getDate() + 1
)
getTime.value = [startDate, endDate]
console.log('getTime', getTime.value)
get()
}
// 7
const get7Days = function () {
const today = new Date()
const startDate = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate() - 6
)
const endDate = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate() + 1
)
getTime.value = [startDate, endDate]
console.log('getTime', getTime.value)
get()
}
//*
//
const getArea = async function () {
try {
const result = await request({
url: '/recharge/user/search',
data: {}
})
//
console.log('area请求成功',result)
//
area.value = result.data
console.log('area',area.value)
} catch (error) {
console.log('area请求失败',error)
ElMessage.error('获取地区数据失败')
}
}
// =================================
//
const del = function (row) {
delObj.value.rechargeId = row.rechargeId
console.log('delObj1', delObj.value)
}
//
const delConfirm = async function () {
try {
console.log('delObj2', delObj.value)
const result = await API({
url: '/recharge/recharge/edit',
data: delObj.value
})
console.log('删除成功', result)
//
get()
} catch (error) {
console.log('请求失败', error)
//
}
}
//
const checkNumber = function () {
if (typeof !isNaN(parseInt(getObj.value.pageNum)) === 'number') {
console.log('总共有多少页' + Math.ceil(total.value / getObj.value.pageSize))
if (
getObj.value.pageNum > 0 &&
getObj.value.pageNum <= Math.ceil(total.value / getObj.value.pageSize)
) {
getObj.value.pageNum = parseInt(getObj.value.pageNum)
console.log('输入的数字合法')
get()
} else {
//
ElMessage({
type: 'error',
message: '请检查输入内容'
})
}
} else {
//
ElMessage({
type: 'error',
message: '输入内容非数字'
})
}
}
//-------------------------------------------------------------------------
//
const activeTab = ref('addRecharge')
//
const changeTab = async (tabName) => {
activeTab.value = tabName
if(tabName === 'detail'){
//get
await get()
}
}
//
onMounted(async function () {
await getAdminData()
await getCurrency()
await getActivity()
await getArea()
await getJwcodeList()
//get
//await get()
})
</script>
<template>
<div>
<el-button-group>
<!-- 切换后状态显示样式否则是默认样式 -->
<el-button
:type="activeTab === 'addRecharge' ? 'primary' : 'default'"
@click="changeTab('addRecharge')"
>
新增充值
</el-button>
<el-button
:type="activeTab === 'detail' ? 'primary' : 'default'"
@click="changeTab('detail')"
>
金币充值明细
</el-button>
</el-button-group>
<!-- 根据activeTab切换显示内容 -->
<!-- 新增充值的布局------------------------------------------------------------------- -->
<div v-if="activeTab === 'addRecharge'">
<!-- <div style="display: flex">
<div style="display: flex">
<div style="margin-right: 20px">新增充值</div>
</div> -->
<!-- <el-button type="primary" plain @click="batchInit()">批量充值</el-button> -->
</div>
<el-form
:model="addRecharge"
@ -1301,7 +956,7 @@ onMounted(async function () {
style="margin-bottom: 5px"
>
<el-upload
action="http://39.101.133.168:8828/hljw/api/aws/upload"
action="http://54.251.137.151:10704/upload"
class="avatar-uploader"
:show-file-list="false"
:on-success="handleAvatarSuccess"
@ -1323,7 +978,7 @@ onMounted(async function () {
</el-icon>
</el-upload>
<p style="margin-left: 10px; color: rgb(177, 176, 176)">
仅支持.jpg .png格式文件2MB
仅支持.jpg .png格式文件1MB
</p>
</el-form-item>
<el-form-item prop="remark" label="备注">
@ -1352,7 +1007,7 @@ onMounted(async function () {
<!-- 客户信息栏 -->
<el-card
style="width: 1200px; float: right;margin-bottom:20px;margin-top: 10px;"
style="width: 1200px; float: right"
class="customer-info"
width="3000px"
>
@ -1633,7 +1288,7 @@ onMounted(async function () {
<el-table-column property="rechargeVoucher" label="充值凭证">
<template #default="scope">
<el-upload
action="http://39.101.133.168:8828/hljw/api/aws/upload"
action="http://54.251.137.151:10704/upload"
class="avatar-uploader"
:show-file-list="false"
:on-success="handleBatchAvatarSuccess"
@ -1798,7 +1453,7 @@ onMounted(async function () {
</el-form-item>
<el-form-item prop="rechargeVoucher" label="交款凭证">
<el-upload
action="http://39.101.133.168:8828/hljw/api/aws/upload"
action="http://54.251.137.151:10704/upload"
class="avatar-uploader"
:show-file-list="false"
:on-success="batchSettingHandleAvatarSuccess"
@ -1833,319 +1488,6 @@ onMounted(async function () {
>
<el-button type="primary" @click="batchSettingConfirm()"> 确认 </el-button>
</el-dialog>
</div>
<!-- 金币充值明细的布局---------------------------------------------------------- -->
<div v-else-if="activeTab === 'detail'">
<el-row>
<el-col>
<el-card style="margin-bottom: 20px;margin-top: 10px">
<el-row style="margin-bottom: 10px">
<el-col :span="5">
<div class="head-card-element">
<el-text class="mx-1" size="large">精网号</el-text>
<el-input v-model="rechargeVo.jwcode" placeholder="请输入精网号" style="width: 150px" clearable />
</div>
</el-col>
<el-col :span="6">
<div class="head-card-element">
<el-text class="mx-1" size="large">活动名称</el-text>
<el-select v-model="rechargeVo.activityId" placeholder="请选择活动名称" style="width: 180px"
clearable>
<el-option v-for="item in activity" :key="item.activityId" :label="item.activityName"
:value="item.activityId" />
</el-select>
</div>
</el-col>
<el-col :span="6">
<div class="head-card-element" v-if="adminData.area == '总部'">
<el-text class="mx-1" size="large">所属地区</el-text>
<el-select v-model="rechargeVo.area" placeholder="请选择所属地区" style="width: 180px" clearable>
<el-option v-for="item in area" :key="item" :label="item" :value="item" />
</el-select>
</div>
</el-col>
<el-col :span="6">
<div class="head-card-element">
<el-text class="mx-1" size="large">充值类型</el-text>
<el-select v-model="rechargeVo.rechargeWay" placeholder="请选择支付方式" style="width: 180px" clearable>
<el-option v-for="item in rechargeWay" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</div>
</el-col>
</el-row>
<el-row>
<el-col :span="21">
<div class="head-card-element">
<el-text class="mx-1" size="large">充值时间</el-text>
<el-date-picker
v-model="getTime"
type="datetimerange"
range-separator="至"
start-placeholder="起始时间"
end-placeholder="结束时间"
/>
<el-button style="margin-left: 10px" @click="getToday()"
></el-button
>
<el-button @click="getYesterday()"></el-button>
<el-button @click="get7Days()">近7天</el-button>
<!-- </div>
</el-col>
<el-col :span="3">
<div class="head-card-btn"> -->
<el-button type="success" @click="reset()">重置</el-button>
<el-button type="primary" @click="search()">查询</el-button>
<el-button type="primary" @click="exportExcel()">导出Excel</el-button>
</div>
</el-col>
</el-row>
</el-card>
</el-col>
</el-row>
<el-row>
<el-col>
<el-card>
<div>
充值金额{{ trueRGold.toFixed(2) }}新币永久金币{{
trueRGold.toFixed(2)
}}金币免费金币{{ trueFGold }}金币
</div>
<!-- 设置表格容器的高度和滚动样式 -->
<div style="height: 520px; overflow-y: auto;margin-top: 10px;">
<el-table
:data="tableData"
style="width: 100%"
height="520px"
@sort-change="handleSortChange"
>
<el-table-column
type="index"
label="序号"
width="80px"
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="80px"
/>
<el-table-column
fixed="left"
prop="jwcode"
label="精网号"
width="80px"
/>
<el-table-column prop="area" label="所属地区" width="100px" />
<el-table-column
prop="activityName"
label="活动名称"
width="100px"
/>
<el-table-column prop="" label="货币名称" width="110px" />
<el-table-column
prop="paidGold"
sortable="custom"
label="充值金额"
width="110px"
/>
<el-table-column
prop="paidGold"
label="永久金币"
sortable="custom"
width="110px"
/>
<el-table-column
prop="freeGold"
label="免费金币"
sortable="custom"
width="110px"
/>
<el-table-column
prop="rechargeWay"
label="充值方式"
width="100px"
/>
<el-table-column prop="payWay" label="支付方式" width="100px" />
<el-table-column
prop="remark"
label="备注"
width="150px"
show-overflow-tooltip
/>
<!-- <el-table-column
prop="rechargeVoucher"
label="支付凭证"
width="150px"
>
<template #default="scope">
<el-image
:preview-src-list="[scope.row.rechargeVoucher]"
preview-teleported="true"
:src="scope.row.rechargeVoucher"
alt="凭证"
style="width: 50px; height: 50px"
/>
</template>
</el-table-column> -->
<el-table-column prop="name" label="提交人" width="100px" />
<!-- <el-table-column prop="status" label="状态" width="100px">
<template #default="scope">
<span v-if="scope.row.status === 1">
<div class="status">
<span class="green-dot"></span>
<span>已通过</span>
</div>
</span>
<span v-if="scope.row.status === 0">
<div class="status">
<span class="grey-dot"></span>
<span>待审核</span>
</div>
</span>
<span v-if="scope.row.status === 2">
<div class="status">
<span class="red-dot"></span>
<span>已驳回</span>
</div>
</span>
</template>
</el-table-column>
<el-table-column
prop="reson"
label="驳回理由"
width="200px"
show-overflow-tooltip
/> -->
<el-table-column
prop="rechargeTime"
sortable
label="充值时间"
width="200px"
>
<template #default="scope">
{{
moment(scope.row.rechargeTime).format('YYYY-MM-DD HH:mm:ss')
}}
</template>
</el-table-column>
<!-- <el-table-column
prop="createTime"
sortable="custom"
label="提交时间"
width="200px"
/>
<el-table-column
fixed="right"
prop="operation"
label="操作"
width="150px"
>
<template #default="scope">
<el-popconfirm
title="确定将此条活动删除吗?"
@confirm="delConfirm"
>
<template #reference>
<el-button type="primary" text @click="del(scope.row)">
删除
</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>
</template>
</el-table-column> -->
</el-table>
</div>
<!-- 分页 -->
<div class="pagination" style="margin-top: 20px">
<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"
@current-change="handleCurrentChange"
></el-pagination>
</div>
</el-card>
</el-col>
</el-row>
<!-- 编辑弹窗 -->
<el-dialog
v-model="editRechargeVisible"
title="新增活动"
width="500"
:before-close="closeEditRechargeVisible"
>
<template #footer>
<el-form :model="editObj" label-width="auto" style="max-width: 600px">
<el-form-item label="活动名称:">
<el-input
v-model="addObj.activityName"
placeholder="请输入活动名称"
style="width: 220px"
/>
</el-form-item>
<el-form-item label="免费金币:">
<el-radio-group v-model="addObj.freeGold">
<el-radio value="0">无赠送</el-radio>
<el-radio value="1">有赠送</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="免费金币兑换比:">
<el-input
v-model="addObj.rechargeRatio"
placeholder="请输入"
style="width: 80px"
/>1
<div style="color: grey">(提示当前规则每10新币可兑换1免费金币)</div>
</el-form-item>
<el-form-item label="开始时间:">
<el-time-picker v-model="addObj.startTime" />
</el-form-item>
<el-form-item label="结束时间:">
<el-time-picker v-model="addObj.endTime" />
</el-form-item>
<el-form-item label="添加人:">
<el-input v-model="addObj.adminName" disabled style="width: 220px" />
</el-form-item>
</el-form>
<div class="dialog-footer">
<el-button @click="closeAddActivityVisible">取消</el-button>
<el-button type="primary" @click="closeAddActivityVisible">
提交
</el-button>
</div>
</template>
</el-dialog>
</div>
</div>
</template>
<style scoped>

2
src/views/refund/beanRefund.vue

@ -6,7 +6,7 @@ import { AiFillRead } from 'vue-icons-plus/ai'
import { ElMessage, ElMessageBox } from 'element-plus'
import axios from 'axios'
import moment from 'moment'
import API from '@/util/http'
//
//
const adminData = ref({})

797
src/views/refund/coinRefund.vue

@ -1,31 +1,28 @@
<script setup>
import { onMounted, reactive } from 'vue'
import { ref, computed, watch } from 'vue'
import { AiFillRead } from 'vue-icons-plus/ai'
import { ElMessage,ElRadioGroup, ElRadio, } from 'element-plus'
import { ElMessage } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'
import axios from 'axios'
import { ElMessageBox } from 'element-plus'
import API from '@/util/http'
import moment from 'moment'
// import _ from 'lodash'
//退---------------------------------------------------------------------------
const addRe = ref({
typeR: '0'
})
//退
//
const adminData = ref({})
const getAdminData = async function () {
try {
const result = await API({ url: '/admin/userinfo', data: {} })
adminData.value = result
addRefund.value.adminId = adminData.value.adminId
console.log('用户信息请求成功', user.value)
console.log('adminData信息', adminData.value)
console.log('请求成功', result)
console.log('用户信息', user.value)
} catch (error) {
console.log('用户信息请求失败', error)
console.log('请求失败', error)
}
}
//
@ -64,7 +61,7 @@ const add = async function () {
ElMessage.error(result.msg)
return
}
console.log('add请求成功', result)
console.log('请求成功', result)
ElMessage.success('添加成功')
//
addRefund.value = {}
@ -79,7 +76,7 @@ const add = async function () {
addRefund.value.typeR = 0
user.value = {}
} catch (error) {
console.log('添加退款请求失败', error)
console.log('请求失败', error)
//
}
}
@ -193,8 +190,9 @@ const getUser = async function (jwcode) {
//ElMessage.success(result.msg)
}
} catch (error) {
console.log('用户信息请求失败', error)
console.log('请求失败', error)
ElMessage.error('查询失败,请检查精网号是否正确')
//
}
}
const calculatedAllGold = computed(() => {
@ -224,7 +222,7 @@ const refundType = [
]
//
//
//
const goods = ref([])
const getGoods = async function (jwcode) {
trimJwCode();
@ -237,7 +235,7 @@ const getGoods = async function (jwcode) {
area: adminData.value.area
}
})
console.log('goods请求成功', result)
console.log('请求成功', result)
if (result.code === 0) {
ElMessage.error(result.msg)
@ -248,8 +246,8 @@ const getGoods = async function (jwcode) {
ElMessage.success(result.msg)
}
} catch (error) {
console.log('商品goods请求失败', error)
ElMessage.error('商品查询失败')
console.log('请求失败', error)
ElMessage.error('查询失败,请检查精网号是否正确')
//
}
}
@ -289,14 +287,14 @@ const getProductByOrderCode = async function (item) {
result.data.freeCoin * -1 +
result.data.rechargeCoin * -1) /
100
console.log('addRefund请求成功', addRefund.value)
console.log('请求成功', addRefund.value)
if (result.data.code === 0) {
ElMessage.error(result.data.msg)
} else {
ElMessage.success('选择成功')
}
} catch (error) {
console.log('精网号查询请求失败', error)
console.log('请求失败', error)
ElMessage.error('查询失败,请检查精网号是否正确')
//
}
@ -306,456 +304,14 @@ const handleSelectionChange = (value) => {
console.log('选择的订单号', value)
const selectedItem = goods.value.find((item) => item.detailId === value)
}
// 退----------------------------------------------------------------------
//
const tableData = ref([])
//==================================
//detail
const detail = ref([])
//
const getObj = ref({
pageNum: 1,
pageSize: 50
})
//
const total = ref(100)
//
const getTime = ref([])
//
const allData = ref([])
//
const area = ref([])
//
const activeName = ref('all')
//退
const consumeType = [
{
value:"退款商品",
label:"退款商品"
}
]
//
//
const trueGold = ref(0)
const truePgold = ref(0)
const trueFgold = ref(0)
const trueTgold = ref(0)
//
const pendingPgold = ref(0)
const pendingFgold = ref(0)
const pendingTgold = ref(0)
//
const pendingGold = ref(0)
//
const approvedPgold = ref(0)
const approvedFgold = ref(0)
const approvedTgold = ref(0)
//
const approvedGold = ref(0)
//
const rejectedPgold = ref(0)
const rejectedFgold = ref(0)
const rejectedTgold = ref(0)
//
const rejectedGold = ref(0)
// ==============================================================
//
const get = async function (val) {
try {
//
if (adminData.value.area === '泰国') {
detail.value.areas = ['泰国', '越南']
} else if (adminData.value.area !== '总部') {
detail.value.area = adminData.value.area
}
//
if (typeof val === 'number') {
getObj.value.pageNum = val
}
//
if (getTime.value != null) {
if (getTime.value.startDate != '' && getTime.value.endDate != '') {
detail.value.startDate = getTime.value[0]
detail.value.endDate = getTime.value[1]
}
} else {
detail.value.startDate = ''
detail.value.endDate = ''
}
//
detail.value.sortField = sortField.value
detail.value.sortOrder = sortOrder.value
console.log('搜索参数', getObj.value)
// POST
const result = await API({
url: '/refund/search',
data: {
...getObj.value,
detail: { ...detail.value }
}
})
// detail.value 使
const detailWithoutSort = { ...detail.value }
delete detailWithoutSort.sortField
delete detailWithoutSort.sortOrder
const result2 = await API({
url: '/refund/RefundA',
data: {
...detailWithoutSort
}
})
//
if (result2.data) {
result2.data.forEach((item) => {
switch (item.status) {
case '待审核':
// item.raudit 0
pendingPgold.value = item.sumRaudit1 || 0
pendingFgold.value = item.sumRaudit2 || 0
pendingTgold.value = item.sumRaudit3 || 0
// item.sumRaudit 0
pendingGold.value = item.sumRaudit || 0
break
case '已通过':
approvedPgold.value = item.sumRaudit1 || 0
approvedFgold.value = item.sumRaudit2 || 0
approvedTgold.value = item.sumRaudit3 || 0
approvedGold.value = item.sumRaudit || 0
break
case '已驳回':
rejectedPgold.value = item.sumRaudit1 || 0
rejectedFgold.value = item.sumRaudit2 || 0
rejectedTgold.value = item.sumRaudit3 || 0
rejectedGold.value = item.sumRaudit || 0
break
}
})
}
trueFgold.value =
pendingFgold.value + approvedFgold.value + rejectedFgold.value
truePgold.value =
pendingPgold.value + approvedPgold.value + rejectedPgold.value
trueTgold.value =
pendingTgold.value + approvedTgold.value + rejectedTgold.value
trueGold.value = pendingGold.value + approvedGold.value + rejectedGold.value
//
//console.log('', result)
//
tableData.value = result.data.list
console.log('tableData请求成功', tableData.value)
//
total.value = result.data.total
console.log('total', total.value)
//
handleClick()
} catch (error) {
console.log('表格数据请求失败', error)
}
}
//
//1
const search = function () {
getObj.value.pageNum = 1
get()
}
//
const reset = function () {
detail.value.jwcode = ''
detail.value.refundGoods = ''
detail.value.refundType = ''
detail.value.area = ''
detail.value.startDate = ''
detail.value.endDate = ''
sortField.value = ''
sortOrder.value = ''
getTime.value = {}
}
//
const getToday = function (){
const today = new Date()
const startDate = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate()
)
const endDate = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate() + 1
)
getTime.value = [startDate, endDate]
console.log('今天', getTime.value)
get()
}
//
const getYesterday = function (){
const yesterday = new Date()
yesterday.setDate(yesterday.getDate() - 1)
const startDate = new Date(
yesterday.getFullYear(),
yesterday.getMonth(),
yesterday.getDate()
)
const endDate = new Date(
yesterday.getFullYear(),
yesterday.getMonth(),
yesterday.getDate() + 1
)
getTime.value = [startDate, endDate]
console.log('昨天', getTime.value)
get()
}
//7
const get7Days = function (){
const today = new Date()
const startDate = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate() - 6
)
const endDate = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate() + 1
)
getTime.value = [startDate, endDate]
console.log('近7天', getTime.value)
get()
}
//
const adminAll = function () {
console.log('全部充值明细')
detail.value.status = ''
getObj.value.pageNum = 1
get()
//
trueFgold.value =
pendingFgold.value + approvedFgold.value + rejectedFgold.value
truePgold.value =
pendingPgold.value + approvedPgold.value + rejectedPgold.value
trueTgold.value =
pendingTgold.value + approvedTgold.value + rejectedTgold.value
trueGold.value =
pendingGold.value + approvedGold.value + rejectedGold.value
}
//asyncawait
// adminAll
//
const adminWait = async function () {
detail.value.status = 0
getObj.value.pageNum = 1
await get()
console.log('待审核充值明细')
trueFgold.value = pendingFgold.value
truePgold.value = pendingPgold.value
trueTgold.value = pendingTgold.value
trueGold.value = pendingGold.value
}
//
const adminPass = async function () {
detail.value.status = 1
getObj.value.pageNum = 1
await get()
console.log('已通过充值明细')
trueFgold.value = approvedFgold.value
truePgold.value = approvedPgold.value
trueTgold.value = approvedTgold.value
trueGold.value = approvedGold.value
}
//
const adminReject = async function () {
detail.value.status = 2
getObj.value.pageNum = 1
await get()
console.log('已驳回充值明细')
trueFgold.value = rejectedFgold.value
truePgold.value = rejectedPgold.value
trueTgold.value = rejectedTgold.value
trueGold.value = rejectedGold.value
}
//
// tab.props.nameall
const tabName = ref('all')
const handleClick = function (tab, event) {
if (tab.props.name === 'all') {
adminAll()
} else if (tab.props.name === 'wait') {
adminWait()
} else if (tab.props.name === 'pass') {
adminPass()
} else if (tab.props.name === 'reject') {
adminReject()
}
}
//
const getArea = async function () {
try {
const result = await API({url:'/recharge/user/search',data:{}})
//console.log('', result)
area.value = result.data
console.log('地区请求成功', area.value)
}catch (error) {
console.log('地区请求失败', error)
ElMessage.error('获取地区失败')
}
}
//id
const delObj = ref({})
const del = function (row) {
delObj.value.detailId = row.detailId
console.log('delObj', delObj.value)
}
//
const delConfirm = async function () {
try {
console.log('delObj', delObj.value)
// POST
const result = await API({
url: '/refund/softDelete?detailId=' + delObj.value.detailId,
data: {}
})
//
console.log('气泡弹窗请求成功', result)
get()
}catch(error){
console.log('删除的气泡弹窗请求失败', error)
ElMessage.error('删除失败')
}
}
//
const allGoods = ref([])
const getAllGoods = async function () {
try {
// POST
const result = await API({ url: '/product', data: {} })
//
console.log('allGoods请求成功', result)
//
goods.value = result.data
} catch (error) {
console.log('商品请求失败', error)
ElMessage.error('商品查询失败')
}
}
getAllGoods()
//
const checPagekNumber = function () {
if (typeof parseInt(getObj.value.pageNum) === 'number') {
console.log('总共有多少页' + Math.ceil(total.value / getObj.value.pageSize))
if (
getObj.value.pageNum > 0 &&
getObj.value.pageNum <= Math.ceil(total.value / getObj.value.pageSize)
) {
getObj.value.pageNum = parseInt(getObj.value.pageNum)
console.log('输入的数字合法')
get()
} else {
//
ElMessage({
type: 'error',
message: '请检查输入内容'
})
}
} else {
//
ElMessage({
type: 'error',
message: '非数字输入内容'
})
}
}
//
const sortField = ref('')
const sortOrder = ref('')
//
const handleSortChange = (column) => {
console.log('column',column.prop)
console.log('column',column.order)
if(column.prop === 'rechargeCoin'){
sortField.value = 'recharge_coin'
} else if(column.prop === 'taskCoin'){
sortField.value = 'task_coin'
}else if(column.prop === 'freeCoin'){
sortField.value = 'free_coin'
}else if(column.prop === 'createTime'){
sortField.value = 'create_time'
}
sortOrder.value = column.order === 'ascending' ? 'asc' : 'desc'
get()
}
const handlePageSizeChange = function (val){
getObj.value.pageSize = val
get()
}
const handleCurrentChange = function (val){
getObj.value.pageNum = val
get()
}
//Excel
const exportExcel = function () {
window.open('/refund/exportExcel?detail=' + JSON.stringify(detail.value))
}
//退---------------------------------------------------------------
//
const activeTab = ref('addRefund')
//
const changeTab = async (tabName) => {
activeTab.value = tabName
//detailget
if (activeTab.value === 'detail') {
await get()
}
}
//
onMounted(async function () {
await getAdminData()
await getArea()
//await get()
})
</script>
<template>
<div>
<el-button-group>
<!-- 切换后状态显示样式否则是默认样式 -->
<el-button
:type="activeTab === 'addRefund' ? 'primary' : 'default'"
@click="changeTab('addRefund')"
>
新增退款
</el-button>
<el-button
:type="activeTab === 'detail' ? 'primary' : 'default'"
@click="changeTab('detail')"
>
金币退款明细
</el-button>
</el-button-group>
<!-- 根据activeTab切换显示内容 -->
<!-- 新增退款的布局---------------------------------------------------------- -->
<div v-if="activeTab === 'addRefund'">
<!-- <div style="font-weight: bold">新增退款</div> -->
<div style="font-weight: bold">新增退款</div>
<el-form
:model="addRefund"
@ -932,7 +488,11 @@ onMounted(async function () {
<p style="color: #2fa1ff">{{ user.rechargeTimes }}</p>
</el-form-item>
</el-col>
<!-- <el-col :span="10">
<el-form-item label="负责客服">
<p>{{ adminData.name }}</p>
</el-form-item>
</el-col> -->
<el-col :span="10">
<el-form-item label="消费次数">
<p style="color: #2fa1ff">{{ user.spendTimes }}</p>
@ -943,318 +503,19 @@ onMounted(async function () {
<p>{{ adminData.area }}</p>
</el-form-item>
</el-col>
<el-col :span="14">
<!-- <el-form-item label="待审核">
<p style="color: #2fa1ff">
{{ user.A }}
</p>
</el-form-item> -->
</el-col>
</el-row>
</el-form>
</el-card>
</div>
<!-- 金币退款明细的布局---------------------------------------------------------- -->
<div v-else-if="activeTab === 'detail'">
<el-row>
<el-col>
<el-card style="margin-bottom: 20px;margin-top:10px">
<el-row style="margin-bottom: 10px">
<el-col :span="5">
<div class="head-card-element">
<el-text class="mx-1" size="large">精网号</el-text>
<el-input
v-model="detail.jwcode"
placeholder="请输入精网号"
size="large"
style="width: 150px"
clearable
/>
</div>
</el-col>
<el-col :span="6">
<div class="head-card-element">
<el-text class="mx-1" size="large">退款类型</el-text>
<el-select
v-model="detail.refundType"
placeholder="请选择退款类型"
size="large"
style="width: 180px"
clearable
>
<el-option
v-for="item in consumeType"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
</el-col>
<el-col :span="6">
<div class="head-card-element">
<el-text class="mx-1" size="large">退款商品</el-text>
<el-select
v-model="detail.refundGoods"
placeholder="请选择退款商品"
size="large"
style="width: 180px"
clearable
>
<el-option
v-for="item in goods"
:key="item.value"
:label="item.name"
:value="item.name"
/>
</el-select>
</div>
</el-col>
<el-col :span="6">
<div class="head-card-element" v-if="adminData.area == '总部'">
<el-text class="mx-1" size="large">所属地区</el-text>
<el-select
v-model="detail.area"
placeholder="请选择所属地区"
size="large"
style="width: 180px"
clearable
>
<el-option
v-for="item in area"
:key="item"
:label="item"
:value="item"
/>
</el-select>
</div>
</el-col>
</el-row>
<el-row>
<el-col :span="21">
<div class="head-card-element">
<el-text class="mx-1" size="large">退款时间</el-text>
<el-date-picker
v-model="getTime"
type="datetimerange"
range-separator="至"
start-placeholder="起始时间"
end-placeholder="结束时间"
/>
<el-button style="margin-left: 10px" @click="getToday()"
></el-button
>
<el-button @click="getYesterday()"></el-button>
<el-button @click="get7Days()">近7天</el-button>
<el-button type="success" @click="reset()">重置</el-button>
<el-button type="primary" @click="search()">查询</el-button>
<el-button type="primary" @click="exportExcel">导出Excel</el-button>
</div>
</el-col>
</el-row>
</el-card>
</el-col>
</el-row>
<el-row>
<el-col>
<el-card>
<!-- <el-tabs
v-model="activeName"
type="card"
class="demo-tabs"
@tab-click="handleClick"
>
<el-tab-pane label="全部" name="all"></el-tab-pane>
<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>
退款金币总数{{ Math.abs(trueGold) }}永久金币{{
Math.abs(truePgold)
}}免费金币{{ Math.abs(trueFgold) }}任务金币{{
Math.abs(trueTgold)
}}
</div>
<!-- 设置表格容器的高度和滚动样式 -->
<div style="height: 520px; overflow-y: auto;margin-top:10px">
<el-table
:data="tableData"
style="width: 100%"
@sort-change="handleSortChange"
height="520px"
>
<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
prop="username"
label="姓名"
fixed="left"
width="100px"
/>
<el-table-column
prop="jwcode"
label="精网号"
fixed="left"
width="110px"
/>
<el-table-column prop="area" label="所属地区" width="110px" />
<el-table-column prop="refundGoods" label="商品名称" width="100px" />
<el-table-column prop="refundType" label="退款类型" width="100px" />
<el-table-column label="退款金币总数" width="110px">
<template #default="scope">
{{
scope.row.rechargeCoin +
scope.row.freeCoin +
scope.row.taskCoin
}}
</template>
</el-table-column>
<el-table-column prop="typeR" label="退款方式" width="110px"/>
<el-table-column
prop="rechargeCoin"
label="永久金币"
width="110px"
sortable="“custom”"
/>
<el-table-column
prop="freeCoin"
sortable="“custom”"
label="免费金币"
width="110px"
/>
<el-table-column
prop="taskCoin"
sortable="“custom”"
label="任务金币"
width="110px"
/>
<!-- 修改prop为taskGold -->
<el-table-column
prop="remark"
label="退款原因"
width="160px"
show-overflow-tooltip
/>
<el-table-column prop="adminName" label="提交人" width="100px" />
<!-- <el-table-column prop="status" label="审核状态" width="120px">
<template #default="scope">
<span v-if="scope.row.status == 1">
<div class="status">
<span class="green-dot"></span>
<span>已通过</span>
</div>
</span>
<span v-if="scope.row.status == 0">
<div class="status">
<span class="grey-dot"></span>
<span>待审核</span>
</div>
</span>
<span v-if="scope.row.status == 2">
<div class="status">
<span class="red-dot"></span>
<span>已驳回</span>
</div>
</span>
</template>
</el-table-column>
<el-table-column
prop="reson"
label="驳回理由"
width="200px"
show-overflow-tooltip
/> -->
<el-table-column
prop="createTime"
sortable="“custom”"
label="提交时间"
width="180px"
>
<template #default="scope">
{{ moment(scope.row.createTime).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
<!-- <el-table-column
prop="operation"
label="操作"
fixed="right"
width="120px"
>
<template #default="scope">
<el-popconfirm
title="确定将此条活动删除吗?"
@confirm="delConfirm"
>
<template #reference>
<el-button type="primary" text @click="del(scope.row)">
删除
</el-button>
</template>
<template #actions="{ delConfirm, cancel }">
<el-button size="small" @click="cancel">取消</el-button>
<el-button type="primary" size="small" @click="delConfirm">
确定
</el-button>
</template>
</el-popconfirm>
</template>
</el-table-column> -->
</el-table>
</div>
<!-- 分页 -->
<div class="pagination" style="margin-top: 20px">
<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"
@current-change="handleCurrentChange"
@jump="checkPageNumber"
></el-pagination>
</div>
</el-card>
</el-col>
</el-row>
</div>
</div>
</template>
<style scoped>
.status {
display: flex;
}
.head-card {
display: flex;
}
.head-card-element {
margin-right: 10px;
}
.head-card-btn {
margin-left: auto;
}
.pagination {
display: flex;
margin-top: 20px;
}
p {
margin: 0px;
}

798
src/views/usergold/index.vue

@ -0,0 +1,798 @@
<!-- 这是客户金币明细页面 -->
<script setup>
import { ref, onMounted, computed ,nextTick} from 'vue'
import { ElMessage } from 'element-plus'
import axios from 'axios'
import moment from 'moment'
import API from '@/util/http'
import { writeFile, utils } from 'xlsx'
//
const adminData = ref({})
const getAdminData = async function () {
try {
const result = await API({
url: '/admin/userinfo',
method: 'post',
data: {}
})
adminData.value = result
console.log('请求成功', result)
console.log('用户信息', adminData.value)
} catch (error) {
console.log('请求失败', error)
}
}
//
const isLoadingArea = ref(false);
const area = ref([])
const getArea = async () => {
isLoadingArea.value = true;
try {
const result = await API({
url: '/detailY/getarea'
});
// { value, label }
if (Array.isArray(result.data) && typeof result.data[0] === 'string') {
area.value = result.data.map(item => ({ value: item, label: item }));
} else {
area.value = result.data;
}
} catch (error) {
console.error('获取地区数据失败:', error);
ElMessage.error('获取地区数据失败,请稍后重试');
//
area.value = [];
} finally {
isLoadingArea.value = false;
}
};
//
const tableData = ref([])
//
const rechargeCoin = ref(0)
const freeCoin = ref(0)
const taskCoin = ref(0)
// ===========================================
//
const total = ref(100)
//
const getTime = ref([])
// detailY
const detailY = ref({})
//
const getObj = ref({
pageNum: 1,
pageSize: 50
})
// excel
const getPutEX = ref(false)
//
const num = [
{
value: '1',
label: '增加'
},
{
value: '2',
label: '减少'
}
]
//
// ===========================================================================
//
const get = async function (val) {
try {
//
if (adminData.value.area === '泰国') {
detailY.value.areas = ['泰国', '越南']
} else if (adminData.value.area !== '总部') {
detailY.value.area = adminData.value.area
}
//
if (typeof val === 'number') {
getObj.value.pageNum = val
}
if (getTime.value.length === 2) {
detailY.value.startDate = getTime.value[0]
detailY.value.endDate = getTime.value[1]
} else {
detailY.value.startDate = ''
detailY.value.endDate = ''
}
//
detailY.value.sortField = sortField.value
detailY.value.sortOrder = sortOrder.value
console.log('搜索参数', getObj.value)
// POST
const result = await API({
url: '/detailY',
method: 'post',
data: { ...getObj.value, detailY: { ...detailY.value } }
})
tableData.value = result.data.list
total.value = result.data.total
} catch (error) {
console.log('请求失败', error)
}
}
// detailY jwcode
const trimJwCode = () => {
if (detailY.value.jwcode) {
detailY.value.jwcode = detailY.value.jwcode.replace(/\s/g, '');
}
}
//
const search = function () {
trimJwCode();
getObj.value.pageNum = 1
get()
}
//
const reset = function () {
delete detailY.value.jwcode
delete detailY.value.num
delete detailY.value.startDate
delete detailY.value.endDate
delete detailY.value.area
delete sortField.value
delete sortOrder.value
getTime.value = []
delete detailY.value.consumePlatform
}
//
const getToday = function () {
const today = moment()
const startDate = today.startOf('day').toDate()
const endDate = today.add(1, 'days').startOf('day').toDate()
getTime.value = [startDate, endDate]
search()
}
//
const getYesterday = function () {
const today = moment()
const yesterday = moment().subtract(1, 'day')
const startDate = yesterday.startOf('day').toDate()
const endDate = today.startOf('day').toDate()
getTime.value = [startDate, endDate]
search()
}
// 7
const get7Days = function () {
const startDate = moment().subtract(6, 'day').startOf('day').toDate()
const endDate = moment().add(1,'days').startOf('day').toDate()
getTime.value = [startDate, endDate]
search()
}
//
const checkNumber = function () {
if (typeof parseInt(getObj.value.pageNum) === 'number') {
console.log('总共有多少页' + Math.ceil(total.value / getObj.value.pageSize))
if (
getObj.value.pageNum > 0 &&
getObj.value.pageNum <= Math.ceil(total.value / getObj.value.pageSize)
) {
getObj.value.pageNum = parseInt(getObj.value.pageNum)
console.log('输入的数字合法')
get()
} else {
//
ElMessage({
type: 'error',
message: '请检查输入内容'
})
}
} else {
//
ElMessage({
type: 'error',
message: '请检查输入内容'
})
}
}
//
onMounted(async function () {
await getArea()
await getAdminData()
await get()
})
// Excel
const headers = [
'序号',
'姓名',
'精网号',
'所属地区',
'平台信息',
'更新数量',
'更新类型',
'永久金币',
'免费金币',
'任务金币',
'提交人',
'更新时间'
]
const showExportInfoPanel = ref(false)
//
const exportExcel = async () => {
try {
console.log('点击导出按钮,尝试显示信息面板');
showExportInfoPanel.value = true;
await nextTick();//
} catch (error) {
console.error('显示信息面板失败:', error);
ElMessage.error('显示信息面板失败,请稍后重试');
}
};
//
const exportProgress = ref(0)
const isExporting = ref(false)
const exportCancelToken = ref(null)
//
const doExportExcel = async () => {
try {
isExporting.value = true
exportProgress.value = 0
showExportInfoPanel.value = false
// Excel
const wb = utils.book_new()
const ws = utils.aoa_to_sheet([headers])
utils.book_append_sheet(wb, ws, 'Sheet1')
//
const writer = {
write: (d, o) => {
if (!d) return
utils.sheet_add_aoa(ws, d, { origin: -1 })
}
}
let page = 1
let totalExported = 0
const pageSize = 5000 // 5000
let totalRecords = 0
//
const firstResult = await API({
url: '/detailY',
method: 'post',
data: {
pageNum: 1,
pageSize,
detailY: { ...detailY.value }
}
})
totalRecords = firstResult.data.total
//
const CancelToken = axios.CancelToken
exportCancelToken.value = CancelToken.source()
//
const platformMap = {
0: '初始化金币',
1: 'ERP系统',
2: 'Homily Chart',
3: 'Homily Link',
4: '金币系统'
};
//
const updateTypeMap = {
0: '充值',
1: '消费',
2: '退款',
3: '其他'
};
//
const firstData = firstResult.data.list
if (firstData.length) {
const rows = firstData.map((row, index) => {
const consumePlatform = parseInt(row.consumePlatform, 10); //
const platformInfo = platformMap[consumePlatform] || '';
return [
totalExported + index + 1,
row.username || '',
row.jwcode || '',
row.area || '',
platformInfo,
(row.gold / 100).toFixed(2) || '0.00',
updateTypeMap[row.updateType] || '',
(row.rechargeCoin / 100).toFixed(2) || '0.00',
(row.freeCoin / 100).toFixed(2) || '0.00',
(row.taskCoin / 100).toFixed(2) || '0.00',
row.name || '',
moment(row.createTime).format('YYYY-MM-DD HH:mm:ss') || ''
]
})
writer.write(rows)
totalExported += firstData.length
exportProgress.value = Math.round((totalExported / totalRecords) * 100)
page++
}
while (totalExported < totalRecords) {
const result = await API({
url: '/detailY',
method: 'post',
data: {
pageNum: page,
pageSize,
detailY: { ...detailY.value }
},
cancelToken: exportCancelToken.value.token
})
const data = result.data.list
if (!data.length) break
//
const rows = data.map((row, index) => [
totalExported + index + 1,
row.username || '',
row.jwcode || '',
row.area || '',
platformMap[row.consumePlatform] || '',
(row.gold / 100).toFixed(2) || '0.00',
updateTypeMap[row.updateType] || '',
(row.rechargeCoin / 100).toFixed(2) || '0.00',
(row.freeCoin / 100).toFixed(2) || '0.00',
(row.taskCoin / 100).toFixed(2) || '0.00',
row.name || '',
moment(row.createTime).format('YYYY-MM-DD HH:mm:ss') || ''
])
//
writer.write(rows)
totalExported += data.length
exportProgress.value = Math.round((totalExported / totalRecords) * 100)
// 500
if (page % 500 === 0) {
await new Promise(resolve => setTimeout(resolve, 0))
}
page++
}
//
writeFile(wb, '客户金币明细.xlsx')
ElMessage.success(`导出成功,共${totalExported}条数据`)
} catch (error) {
if (!axios.isCancel(error)) {
ElMessage.error(`导出失败: ${error.message}`)
}
} finally {
isExporting.value = false
exportCancelToken.value = null
}
}
//
const cancelExport = () => {
if (exportCancelToken.value) {
exportCancelToken.value.cancel('用户取消导出')
ElMessage.warning('导出已取消')
isExporting.value = false
}
}
const putExcel = ref({
startDate: new Date(),
endDate: new Date(new Date().setDate(new Date().getDate() + 1))
})
//
const checkJwCode = async (jwcode) => {
try {
const result = await API({
url: '/recharge/user',
method: 'post',
data: {
jwcode,
area: adminData.value.area
}
})
// code
return result.code !== 0
} catch (error) {
console.log('校验精网号失败', error)
return false
}
}
//
const platform = [
{
value: '4',
label: '金币系统'
},
{
value: '1',
label: 'ERP系统'
},
{
value: '2',
label: 'Homily Chart'
},
{
value: '3',
label: 'Homily Link'
},
{
value: '0',
label: '初始化金币'
}
]
//
const sortField = ref('')
const sortOrder = ref('')
//
const handleSortChange = (column) => {
if (column.prop === 'rechargeCoin') {
sortField.value = 'recharge_coin'
} else if (column.prop === 'taskCoin') {
sortField.value = 'task_coin'
} else if (column.prop === 'freeCoin') {
sortField.value = 'free_coin'
} else if (column.prop === 'createTime') {
sortField.value = 'create_time'
} else if (column.prop === 'gold') {
sortField.value = 'gold'
}
sortOrder.value = column.order === 'ascending' ? 'ASC' : 'DESC'
//gethandleSortChange
get()
}
const handlePageSizeChange = function (val) {
getObj.value.pageSize = val
get()
}
const handleCurrentChange = function (val) {
getObj.value.pageNum = val
get()
}
</script>
<template>
<!-- 导出excel提前展示的信息面板 -->
<el-dialog
v-model="showExportInfoPanel"
title="导出信息确认"
width="400px"
:close-on-click-modal="false"
>
<div class="info-panel-header">导出信息</div>
<!-- 直接使用 detailY 显示信息添加可选链操作符 -->
<!-- detailY是一个ref所以在模板中应该直接使用detailY.consumePlatform
而不是detailY.value.consumePlatform
因为在模板中ref变量会自动解包不需要.value
例如在代码中我们可能错误地在模板中使用了detailY.value但实际上应该直接使用detailY -->
<div v-if="!detailY.jwcode && !detailY.consumePlatform && !detailY.num && !detailY.area && (getTime.length < 2)">
你正在导出所有数据
</div>
<div v-else>
你正在导出以下数据
</div>
<div v-if="detailY.jwcode">精网号{{ detailY.jwcode || '' }}</div>
<div v-if="detailY.consumePlatform">平台信息{{ detailY.consumePlatform ? (platform.find(item => item.value === detailY.consumePlatform)?.label) : '' }}</div>
<div v-if="detailY.num">数量更新类型{{ detailY.num ? (num.find(item => item.value === detailY.num)?.label || '') : '' }}</div>
<div v-if="detailY.area">所属地区{{ detailY.area || '' }}</div>
<div v-if="Array.isArray(getTime) && getTime.length >= 2">
<span>更新时间</span>
<!-- 修改时间格式为精确到秒 -->
<span v-if="Array.isArray(getTime) && getTime.length >= 2">
{{ moment(getTime[0]).format('YYYY-MM-DD HH:mm:ss') }} {{ moment(getTime[1]).format('YYYY-MM-DD HH:mm:ss') }}
</span>
<span v-else></span>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="showExportInfoPanel = false">取消</el-button>
<el-button type="primary" @click="doExportExcel">导出</el-button>
</span>
</template>
</el-dialog>
<!-- 导出进度弹窗 -->
<el-dialog
v-model="isExporting"
title="正在导出"
width="400px"
:close-on-click-modal="false"
:show-close="false"
>
<el-progress
:percentage="exportProgress"
:stroke-width="15"
striped
animated
/>
<div class="export-status">
已导出 {{ Math.round((exportProgress / 100) * total) }} / {{ total }}
</div>
<template #footer>
<el-button type="danger" @click="cancelExport">取消导出</el-button>
</template>
</el-dialog>
<el-row>
<el-col>
<el-card style="margin-bottom: 20px">
<el-row style="margin-bottom: 10px">
<el-col :span="6">
<div class="head-card-element">
<el-text class="mx-1" size="large">精网号</el-text>
<el-input
v-model="detailY.jwcode"
style="width: 240px"
placeholder="请输入精网号"
clearable
/>
</div>
</el-col>
<el-col :span="6">
<div class="head-card-element">
<el-text class="mx-1" size="large">平台信息</el-text>
<el-select
v-model="detailY.consumePlatform"
placeholder="请选择平台信息"
style="width: 200px"
clearable
>
<el-option
v-for="item in platform"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
</el-col>
<el-col :span="6">
<div class="head-card-element">
<el-text class="mx-1" size="large">数量更新类型</el-text>
<el-select
v-model="detailY.num"
placeholder="请选择更新类型"
style="width: 200px"
clearable
>
<el-option
v-for="item in num"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
</el-col>
<el-col :span="6">
<div class="head-card-element">
<el-text class="mx-1" size="large">所属地区</el-text>
<el-select
v-model="detailY.area"
placeholder="请选择所属地区"
style="width: 240px"
clearable
:loading="isLoadingArea"
>
<el-option
v-for="item in area"
:key="item.value || item"
:label="item.label || item"
:value="item.value || item"
/>
</el-select>
</div>
</el-col>
</el-row>
<div class="head-card-element">
<el-text class="mx-1" size="large">更新时间</el-text>
<el-date-picker
v-model="getTime"
type="datetimerange"
range-separator="至"
start-placeholder="起始时间"
end-placeholder="结束时间"
style="margin-right: 50px"
/>
<el-button @click="getToday()"></el-button>
<el-button @click="getYesterday()"></el-button>
<el-button @click="get7Days()">近7天</el-button>
<el-button type="success" @click="exportExcel">导出Excel表格</el-button>
<el-button type="success" @click="reset()">重置</el-button>
<el-button type="primary" @click="search()">查询</el-button>
</div>
</el-card>
</el-col>
</el-row>
<el-row>
<el-col>
<el-card>
<div style="height: 584px; overflow-y: auto">
<el-table
:data="tableData"
style="width: 100%"
@sort-change="handleSortChange"
height="584px"
>
<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="150"
/>
<el-table-column
fixed="left"
prop="jwcode"
label="精网号"
width="120"
/>
<el-table-column prop="area" label="所属地区" width="120" />
<el-table-column
prop="consumePlatform"
label="平台信息"
width="140"
>
<template #default="scope">
<!-- 使用非严格相等比较 -->
<span v-if="scope.row.consumePlatform == 0">初始化金币</span>
<span v-if="scope.row.consumePlatform == 1">ERP系统</span>
<span v-if="scope.row.consumePlatform == 3">Homily Link</span>
<span v-if="scope.row.consumePlatform == 2">Homily Chart</span>
<span v-if="scope.row.consumePlatform == 4">金币系统</span>
</template>
</el-table-column>
<el-table-column
prop="gold"
label="更新数量"
width="120"
sortable="custom"
>
<template #default="scope">
<span>{{ scope.row.gold / 100 }}</span>
</template>
</el-table-column>
<el-table-column prop="updateType" label="更新类型" width="110">
<!-- 模板内容 -->
<template #default="scope">
<span v-if="scope.row.updateType == 1">消费</span>
<span v-if="scope.row.updateType == 0">充值</span>
<span v-if="scope.row.updateType == 2">退款</span>
<span v-if="scope.row.updateType == 3">其他</span>
</template>
</el-table-column>
<el-table-column
prop="rechargeCoin"
sortable="custom"
label="永久金币"
width="110"
>
<template #default="scope">
<span>{{ scope.row.rechargeCoin / 100 }}</span>
</template>
</el-table-column>
<el-table-column
prop="freeCoin"
sortable="custom"
label="免费金币"
width="110"
>
<template #default="scope">
<span>{{ scope.row.freeCoin / 100 }}</span>
</template>
</el-table-column>
<el-table-column
prop="taskCoin"
sortable="custom"
label="任务金币"
width="110"
>
<template #default="scope">
<span>{{ scope.row.taskCoin / 100 }}</span>
</template>
</el-table-column>
<el-table-column prop="name" label="提交人" width="110" />
<el-table-column
prop="createTime"
sortable="custom"
label="更新时间"
width="210"
show-overflow-tooltip
>
<template #default="scope">
<span>{{
moment(scope.row.createTime).format('YYYY-MM-DD HH:mm:ss')
}}</span>
</template>
</el-table-column>
</el-table>
</div>
<!-- 此处分页 -->
<div class="pagination" style="margin-top: 20px">
<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"
@current-change="handleCurrentChange"
></el-pagination>
</div>
</el-card>
</el-col>
</el-row>
</template>
<style scoped>
.pagination {
display: flex;
}
.status {
display: flex;
}
.head-card {
display: flex;
}
.info-panel-header {
font-weight: bold;
margin-bottom: 10px;
}
.dialog-footer {
display: flex;
justify-content: flex-end;
}
.export-status {
margin-top: 15px;
text-align: center;
color: #666;
}
.el-progress-bar__inner {
transition: width 0.5s ease;
}
</style>

1482
src/views/workspace/index.vue
File diff suppressed because it is too large
View File

Loading…
Cancel
Save