Compare commits

...

28 Commits

Author SHA1 Message Date
lihuilin 237cc42cd6 0512准备提测 10 months ago
lihuilin 4d333b45d8 自定义表头bug修完 10 months ago
lihuilin 35a5413266 消费导出完成,bug改完 10 months ago
lihuilin c658588182 0430改完bug 10 months ago
zry 59fbb3f106 Merge branch 'feat/lhl' of http://39.101.133.168:8807/yanjiaqing/gold_vue into feat/lhl 10 months ago
lihuilin d6a4c7ae92 充值类型下拉框失败 10 months ago
zry afd1a05c3b 导出excel功能完成 10 months ago
zry 4ee96e5ee2 合并main到feat/lhl 10 months ago
zry d1aaf0d4e8 测试合并branch 'feat/zry' 10 months ago
zry c1ff9eaca0 测试新的合并方案 10 months ago
zry 08c57ccb87 重做了客户金币明细的导出excel 10 months ago
lihuilin 229c13b945 改完今昨近七天 10 months ago
zry aca98aa791 新增活动的警告修改 10 months ago
zry 26012f376d 延迟的更改与提交(合并) 10 months ago
zry 204ec99a95 合并 10 months ago
zry 5649b90cf7 已完成的合并 10 months ago
zry eaf90724fd 活动页数100删除,工作台 10 months ago
lihuilin a117177bbb 0428提测未整合 10 months ago
lihuilin 653532717b 三期bug结束 10 months ago
zry 6736959de2 按钮失效bug修复;商品对应接口改正... 10 months ago
zry 83a81b0eca .env.production的更改 10 months ago
zry 21fde0c627 1.上正式地址,2.修复金豆明细地区无法更新金豆总额的bug 10 months ago
zry 74b52628e0 1.修复了在金豆明细地区搜索条件时的金豆总额更新,2.合并了lhl分支3.上正式环境 10 months ago
zry fccafa7087 Merge branch 'lhl' of http://39.101.133.168:8807/yanjiaqing/gold_vue into lhl 10 months ago
zry 55cc8c7b81 创建了zry新分支并push代码 10 months ago
lihuilin 3ffaf69421 测试正式地址正常 10 months ago
lihuilin f454649913 整合完毕 10 months ago
lihuilin d9a91abab1 充值审核去空格尝试 10 months ago
  1. 6
      gold-system/.env.development
  2. 4
      gold-system/.env.production
  3. 7
      gold-system/.env.test
  4. 6
      gold-system/package-lock.json
  5. 2
      gold-system/src/api/index.js
  6. 2
      gold-system/src/store/area.js
  7. 4
      gold-system/src/util/request.js
  8. 441
      gold-system/src/views/audit/rechargeAudit.vue
  9. 12
      gold-system/src/views/audit/refundAudit.vue
  10. 38
      gold-system/src/views/consume/addConsume.vue
  11. 18
      gold-system/src/views/consume/allConsume.vue
  12. 15
      gold-system/src/views/goldBeen/addGoldenBeen.vue
  13. 51
      gold-system/src/views/goldBeen/goldenBeenBalance.vue
  14. 308
      gold-system/src/views/goldBeen/goldenBeenConsum.vue
  15. 574
      gold-system/src/views/goldBeen/goldenBeenDetail.vue
  16. 572
      gold-system/src/views/goldBeen/onLineDetail.vue
  17. 9
      gold-system/src/views/index.vue
  18. 26
      gold-system/src/views/login.vue
  19. 377
      gold-system/src/views/managerecharge/activity.vue
  20. 175
      gold-system/src/views/managerecharge/rate.vue
  21. 12
      gold-system/src/views/permissions/index.vue
  22. 230
      gold-system/src/views/recharge/addRecharge.vue
  23. 2
      gold-system/src/views/recharge/adminRecharge.vue
  24. 320
      gold-system/src/views/recharge/allRecharge.vue
  25. 22
      gold-system/src/views/refund/addRefund.vue
  26. 3
      gold-system/src/views/refund/allRefund.vue
  27. 725
      gold-system/src/views/usergold/index.vue
  28. 59
      gold-system/src/views/usergoldInfo/index.vue
  29. 7
      gold-system/src/views/workspace/index.vue
  30. 2
      gold-system/stats.html

6
gold-system/.env.development

@ -1 +1,5 @@
VITE_API_BASE='http://54.251.137.151:10704/'
# VITE_API_BASE='http://54.251.137.151:10704/'
# VITE_API_BASE='http://192.168.8.94:8080/'
VITE_API_BASE='https://hwjb.homilychart.com/gold_htms_dev'
# VITE_API_BASE='http://54.251.137.151:10704/'
# VITE_API_BASE='http://192.168.8.220:8080/'

4
gold-system/.env.production

@ -1 +1,3 @@
VITE_API_BASE='http://54.251.137.151:10702/'
# VITE_API_BASE='http://54.251.137.151:10702/'
VITE_API_BASE='https://hwjb.homilychart.com/gold_htms_prod'
# VITE_API_BASE='http://192.168.8.220:8080/'

7
gold-system/.env.test

@ -1 +1,6 @@
VITE_API_BASE='http://54.251.137.151:10704/'
# VITE_API_BASE='https://hwjb.homilychart.com/gold_htms_prod'
#VITE_API_BASE='http://54.251.137.151:10704/'
# VITE_API_BASE='http://192.168.8.94:8080/'
VITE_API_BASE='https://hwjb.homilychart.com/gold_htms_dev'
# VITE_API_BASE='http://192.168.8.232:8080/'

6
gold-system/package-lock.json

@ -4093,9 +4093,8 @@
}, },
"node_modules/moment": { "node_modules/moment": {
"version": "2.30.1", "version": "2.30.1",
"resolved": "https://mirrors.huaweicloud.com/repository/npm/moment/-/moment-2.30.1.tgz",
"resolved": "https://registry.npmmirror.com/moment/-/moment-2.30.1.tgz",
"integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
"license": "MIT",
"engines": { "engines": {
"node": "*" "node": "*"
} }
@ -4987,9 +4986,8 @@
}, },
"node_modules/xlsx": { "node_modules/xlsx": {
"version": "0.18.5", "version": "0.18.5",
"resolved": "https://mirrors.huaweicloud.com/repository/npm/xlsx/-/xlsx-0.18.5.tgz",
"resolved": "https://registry.npmmirror.com/xlsx/-/xlsx-0.18.5.tgz",
"integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==", "integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==",
"license": "Apache-2.0",
"dependencies": { "dependencies": {
"adler-32": "~1.3.0", "adler-32": "~1.3.0",
"cfb": "~1.2.1", "cfb": "~1.2.1",

2
gold-system/src/api/index.js

@ -1,6 +1,6 @@
import { pa } from 'element-plus/es/locales.mjs'; import { pa } from 'element-plus/es/locales.mjs';
import http from '../util/http.js'; import http from '../util/http.js';
// 这个是不知道有啥用
const API={ const API={
post: function(url,data){ post: function(url,data){
return http({url:url,method:'post',data:data}) return http({url:url,method:'post',data:data})

2
gold-system/src/store/area.js

@ -1,5 +1,5 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
// 这个也是不知道有啥用,谁给在index.vue里注了
export const useAreaStore = defineStore('area', { export const useAreaStore = defineStore('area', {
state: () => ({ state: () => ({
currentArea: '全部', currentArea: '全部',

4
gold-system/src/util/request.js

@ -1,11 +1,13 @@
import axios from 'axios' import axios from 'axios'
// 创建axios实例
const service = axios.create({ const service = axios.create({
baseURL: import.meta.env.VITE_API_BASE, baseURL: import.meta.env.VITE_API_BASE,
timeout: 10000, timeout: 10000,
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}, },
// 设置默认请求方法为 POST
// 设置请求头,指定请求体的格式为 JSON
// 设置默认请求方法为 POST 这行对应的代码搁哪呢?
}) })
// 请求拦截器 // 请求拦截器

441
gold-system/src/views/audit/rechargeAudit.vue

@ -8,7 +8,29 @@ import request from '@/util/http'
import moment from 'moment' import moment from 'moment'
import API from '../../api/index.js' import API from '../../api/index.js'
// //
//
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 }
])
//
const defaultColumns = ['username', 'jwcode', 'area', 'status', 'operation']
const selectedColumns = ref([...defaultColumns])
// //
const adminData = ref({}) const adminData = ref({})
const getAdminData = async function () { const getAdminData = async function () {
@ -98,6 +120,10 @@ const trueGold = ref(0)
const trueCount = ref(0) const trueCount = ref(0)
const trueRGold = ref(0) const trueRGold = ref(0)
const trueFGold = ref(0) const trueFGold = ref(0)
//
const formattedTrueGold = computed(() => trueGold.value.toFixed(2))
const formattedTrueRGold = computed(() => trueRGold.value.toFixed(2))
const formattedTrueFGold = computed(() => trueFGold.value.toFixed(2))
// //
const pendingCount = ref(0) const pendingCount = ref(0)
// //
@ -215,6 +241,7 @@ const get = async function (val) {
} }
// //
const search = function () { const search = function () {
trimJwCode();
getObj.value.pageNum = 1 getObj.value.pageNum = 1
get() get()
} }
@ -410,7 +437,7 @@ const pass = function (row) {
passObj.value = row passObj.value = row
passObj.value.adminId = adminData.value.adminId passObj.value.adminId = adminData.value.adminId
passObj.value.auditId = row.auditId passObj.value.auditId = row.auditId
passObj.value.status = 1
// passObj.value.status = 1
passObj.value.rechargeId = row.rechargeId passObj.value.rechargeId = row.rechargeId
passObj.value.detailId = row.detailId passObj.value.detailId = row.detailId
passObj.value.jwcode = row.jwcode passObj.value.jwcode = row.jwcode
@ -424,6 +451,8 @@ const pass = function (row) {
// //
const passConfirm = async function () { const passConfirm = async function () {
try { try {
//
passObj.value.status = 1
console.log('通过对象', passObj.value) console.log('通过对象', passObj.value)
// POST // POST
// passObj.value.flag = 0; // passObj.value.flag = 0;
@ -442,8 +471,12 @@ const passConfirm = async function () {
message: '通过成功!' message: '通过成功!'
}) })
} catch (error) { } catch (error) {
console.log('请求失败', error)
//
console.error('请求失败', error);
//
ElMessage({
type: 'error',
message: '网络请求出错,请检查网络连接!'
});
} }
} }
@ -538,6 +571,13 @@ const handleSortChange = (column) => {
sortOrder.value = column.order === 'ascending' ? 'ASC' : 'DESC' sortOrder.value = column.order === 'ascending' ? 'ASC' : 'DESC'
get() get()
} }
//
const trimJwCode = () => {
if (rechargeVo.value.jwcode) {
rechargeVo.value.jwcode = rechargeVo.value.jwcode.replace(/\s/g, '');
}
}
</script> </script>
<template> <template>
@ -548,76 +588,40 @@ const handleSortChange = (column) => {
<el-col :span="6"> <el-col :span="6">
<div class="head-card-element"> <div class="head-card-element">
<el-text class="mx-1" size="large">精网号</el-text> <el-text class="mx-1" size="large">精网号</el-text>
<el-input
v-model="rechargeVo.jwcode"
placeholder="请输入精网号"
size="large"
style="width: 240px"
clearable
/>
<el-input v-model="rechargeVo.jwcode" placeholder="请输入精网号" style="width: 240px" clearable />
</div> </div>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<div class="head-card-element"> <div class="head-card-element">
<el-text class="mx-1" size="large">活动名称</el-text> <el-text class="mx-1" size="large">活动名称</el-text>
<el-select
v-model="rechargeVo.activityId"
placeholder="请选择活动名称"
size="large"
style="width: 240px"
clearable
>
<el-option
v-for="item in activity"
:key="item.activityId"
:label="item.activityName"
:value="item.activityId"
/>
<el-select v-model="rechargeVo.activityId" placeholder="请选择活动名称" style="width: 240px"
clearable>
<el-option v-for="item in activity" :key="item.activityId" :label="item.activityName"
:value="item.activityId" />
</el-select> </el-select>
</div> </div>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<div class="head-card-element"> <div class="head-card-element">
<el-text class="mx-1" size="large">支付方式</el-text> <el-text class="mx-1" size="large">支付方式</el-text>
<el-select
v-model="rechargeVo.payWay"
placeholder="请选择支付方式"
size="large"
style="width: 240px"
clearable
>
<el-option
v-for="item in payWay"
:key="item.value"
:label="item.label"
:value="item.value"
/>
<el-select v-model="rechargeVo.payWay" placeholder="请选择支付方式" style="width: 240px" clearable>
<el-option v-for="item in payWay" :key="item.value" :label="item.label" :value="item.value" />
</el-select> </el-select>
</div> </div>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<div class="head-card-element" v-if="adminData.area == '总部'"> <div class="head-card-element" v-if="adminData.area == '总部'">
<el-text class="mx-1" size="large">所属地区</el-text> <el-text class="mx-1" size="large">所属地区</el-text>
<el-select
v-model="rechargeVo.area"
placeholder="请选择所属地区"
size="large"
style="width: 240px"
clearable
>
<el-option
v-for="item in area"
:key="item"
:label="item"
:value="item"
/>
<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> </el-select>
</div> </div>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="21">
<div class="head-card-element">
<el-col :span="16">
<div class="time-controls">
<div class="time-group">
<el-text class="mx-1" size="large">充值时间</el-text> <el-text class="mx-1" size="large">充值时间</el-text>
<el-date-picker <el-date-picker
v-model="getTime" v-model="getTime"
@ -625,18 +629,27 @@ const handleSortChange = (column) => {
range-separator="至" range-separator="至"
start-placeholder="起始时间" start-placeholder="起始时间"
end-placeholder="结束时间" end-placeholder="结束时间"
style="width: 400px"
/> />
<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 @click="getToday()" style="margin-left: 10px"> </el-button>
<el-button @click="getYesterday()" style="margin-left: 10px"> </el-button>
<el-button @click="get7Days()" style="margin-left: 10px"> 近7天 </el-button>
</div> </div>
</el-col>
<el-col :span="3">
<div class="head-card-btn">
<el-button @click="reset()">重置</el-button>
<el-button type="primary" @click="search()">查询</el-button>
</div>
</el-col>
<el-col :span="8">
<el-button @click="reset()" type="success" style="margin-right: 10px">重置</el-button>
<el-button type="primary" @click="search()">查询</el-button>
</el-col>
</el-row>
<el-row>
<el-col :span="21">
<div>
<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> </div>
</el-col> </el-col>
</el-row> </el-row>
@ -646,12 +659,7 @@ const handleSortChange = (column) => {
<el-row> <el-row>
<el-col> <el-col>
<el-card> <el-card>
<el-tabs
v-model="activeName"
type="card"
class="demo-tabs"
@tab-click="handleClick"
>
<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="all"></el-tab-pane>
<el-tab-pane label="待审核" name="wait"></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="pass"></el-tab-pane>
@ -659,162 +667,66 @@ const handleSortChange = (column) => {
<div> <div>
总条数{{ trueCount }}总金币数{{ 总条数{{ trueCount }}总金币数{{
trueGold
}}金币永久金币{{ trueRGold }}金币免费金币{{ trueFGold }}金币
formattedTrueGold
}}金币永久金币{{ formattedTrueRGold }}金币免费金币{{ formattedTrueFGold }}金币
</div> </div>
</el-tabs> </el-tabs>
<div style="height: 540px; overflow-y: auto"> <div style="height: 540px; overflow-y: auto">
<el-table
:data="tableData"
style="width: 100%"
height="540px"
@sort-change="handleSortChange"
>
<el-table-column
type="index"
label="序号"
width="100px"
fixed="left"
>
<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"> <template #default="scope">
<span>{{ <span>{{
scope.$index + 1 + (getObj.pageNum - 1) * getObj.pageSize scope.$index + 1 + (getObj.pageNum - 1) * getObj.pageSize
}}</span> }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="username" label="姓名" width="100px" />
<el-table-column prop="jwcode" label="精网号" width="110px" />
<el-table-column prop="area" label="所属地区" width="100px" />
<el-table-column
prop="activityName"
label="活动名称"
width="150px"
/>
<el-table-column
prop="rechargeGold"
label="充值金额"
sortable="“custom”"
width="110px"
>
<template #default="scope">
{{ scope.row.rechargeGold }}
</template>
</el-table-column>
<el-table-column
prop="rechargeWay"
label="充值方式"
width="110px"
/>
<el-table-column
prop="paidGold"
label="永久金币"
sortable="“custom”"
width="110px"
>
<template #default="scope">
{{ scope.row.paidGold / 100 }}
</template>
</el-table-column>
<el-table-column
prop="freeGold"
label="免费金币"
sortable="“custom”"
width="110px"
>
<template #default="scope">
{{ scope.row.freeGold / 100 }}
</template>
</el-table-column>
<el-table-column
prop="remark"
label="备注"
width="200px"
show-overflow-tooltip
/>
<el-table-column prop="payWay" label="支付方式" width="100px" />
<el-table-column
prop="rechargeVoucher"
label="支付凭证"
width="150px"
>
<template #default="scope">
<el-image
: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"
label="交款时间"
sortable="“custom”"
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"
label="提交时间"
sortable="“custom”"
width="200px"
/>
<el-table-column
fixed="right"
prop="operation"
label="操作"
width="150px"
>
<!-- 动态列 -->
<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 === '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>
</template>
<el-table-column fixed="right" prop="operation" label="操作" width="150px">
<template #default="scope"> <template #default="scope">
<div class="operation"> <div class="operation">
<el-popconfirm
title="确定要通过此条记录吗?"
@confirm="passConfirm"
>
<el-popconfirm title="确定要通过此条记录吗?" @confirm="passConfirm">
<template #reference> <template #reference>
<el-button
:disabled="
scope.row.status === 1 || scope.row.status === 2
? true
: false
"
type="primary"
text
@click="pass(scope.row)"
>
<el-button :disabled="scope.row.status === 1 || scope.row.status === 2
? true
: false
" type="primary" text @click="pass(scope.row)">
通过 通过
</el-button> </el-button>
</template> </template>
@ -825,16 +737,10 @@ const handleSortChange = (column) => {
</el-button> </el-button>
</template> </template>
</el-popconfirm> </el-popconfirm>
<el-button
:disabled="
scope.row.status === 1 || scope.row.status === 2
? true
: false
"
type="primary"
text
@click="reject(scope.row)"
>
<el-button :disabled="scope.row.status === 1 || scope.row.status === 2
? true
: false
" type="primary" text @click="reject(scope.row)">
驳回 驳回
</el-button> </el-button>
</div> </div>
@ -845,44 +751,21 @@ const handleSortChange = (column) => {
<!-- 分页 --> <!-- 分页 -->
<div class="pagination"> <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> </div>
</el-card> </el-card>
</el-col> </el-col>
</el-row> </el-row>
<!-- 驳回弹出框 --> <!-- 驳回弹出框 -->
<el-dialog
v-model="rejectVisible"
title="驳回理由"
width="500"
:before-close="closeRejectVisible"
>
<el-dialog v-model="rejectVisible" title="驳回理由" width="500" :before-close="closeRejectVisible">
<template #footer> <template #footer>
<el-form
:model="rejectObj"
ref="Ref"
:rules="rules"
label-width="auto"
style="max-width: 600px"
>
<el-form :model="rejectObj" ref="Ref" :rules="rules" label-width="auto" style="max-width: 600px">
<el-form-item prop="reson" label="驳回理由:"> <el-form-item prop="reson" label="驳回理由:">
<el-input
v-model="rejectObj.reson"
maxlength="150"
show-word-limit
style="width: 350px"
type="textarea"
placeholder="请输入内容"
/>
<el-input v-model="rejectObj.reson" maxlength="150" show-word-limit style="width: 350px" type="textarea"
placeholder="请输入内容" />
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -899,23 +782,65 @@ const handleSortChange = (column) => {
display: flex; display: flex;
} }
.status {
.operation {
display: flex; display: flex;
} }
.operation {
.green-dot {
background-color: #67C23A;
}
.grey-dot {
background-color: #909399;
}
.red-dot {
background-color: #F56C6C;
}
.time-controls {
display: flex; display: flex;
align-items: center;
} }
.head-card {
.time-group {
display: flex; display: flex;
align-items: center;
gap: 10px;
} }
.head-card-element {
margin-right: 20px;
.quick-buttons {
display: flex;
align-items: center;
} }
.head-card-btn {
margin-left: auto;
.status {
display: flex;
align-items: center; /* 确保子元素垂直居中对齐 */
gap: 6px; /* 设置圆点和文字之间的间距 */
}
.green-dot, .grey-dot, .red-dot {
display: inline-block;
width: 8px;
height: 8px;
border-radius: 50%;
flex-shrink: 0; /* 防止圆点在空间不足时缩小 */
margin: 0; /* 移除原有的 margin-right */
}
/* 备注列样式 */
.remark-cell {
display: block;
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* 设置单元格内容溢出隐藏 */
.el-table .el-table__cell {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
} }
</style> </style>

12
gold-system/src/views/audit/refundAudit.vue

@ -181,6 +181,7 @@ const get = async function (val) {
} }
// //
const search = function () { const search = function () {
trimJwCode();
getObj.value.pageNum = 1 getObj.value.pageNum = 1
get() get()
} }
@ -494,6 +495,13 @@ const handleSortChange = (column) => {
sortOrder.value = column.order === 'ascending' ? 'ASC' : 'DESC' sortOrder.value = column.order === 'ascending' ? 'ASC' : 'DESC'
get() get()
} }
//
const trimJwCode = () => {
if (detail.value.jwcode) {
// 使
detail.value.jwcode = detail.value.jwcode.replace(/\s/g, '');
}
}
</script> </script>
<template> <template>
@ -574,7 +582,7 @@ const handleSortChange = (column) => {
<el-row> <el-row>
<el-col :span="21"> <el-col :span="21">
<div class="head-card-element"> <div class="head-card-element">
<el-text class="mx-1" size="large">充值时间</el-text>
<el-text class="mx-1" size="large">退款时间</el-text>
<el-date-picker <el-date-picker
v-model="getTime" v-model="getTime"
type="datetimerange" type="datetimerange"
@ -591,7 +599,7 @@ const handleSortChange = (column) => {
</el-col> </el-col>
<el-col :span="3"> <el-col :span="3">
<div class="head-card-btn"> <div class="head-card-btn">
<el-button @click="reset()">重置</el-button>
<el-button type="success" @click="reset()">重置</el-button>
<el-button type="primary" @click="search()">查询</el-button> <el-button type="primary" @click="search()">查询</el-button>
</div> </div>
</el-col> </el-col>

38
gold-system/src/views/consume/addConsume.vue

@ -9,7 +9,12 @@ import API from "../../api/index.js";
import moment from "moment"; import moment from "moment";
import _ from "lodash"; import _ from "lodash";
import request from "@/util/http"; import request from "@/util/http";
//
const trimJwCode = () => {
if (addConsume.value.jwcode) {
addConsume.value.jwcode = addConsume.value.jwcode.replace(/\s/g, '');
}
}
// //
const adminData = ref({}); const adminData = ref({});
const getAdminData = async function () { const getAdminData = async function () {
@ -143,12 +148,13 @@ const user = ref({
firstRechargeTime: "", firstRechargeTime: "",
}); });
const getUser = async function (jwcode) { const getUser = async function (jwcode) {
trimJwCode();
try { try {
// POST // POST
const result = await request({ const result = await request({
url: "/recharge/user", url: "/recharge/user",
data: { data: {
jwcode: jwcode,
jwcode: addConsume.value.jwcode,
area: adminData.value.area, area: adminData.value.area,
}, },
}); });
@ -174,12 +180,13 @@ const getUser = async function (jwcode) {
// //
const userGold = ref({}); const userGold = ref({});
const getUserGold = async function (jwcode) { const getUserGold = async function (jwcode) {
trimJwCode();
try { try {
// POST // POST
const result = await request({ const result = await request({
url: "/recharge/user", url: "/recharge/user",
data: { data: {
jwcode: jwcode,
jwcode: addConsume.value.jwcode,
area: adminData.value.area, area: adminData.value.area,
}, },
}); });
@ -317,6 +324,21 @@ onMounted(async function () {
await getGoods(); await getGoods();
await getIndexs(1); 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> </script>
<template> <template>
@ -353,6 +375,10 @@ onMounted(async function () {
placeholder="请选择" placeholder="请选择"
style="width: 300px" style="width: 300px"
@change="handleProductSelect(addConsume.productName)" @change="handleProductSelect(addConsume.productName)"
@blur="handleSelectBlur(addConsume.productName)"
filterable
allow-create
default-first-option
> >
<el-option <el-option
v-for="item in goods" v-for="item in goods"
@ -436,7 +462,7 @@ onMounted(async function () {
placeholder="提交人姓名" placeholder="提交人姓名"
/> />
</el-form-item> </el-form-item>
<el-button @click="delteConsume" style="margin-left: 280px">重置</el-button>
<el-button type="success" @click="delteConsume" style="margin-left: 280px">重置</el-button>
<el-button type="primary" @click="addBefore"> 提交 </el-button> <el-button type="primary" @click="addBefore"> 提交 </el-button>
</el-form> </el-form>
@ -500,11 +526,11 @@ onMounted(async function () {
<p style="color: #2fa1ff">{{ user.rechargeTimes }}</p> <p style="color: #2fa1ff">{{ user.rechargeTimes }}</p>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="10">
<!-- <el-col :span="10">
<el-form-item label="负责客服"> <el-form-item label="负责客服">
<p>{{ adminData.name }}</p> <p>{{ adminData.name }}</p>
</el-form-item> </el-form-item>
</el-col>
</el-col> -->
<el-col :span="14"> <el-col :span="14">
<el-form-item label="消费次数"> <el-form-item label="消费次数">
<p style="color: #2fa1ff">{{ user.spendTimes }}</p> <p style="color: #2fa1ff">{{ user.spendTimes }}</p>

18
gold-system/src/views/consume/allConsume.vue

@ -284,15 +284,14 @@ const getGoods = async function () {
try { try {
// POST // POST
const result = await request({ const result = await request({
url: '/product',
url: '/product/findProductName',
data: {} data: {}
}) })
// //
console.log('请求成功', result)
console.log('请求成功product', result)
// //
goods.value = result.data goods.value = result.data
console.log('allData', allData.value)
console.log('地区', area.value)
console.log('goods 数据', goods.value) //
} catch (error) { } catch (error) {
console.log('请求失败', error) console.log('请求失败', error)
// //
@ -344,11 +343,12 @@ const handleCurrentChange = function (val) {
style="width: 240px" style="width: 240px"
clearable clearable
> >
<!-- 修改 v-for 绑定逻辑 -->
<el-option <el-option
v-for="item in goods"
:key="item.activityId"
:label="item.name"
:value="item.name"
v-for="(item, index) in goods"
:key="index"
:label="item"
:value="item"
/> />
</el-select> </el-select>
</div> </div>
@ -412,7 +412,7 @@ const handleCurrentChange = function (val) {
</el-col> </el-col>
<el-col :span="3"> <el-col :span="3">
<div class="head-card-btn"> <div class="head-card-btn">
<el-button @click="reset()">重置</el-button>
<el-button type="success" @click="reset()">重置</el-button>
<el-button type="primary" @click="search()">查询</el-button> <el-button type="primary" @click="search()">查询</el-button>
</div> </div>
</el-col> </el-col>

15
gold-system/src/views/goldBeen/addGoldenBeen.vue

@ -14,7 +14,7 @@
<el-input v-model="beenObj.jwcode" style="width: 220px" /> <el-input v-model="beenObj.jwcode" style="width: 220px" />
<el-button <el-button
type="primary" type="primary"
@click="getUser(beenObj.jwcode)"
@click="getUser()"
style="margin-left: 20px" style="margin-left: 20px"
>查询</el-button >查询</el-button
> >
@ -62,7 +62,7 @@
</el-form-item> --> </el-form-item> -->
<el-form-item> <el-form-item>
<div class="btn-group"> <div class="btn-group">
<el-button @click="resetData(ruleFormRef)">重置</el-button>
<el-button type="success" @click="resetData(ruleFormRef)">重置</el-button>
<el-button type="primary" @click="addBean(ruleFormRef)"> <el-button type="primary" @click="addBean(ruleFormRef)">
提交 提交
</el-button> </el-button>
@ -150,13 +150,20 @@ const resetData = (formEl) => {
if (!formEl) return if (!formEl) return
formEl.resetFields() formEl.resetFields()
} }
const getUser = async function (jwcode) {
//
const trimJwCode = () => {
if (beenObj.value.jwcode) {
beenObj.value.jwcode = beenObj.value.jwcode.replace(/\s/g, '');
}
}
const getUser = async function () {
trimJwCode();
try { try {
// POST // POST
const result = await API({ const result = await API({
url: '/dou/search', url: '/dou/search',
data: { data: {
jwcode: jwcode
jwcode: beenObj.value.jwcode
} }
}) })
if (result.code === 0) { if (result.code === 0) {

51
gold-system/src/views/goldBeen/goldenBeenBalance.vue

@ -1,14 +1,17 @@
<template> <template>
<!-- 这是客户金豆余额页面 -->
<div class="filter-box"> <div class="filter-box">
<el-form :model="detailY" ref="ruleFormRef"> <el-form :model="detailY" ref="ruleFormRef">
<el-form-item prop="jwcode" label="精网号">
<el-form-item prop="jwcode">
<el-text class="mx-1" size="large">精网号</el-text>
<el-input <el-input
v-model="detailY.jwcode" v-model="detailY.jwcode"
placeholder="请输入精网号" placeholder="请输入精网号"
style="width: 220px" style="width: 220px"
/> />
</el-form-item> </el-form-item>
<el-form-item prop="area" label="地区">
<el-form-item prop="area">
<el-text class="mx-1" size="large">地区</el-text>
<el-select <el-select
v-model="detailY.area" v-model="detailY.area"
placeholder="请选择所属地区" placeholder="请选择所属地区"
@ -24,21 +27,21 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" size="small" @click="search()"
<el-button type="primary" @click="search()"
>查询</el-button >查询</el-button
> >
<el-button type="primary" size="small" @click="reset(ruleFormRef)"
<el-button type="success" @click="reset(ruleFormRef)"
>重置</el-button >重置</el-button
> >
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
<div class="table-box"> <div class="table-box">
<p>
现有金豆:&nbsp;&nbsp;付费金豆:{{ getObj.jinbiBuy }}&nbsp;&nbsp;免费金豆:{{
<div>
现有金豆&nbsp;&nbsp;付费金豆{{ getObj.jinbiBuy }}&nbsp;&nbsp;免费金豆{{
getObj.jinbiFree getObj.jinbiFree
}}&nbsp;&nbsp;历史消费:{{ getObj.jinbiCostTotal }}
</p>
}}&nbsp;&nbsp;历史消费{{ getObj.jinbiCostTotal }}
</div>
<el-table <el-table
:data="tableData" :data="tableData"
style="width: 100%" style="width: 100%"
@ -118,7 +121,14 @@ let getObj = ref({
jinbiCostTotal: 0, jinbiCostTotal: 0,
jinbiFree: 0 jinbiFree: 0
}) })
//
const trimJwCode = () => {
if (detailY.jwcode) {
detailY.jwcode = detailY.jwcode.replace(/\s/g, '');
}
}
const search = function () { const search = function () {
trimJwCode();
getInit({}) getInit({})
getCount() getCount()
} }
@ -186,14 +196,23 @@ const getArea = async () => {
} }
} }
const getCount = async () => { const getCount = async () => {
const result = await API({
url: '/dou/getYveTotal'
})
if (result.code == 200) {
const { jinbiBuy, jinbiFree, jinbiCostTotal } = result.data
getObj.value.jinbiBuy = jinbiBuy
getObj.value.jinbiFree = jinbiFree
getObj.value.jinbiCostTotal = jinbiCostTotal
try {
const result = await API({
url: '/dou/getYveTotal',
// jwcodeipAddress
data: {
jwcode: detailY.jwcode,
ipAddress: detailY.area
}
})
if (result.code === 200) {
const { jinbiBuy, jinbiFree, jinbiCostTotal } = result.data
getObj.value.jinbiBuy = jinbiBuy
getObj.value.jinbiFree = jinbiFree
getObj.value.jinbiCostTotal = jinbiCostTotal
}
} catch (error) {
console.log('获取统计数据失败', error)
} }
} }
getArea() getArea()

308
gold-system/src/views/goldBeen/goldenBeenConsum.vue

@ -1,14 +1,17 @@
<template> <template>
<!-- 这是金豆消费明细页面 -->
<div class="filter-box"> <div class="filter-box">
<el-form :model="detailY" ref="ruleFormRef"> <el-form :model="detailY" ref="ruleFormRef">
<el-form-item prop="jwcode" label="精网号">
<el-form-item prop="jwcode">
<el-text class="mx-1" size="large">精网号</el-text>
<el-input <el-input
v-model="detailY.jwcode" v-model="detailY.jwcode"
placeholder="请输入精网号" placeholder="请输入精网号"
style="width: 220px" style="width: 220px"
/> />
</el-form-item> </el-form-item>
<el-form-item prop="ipAddress" label="地区">
<el-form-item prop="ipAddress">
<el-text class="mx-1" size="large">地区</el-text>
<el-select <el-select
v-model="detailY.ipAddress" v-model="detailY.ipAddress"
placeholder="请选择所属地区" placeholder="请选择所属地区"
@ -23,7 +26,8 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item prop="sourceType" label="消费类型">
<el-form-item prop="sourceType">
<el-text class="mx-1" size="large">消费类型</el-text>
<el-select <el-select
v-model="detailY.sourceType" v-model="detailY.sourceType"
placeholder="请选择消费类型" placeholder="请选择消费类型"
@ -54,32 +58,48 @@
/> />
</el-select> </el-select>
</el-form-item> --> </el-form-item> -->
<el-form-item prop="sourceName" label="直播间">
<el-form-item prop="sourceName">
<el-text class="mx-1" size="large">直播间</el-text>
<el-input <el-input
v-model="detailY.sourceName" v-model="detailY.sourceName"
placeholder="请输入直播间" placeholder="请输入直播间"
style="width: 220px" style="width: 220px"
/> />
</el-form-item> </el-form-item>
<el-form-item prop="createTime" label="消费时间">
<el-form-item prop="startTime">
<el-text class="mx-1" size="large">开始时间</el-text>
<el-date-picker <el-date-picker
v-model="detailY.createTime"
type="daterange"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="YYYY-MM-DD HH:mm:ss"
v-model="detailY.startTime"
type="date"
placeholder="开始日期"
style="width: 240px"
format="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
/>
</el-form-item>
<el-form-item prop="endTime">
<el-text class="mx-1" size="large">结束时间</el-text>
<el-date-picker
v-model="detailY.endTime"
type="date"
placeholder="结束日期"
style="width: 240px" style="width: 240px"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
/> />
<el-button style="margin-left: 10px" @click="getToday()"></el-button>
<el-button @click="getYesterday()"></el-button>
<el-button @click="get7Days()">近7天</el-button>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="success" @click="exportExcel">导出Excel</el-button>
<el-button type="primary" @click="search">查询</el-button> <el-button type="primary" @click="search">查询</el-button>
<el-button type="success" @click="reset(ruleFormRef)">重置</el-button> <el-button type="success" @click="reset(ruleFormRef)">重置</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
<div class="table-box"> <div class="table-box">
<p>合计数:实际用户金豆数:{{ beenCount }}</p>
<div>合计数实际用户金豆数{{ beenCount }}</div>
<el-table :data="tableData" style="width: 100%" height="584px"> <el-table :data="tableData" style="width: 100%" height="584px">
<el-table-column type="index" label="序号" width="100px" fixed="left"> <el-table-column type="index" label="序号" width="100px" fixed="left">
<template #default="scope"> <template #default="scope">
@ -145,6 +165,59 @@
</el-pagination> </el-pagination>
</div> </div>
</div> </div>
<!-- 导出信息确认对话框 -->
<el-dialog
v-model="showExportInfoPanel"
title="导出信息确认"
width="400px"
:close-on-click-modal="false"
>
<div class="info-panel-header">导出信息</div>
<div v-if="!detailY.jwcode && !detailY.ipAddress && !detailY.sourceType && !detailY.sourceName && (!detailY.startTime || !detailY.endTime)">
你正在导出所有数据
</div>
<div v-else>
你正在导出以下数据
</div>
<div v-if="detailY.jwcode">精网号{{ detailY.jwcode }}</div>
<div v-if="detailY.ipAddress">地区{{ detailY.ipAddress }}</div>
<div v-if="detailY.sourceType">
消费类型{{ consumList.value.find(item => item.value === detailY.sourceType)?.text }}
</div>
<div v-if="detailY.sourceName">直播间{{ detailY.sourceName }}</div>
<div v-if="detailY.startTime && detailY.endTime">
时间范围{{ detailY.startTime }} {{ detailY.endTime }}
</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>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue' import { ref } from 'vue'
@ -152,6 +225,10 @@ import type { FormInstance } from 'element-plus'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import moment from 'moment' import moment from 'moment'
import API from '@/util/http' import API from '@/util/http'
import axios from 'axios'
// xlsx
import * as XLSX from 'xlsx'
const { utils, writeFile } = XLSX
// //
const tableData = ref([]) const tableData = ref([])
@ -172,14 +249,15 @@ const consumList = ref<any>([
{ value: 10, text: '打赏视频' }, { value: 10, text: '打赏视频' },
{ value: 11, text: '付费购买' } { value: 11, text: '付费购买' }
]) ])
const channelList = ref<string[]>([])
const liveroomList = ref<string[]>([])
// const channelList = ref<string[]>([])
// const liveroomList = ref<string[]>([])
const ruleFormRef = ref<FormInstance>() const ruleFormRef = ref<FormInstance>()
// //
const detailY = ref({ const detailY = ref({
jwcode: '', jwcode: '',
ipAddress: '', ipAddress: '',
createTime: '',
startTime:'',
endTime:'',
// channel: '', // // channel: '', //
sourceName: '', // sourceName: '', //
sourceType: '' // sourceType: '' //
@ -188,11 +266,44 @@ const getObj = ref({
pageNum: 1, pageNum: 1,
pageSize: 50 pageSize: 50
}) })
//
const getToday = function () {
const today = new Date()
//
const startDate = moment(today).startOf('day').format('YYYY-MM-DD HH:mm:ss')
//
const endDate = moment(today).endOf('day').format('YYYY-MM-DD HH:mm:ss')
detailY.value.startTime = startDate
detailY.value.endTime = endDate
search()
}
//
const getYesterday = function () {
const yesterday = moment().subtract(1, 'days')
//
const startDate = yesterday.startOf('day').format('YYYY-MM-DD HH:mm:ss')
//
const endDate = yesterday.endOf('day').format('YYYY-MM-DD HH:mm:ss')
detailY.value.startTime = startDate
detailY.value.endTime = endDate
search()
}
// 7
const get7Days = function () {
//
const startDate = moment().subtract(6, 'days').startOf('day').format('YYYY-MM-DD HH:mm:ss')
//
const endDate = moment().endOf('day').format('YYYY-MM-DD HH:mm:ss')
detailY.value.startTime = startDate
detailY.value.endTime = endDate
search()
}
// //
const getInit = async function () { const getInit = async function () {
try { try {
console.log('搜索参数', getObj.value) console.log('搜索参数', getObj.value)
const [startTime, endTime] = detailY.value.createTime
const startTime = detailY.value.startTime
const endTime = detailY.value.endTime
// POST // POST
const result = await API({ const result = await API({
url: '/dou/getSpend', url: '/dou/getSpend',
@ -218,8 +329,19 @@ const getInit = async function () {
// //
} }
} }
//
const trimJwCode = () => {
if (detailY.value.jwcode) {
detailY.value.jwcode = detailY.value.jwcode.replace(/\s/g, '');
}
if (detailY.value.sourceName) {
detailY.value.sourceName = detailY.value.sourceName.replace(/\s/g, '');
}
}
// //
const search = function () { const search = function () {
trimJwCode();
getObj.value.pageNum = 1 getObj.value.pageNum = 1
getInit() getInit()
getCount() getCount()
@ -247,8 +369,8 @@ const getCount = async () => {
ipAddress: detailY.value.ipAddress, ipAddress: detailY.value.ipAddress,
sourceName: detailY.value.sourceName, sourceName: detailY.value.sourceName,
sourceType: detailY.value.sourceType, sourceType: detailY.value.sourceType,
startTime: detailY.value.createTime[0],
endTime: detailY.value.createTime[1]
startTime: detailY.value.startTime,
endTime: detailY.value.endTime
} }
}) })
if (result.code == 200) { if (result.code == 200) {
@ -268,6 +390,158 @@ const getArea = async () => {
console.log('请求失败', error) console.log('请求失败', error)
} }
} }
//
const showExportInfoPanel = ref(false)
const exportProgress = ref(0)
const isExporting = ref(false)
const exportCancelToken = ref<any>(null)
// Excel
const headers = [
'序号',
'姓名',
'精网号',
'地区',
'消费类型',
'金豆价格',
'直播间',
'消费时间'
]
//
const exportExcel = () => {
showExportInfoPanel.value = true
}
//
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: any[][], o: any) => {
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: '/dou/getSpend',
method: 'post',
data: {
pageNum: 1,
pageSize,
spend: {
...detailY.value
}
}
})
totalRecords = firstResult.data.total
//
const CancelToken = axios.CancelToken
exportCancelToken.value = CancelToken.source()
//
const firstData = firstResult.data.list
if (firstData.length) {
const rows = firstData.map((row: any, index: number) => {
return [
totalExported + index + 1,
row.nickname || '',
row.jwcode || '',
row.ipAddress || '',
consumList.value.find(item => item.value === row.sourceType)?.text || '',
row.jinbiCostTotal || 0,
row.room || '',
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: '/dou/getSpend',
method: 'post',
data: {
pageNum: page,
pageSize,
spend: {
...detailY.value
}
},
cancelToken: exportCancelToken.value.token
})
const data = result.data.list
if (!data.length) break
//
const rows = data.map((row: any, index: number) => [
totalExported + index + 1,
row.nickname || '',
row.jwcode || '',
row.ipAddress || '',
consumList.value.find(item => item.value === row.sourceType)?.text || '',
row.jinbiCostTotal || 0,
row.room || '',
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')
exportProgress.value = 100
isExporting.value = false
exportCancelToken.value = null
ElMessage.success(`导出成功,共${totalExported}条数据`)
} catch (error) {
if (!axios.isCancel(error)) {
ElMessage.error(`导出失败: ${error.message}`)
}
isExporting.value = false
exportCancelToken.value = null
}
}
//
const cancelExport = () => {
if (exportCancelToken.value) {
exportCancelToken.value.cancel('用户取消导出')
ElMessage.warning('导出已取消')
isExporting.value = false
}
}
// //
getInit() getInit()
getCount() getCount()

574
gold-system/src/views/goldBeen/goldenBeenDetail.vue

@ -1,14 +1,17 @@
<template> <template>
<!-- 这是金豆充值明细页面 -->
<div class="filter-box"> <div class="filter-box">
<el-form :model="detailY" ref="ruleFormRef"> <el-form :model="detailY" ref="ruleFormRef">
<el-form-item prop="jwcode" label="精网号">
<el-form-item prop="jwcode">
<el-text class="mx-1" size="large">精网号</el-text>
<el-input <el-input
v-model="detailY.jwcode" v-model="detailY.jwcode"
placeholder="请输入精网号" placeholder="请输入精网号"
style="width: 220px" style="width: 220px"
/> />
</el-form-item> </el-form-item>
<el-form-item prop="deptName" label="地区">
<el-form-item prop="deptName" >
<el-text class="mx-1" size="large">地区</el-text>
<el-select <el-select
v-model="detailY.deptName" v-model="detailY.deptName"
placeholder="请选择所属地区" placeholder="请选择所属地区"
@ -23,20 +26,31 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item prop="orderNo" label="订单号">
<el-form-item prop="orderNo" >
<el-text class="mx-1" size="large">订单号</el-text>
<el-input <el-input
v-model="detailY.orderNo" v-model="detailY.orderNo"
placeholder="请输入订单号" placeholder="请输入订单号"
style="width: 220px" style="width: 220px"
/> />
</el-form-item> </el-form-item>
<el-form-item prop="type" label="充值类型">
<el-input
<el-form-item prop="type">
<el-text class="mx-1" size="large">充值类型</el-text>
<el-select
v-model="detailY.type" v-model="detailY.type"
placeholder="请输入充值类型"
style="width: 220px"
/>
placeholder="请选择充值类型"
style="width: 240px"
clearable
>
<el-option
v-for="item in typeList"
:key="item"
:label="item"
:value="item"
/>
</el-select>
</el-form-item> </el-form-item>
<!-- <el-form-item prop="payStyle" label="充值平台"> <!-- <el-form-item prop="payStyle" label="充值平台">
<el-select <el-select
v-model="detailY.payStyle" v-model="detailY.payStyle"
@ -52,30 +66,100 @@
/> />
</el-select> </el-select>
</el-form-item> --> </el-form-item> -->
<el-form-item prop="createTime" label="充值时间">
<el-row :span="24">
<el-form-item prop="startTime">
<el-text class="mx-1" size="large">开始时间</el-text>
<el-date-picker
v-model="detailY.startTime"
type="date"
placeholder="开始日期"
style="width: 240px"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
/>
</el-form-item>
<el-form-item prop="endTime">
<el-text class="mx-1" size="large">结束时间</el-text>
<el-date-picker <el-date-picker
v-model="detailY.createTime"
type="daterange"
start-placeholder="开始日期"
end-placeholder="结束日期"
v-model="detailY.endTime"
type="date"
placeholder="结束日期"
style="width: 240px" style="width: 240px"
format="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
:unlinkPanels="true"
/> />
</el-form-item> </el-form-item>
<el-button style="margin-left: 10px" @click="getToday()"></el-button>
<el-button @click="getYesterday()"></el-button>
<el-button @click="get7Days()">近7天</el-button>
</el-row>
<el-form-item> <el-form-item>
<el-button type="primary" @click="search">查询</el-button> <el-button type="primary" @click="search">查询</el-button>
<el-button type="success" @click="reset(ruleFormRef)">重置</el-button> <el-button type="success" @click="reset(ruleFormRef)">重置</el-button>
<el-button type="primary" @click="exportExcel">导出excel</el-button>
<el-button type="primary" @click="showExportInfoPanel = true">导出excel</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
<!-- 导出excel提前展示的信息面板 -->
<el-dialog
v-model="showExportInfoPanel"
title="导出信息确认"
width="400px"
:close-on-click-modal="false"
>
<div class="info-panel-header">导出信息</div>
<div v-if="!detailY.jwcode && !detailY.deptName && !detailY.orderNo && !detailY.type && !detailY.startTime && !detailY.endTime">
你正在导出所有数据
</div>
<div v-else>
你正在导出以下数据
</div>
<div v-if="detailY.jwcode">精网号{{ detailY.jwcode || '' }}</div>
<div v-if="detailY.deptName">所属地区{{ detailY.deptName || '' }}</div>
<div v-if="detailY.orderNo">订单号{{ detailY.orderNo || '' }}</div>
<div v-if="detailY.type">充值类型{{ detailY.type || '' }}</div>
<div v-if="detailY.startTime || detailY.endTime">
<span>更新时间</span>
<span>{{ detailY.startTime || '无起始时间' }} {{ detailY.endTime || '无结束时间' }}</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">
已导出 {{ exportedCount }} / {{ totalExport }}
</div>
<template #footer>
<el-button type="danger" @click="cancelExport">取消导出</el-button>
</template>
</el-dialog>
<div class="table-box"> <div class="table-box">
<el-card
>金豆总数充值金豆总数{{ countValue }}合计金额数:{{
<div
>金豆总数充值金豆总数{{ countValue }}合计金额数{{
priceValue priceValue
}}</el-card
}}</div
> >
<el-table :data="tableData" style="width: 100%" height="584px"> <el-table :data="tableData" style="width: 100%" height="584px">
<el-table-column type="index" label="序号" width="100px" fixed="left"> <el-table-column type="index" label="序号" width="100px" fixed="left">
@ -130,7 +214,7 @@
</div> </div>
</div> </div>
<!-- 这是导出excel的弹窗 --> <!-- 这是导出excel的弹窗 -->
<el-dialog
<!-- <el-dialog
v-model="dialogVisible" v-model="dialogVisible"
title="请选择导出条件" title="请选择导出条件"
width="500" width="500"
@ -192,16 +276,144 @@
> >
</el-form> </el-form>
</template> </template>
</el-dialog>
</el-dialog> -->
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { reactive, ref } from 'vue'
import { reactive, ref, onMounted, onUnmounted } from 'vue'
import { FormInstance } from 'element-plus' import { FormInstance } from 'element-plus'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import moment from 'moment' import moment from 'moment'
import API from '@/util/http' import API from '@/util/http'
import { utils, write } from 'xlsx' import { utils, write } from 'xlsx'
import { saveAs } from 'file-saver' import { saveAs } from 'file-saver'
const showExportInfoPanel = ref(false)
const isExporting = ref(false)
const exportProgress = ref(0)
const totalExport = ref(0)
const exportedCount = ref(0)
let cancelToken: any = null
let allExportData: any[] = []
//
const cancelExport = () => {
if (cancelToken) {
cancelToken.cancel('导出已取消')
}
isExporting.value = false
exportProgress.value = 0
exportedCount.value = 0
allExportData = []
ElMessage.info('导出已取消')
}
// Excel
const doExportExcel = async () => {
try {
isExporting.value = true
exportProgress.value = 0
exportedCount.value = 0
allExportData = []
//
const totalResult = await API({
url: '/dou/getPay',
data: {
pay: {
jwcode: detailY.value.jwcode,
deptName: detailY.value.deptName,
startTime: detailY.value.startTime || '',
endTime: detailY.value.endTime || '',
payStyle: detailY.value.payStyle,
type: detailY.value.type,
orderNo: detailY.value.orderNo,
sortField: '',
sortOrder: ''
},
pageNum: 1,
pageSize: 1
}
})
totalExport.value = totalResult.data.total
if (totalExport.value === 0) {
ElMessage.error('没有数据可导出')
isExporting.value = false
return
}
const pageSize = 5000 // 100
const totalPages = Math.ceil(totalExport.value / pageSize)
for (let page = 1; page <= totalPages; page++) {
if (!isExporting.value) break //
const result = await API({
url: '/dou/getPay',
data: {
pay: {
jwcode: detailY.value.jwcode,
deptName: detailY.value.deptName,
startTime: detailY.value.startTime || '',
endTime: detailY.value.endTime || '',
payStyle: detailY.value.payStyle,
type: detailY.value.type,
orderNo: detailY.value.orderNo,
sortField: '',
sortOrder: ''
},
pageNum: page,
pageSize: pageSize
}
})
const data = result.data.list
allExportData = allExportData.concat(data)
exportedCount.value = allExportData.length
exportProgress.value = Math.round((exportedCount.value / totalExport.value) * 100)
}
if (isExporting.value) {
//
const exportData = allExportData.map((item, index) => {
return {
序号: index + 1, //
姓名: item.nickname,
精网号: item.jwcode,
地区: item.ipAddress,
订单号: item.orderNo,
金豆数量: item.money,
付费金豆: item.moneyBuy,
免费金豆: item.moneyFree,
金额: item.price,
类型: item.type,
充值时间: !!item.time ? moment.unix(item.time).format('YYYY-MM-DD HH:mm:ss') : '-'
}
})
const worksheet = utils.json_to_sheet(exportData)
const workbook = utils.book_new()
utils.book_append_sheet(workbook, worksheet, 'Sheet1')
const wbout = write(workbook, { bookType: 'xlsx', type: 'array' })
saveAs(
new Blob([wbout], { type: 'application/octet-stream' }),
'金豆充值明细导出.xlsx'
)
showExportInfoPanel.value = false
isExporting.value = false
ElMessage.success('导出成功')
}
} catch (error) {
if (error.message === '导出已取消') {
return
}
console.log('导出失败', error)
isExporting.value = false
ElMessage.error('导出失败,请稍后重试')
}
}
// //
const tableData = ref([]) const tableData = ref([])
// //
@ -216,12 +428,66 @@ const excelData = reactive({
}) })
const priceValue = ref(0) const priceValue = ref(0)
const countValue = ref(0) const countValue = ref(0)
// areaList
const areaList = ref<string[]>([]) const areaList = ref<string[]>([])
const isExport = ref<boolean>(false) const isExport = ref<boolean>(false)
const rules = ref({ const rules = ref({
jwcode: [{ required: true, message: '请输入精网号', trigger: 'blur' }], jwcode: [{ required: true, message: '请输入精网号', trigger: 'blur' }],
area: [{ required: true, message: '请选择所属地区', trigger: 'change' }] area: [{ required: true, message: '请选择所属地区', trigger: 'change' }]
}) })
//
const getToday = function () {
const today = new Date()
//
const startDate = moment(today).startOf('day').format('YYYY-MM-DD HH:mm:ss')
//
const endDate = moment(today).endOf('day').format('YYYY-MM-DD HH:mm:ss')
detailY.value.startTime = startDate
detailY.value.endTime = endDate
search()
}
//
const getYesterday = function () {
const yesterday = moment().subtract(1, 'days')
//
const startDate = yesterday.startOf('day').format('YYYY-MM-DD HH:mm:ss')
//
const endDate = yesterday.endOf('day').format('YYYY-MM-DD HH:mm:ss')
detailY.value.startTime = startDate
detailY.value.endTime = endDate
search()
}
// 7
const get7Days = function () {
//
const startDate = moment().subtract(6, 'days').startOf('day').format('YYYY-MM-DD HH:mm:ss')
//
const endDate = moment().endOf('day').format('YYYY-MM-DD HH:mm:ss')
detailY.value.startTime = startDate
detailY.value.endTime = endDate
search()
}
//
const getArea = async () => {
try {
const result = await API({
url: '/dou/getPayIp'
})
areaList.value = result.data
} catch (error) {
console.log('请求失败', error)
}
}
const getType = async () => {
try {
const result = await API({
url: '/dou/getType'
})
typeList.value = result.data
} catch (error) {
console.log('请求失败', error)
}
}
const handlePageSizeChange = (val) => { const handlePageSizeChange = (val) => {
getObj.value.pageSize = val getObj.value.pageSize = val
getObj.value.pageNum = 1 getObj.value.pageNum = 1
@ -253,84 +519,85 @@ const detailY = ref({
orderNo: '', orderNo: '',
payStyle: '', payStyle: '',
type: '', type: '',
createTime: ''
startTime:'',
endTime:''
}) })
const getObj = ref({ const getObj = ref({
pageNum: 1, pageNum: 1,
pageSize: 50 pageSize: 50
}) })
const exportExcel = function () {
dialogVisible.value = true
isExport.value = true
}
const exportConfirm = function () {
if (excelData.timegap == '1') {
excelData.startTime = moment().startOf('day').format('YYYY-MM-DD HH:mm:ss')
excelData.endTime = moment().endOf('day').format('YYYY-MM-DD HH:mm:ss')
} else if (excelData.timegap == '3') {
excelData.startTime = moment()
.subtract(3, 'days')
.startOf('day')
.format('YYYY-MM-DD HH:mm:ss')
excelData.endTime = moment().endOf('day').format('YYYY-MM-DD HH:mm:ss')
} else if (excelData.timegap == '7') {
excelData.startTime = moment()
.subtract(7, 'days')
.startOf('day')
.format('YYYY-MM-DD')
excelData.endTime = moment().endOf('day').format('YYYY-MM-DD HH:mm:ss')
} else if (excelData.timegap == '30') {
excelData.startTime = moment()
.subtract(30, 'days')
.startOf('day')
.format('YYYY-MM-DD HH:mm:ss')
excelData.endTime = moment().endOf('day').format('YYYY-MM-DD HH:mm:ss')
}
getInit(
{
sortField: '',
sortOrder: ''
},
(data) => {
console.log('导出数据', data)
//
data = data.map((item) => {
return {
姓名: item.name,
精网号: item.jwcode,
地区: item.deptName,
订单号: item.orderNo,
充值平台: item.payStyle,
金豆数量: item.count,
充值时间: moment(item.successTime).format('YYYY-MM-DD'),
金额: item.price
}
})
if (data.length == 0) {
ElMessage.error('没有数据')
isExport.value = false
dialogVisible.value = false
return
}
console.log('导出数据', data)
excelExport(data)
}
)
}
// const exportExcel = function () {
// dialogVisible.value = true
// isExport.value = true
// }
// const exportConfirm = function () {
// if (excelData.timegap == '1') {
// excelData.startTime = moment().startOf('day').format('YYYY-MM-DD HH:mm:ss')
// excelData.endTime = moment().endOf('day').format('YYYY-MM-DD HH:mm:ss')
// } else if (excelData.timegap == '3') {
// excelData.startTime = moment()
// .subtract(3, 'days')
// .startOf('day')
// .format('YYYY-MM-DD HH:mm:ss')
// excelData.endTime = moment().endOf('day').format('YYYY-MM-DD HH:mm:ss')
// } else if (excelData.timegap == '7') {
// excelData.startTime = moment()
// .subtract(7, 'days')
// .startOf('day')
// .format('YYYY-MM-DD')
// excelData.endTime = moment().endOf('day').format('YYYY-MM-DD HH:mm:ss')
// } else if (excelData.timegap == '30') {
// excelData.startTime = moment()
// .subtract(30, 'days')
// .startOf('day')
// .format('YYYY-MM-DD HH:mm:ss')
// excelData.endTime = moment().endOf('day').format('YYYY-MM-DD HH:mm:ss')
// }
// getInit(
// {
// sortField: '',
// sortOrder: ''
// },
// (data) => {
// console.log('', data)
// //
// data = data.map((item) => {
// return {
// : item.name,
// : item.jwcode,
// : item.deptName,
// : item.orderNo,
// : item.payStyle,
// : item.count,
// : moment(item.successTime).format('YYYY-MM-DD'),
// : item.price
// }
// })
// if (data.length == 0) {
// ElMessage.error('')
// isExport.value = false
// dialogVisible.value = false
// return
// }
// console.log('', data)
// excelExport(data)
// }
// )
// }
//excel //excel
const excelExport = async function (data) {
const worksheet = utils.json_to_sheet(data)
const workbook = utils.book_new()
utils.book_append_sheet(workbook, worksheet, 'Sheet1')
// const excelExport = async function (data) {
// const worksheet = utils.json_to_sheet(data)
// const workbook = utils.book_new()
// utils.book_append_sheet(workbook, worksheet, 'Sheet1')
const wbout = write(workbook, { bookType: 'xlsx', type: 'array' })
saveAs(
new Blob([wbout], { type: 'application/octet-stream' }),
'数据导出.xlsx'
)
isExport.value = false
dialogVisible.value = false
}
// const wbout = write(workbook, { bookType: 'xlsx', type: 'array' })
// saveAs(
// new Blob([wbout], { type: 'application/octet-stream' }),
// '.xlsx'
// )
// isExport.value = false
// dialogVisible.value = false
// }
const ruleFormRef = ref<FormInstance>() const ruleFormRef = ref<FormInstance>()
// //
const getInit = async function ( const getInit = async function (
@ -341,53 +608,67 @@ const getInit = async function (
sortField?: string sortField?: string
sortOrder?: string sortOrder?: string
}, },
callback?: Function
// callback?: Function
) { ) {
try { try {
console.log('搜索参数', getObj.value) console.log('搜索参数', getObj.value)
const [startTime, endTime] = detailY.value.createTime
const startTime = detailY.value.startTime
const endTime = detailY.value.endTime
console.log(startTime, endTime) console.log(startTime, endTime)
// POST // POST
const result = await API({ const result = await API({
url: '/dou/getPay', url: '/dou/getPay',
data: { data: {
pay: { pay: {
jwcode: isExport.value ? excelData.jwcode : detailY.value.jwcode,
deptName: isExport.value ? excelData.area : detailY.value.deptName,
startTime: isExport.value ? excelData.startTime : startTime || '',
endTime: isExport.value ? excelData.endTime : endTime || '',
payStyle: isExport.value ? '' : detailY.value.payStyle,
type: isExport.value ? '' : detailY.value.type,
orderNo: isExport.value ? '' : detailY.value.orderNo,
jwcode: detailY.value.jwcode,
deptName: detailY.value.deptName,
startTime: detailY.value.startTime || '',
endTime: detailY.value.endTime || '',
payStyle: detailY.value.payStyle,
type: detailY.value.type,
orderNo: detailY.value.orderNo,
sortField, sortField,
sortOrder sortOrder
}, },
pageNum: isExport.value ? '' : getObj.value.pageNum,
pageSize: isExport.value ? '' : getObj.value.pageSize
pageNum: getObj.value.pageNum,
pageSize: getObj.value.pageSize
} }
}) })
if (isExport.value) {
!!callback && callback(result.data)
} else {
// if (isExport.value) {
// !!callback && callback(result.data)
// } else {
tableData.value = result.data.list tableData.value = result.data.list
total.value = result.data.total total.value = result.data.total
}
// }
} catch (error) { } catch (error) {
console.log('请求失败', error) console.log('请求失败', error)
// //
} }
} }
// const handleSortChange = (column) => {
// const { prop, order } = column
// if (order === 'ascending') {
// getInit({ sortField: prop, sortOrder: 'ASC' })
// } else if (order === 'descending') {
// getInit({ sortField: prop, sortOrder: 'DESC' })
// }
// }
const handleSortChange = (column) => {
const { prop, order } = column
if (order === 'ascending') {
getInit({ sortField: prop, sortOrder: 'ASC' })
} else if (order === 'descending') {
getInit({ sortField: prop, sortOrder: 'DESC' })
}
}
//
const trim = () => {
if (detailY.value.jwcode) {
detailY.value.jwcode = detailY.value.jwcode.replace(/\s/g, '');
}
if (detailY.value.orderNo) {
detailY.value.orderNo = detailY.value.orderNo.replace(/\s/g, '');
}
if (detailY.value.type) {
detailY.value.type = detailY.value.type.replace(/\s/g, '');
}
}
// //
const search = function () { const search = function () {
trim();
getObj.value.pageNum = 1 getObj.value.pageNum = 1
getInit({}) getInit({})
getCount() getCount()
@ -396,17 +677,7 @@ const search = function () {
const reset = function (formEl) { const reset = function (formEl) {
formEl.resetFields() formEl.resetFields()
} }
//
const getArea = async () => {
try {
const result = await API({
url: '/dou/getPayIp'
})
areaList.value = result.data
} catch (error) {
console.log('请求失败', error)
}
}
// //
const getPayType = async () => { const getPayType = async () => {
try { try {
@ -426,9 +697,9 @@ const getCount = async () => {
url: '/dou/getTotal', url: '/dou/getTotal',
data: { data: {
jwcode: detailY.value.jwcode, jwcode: detailY.value.jwcode,
//deptName: detailY.value.deptName,
startTime: detailY.value.createTime[0],
endTime: detailY.value.createTime[1],
deptName: detailY.value.deptName,
startTime: detailY.value.startTime,
endTime: detailY.value.endTime,
orderNo: detailY.value.orderNo, orderNo: detailY.value.orderNo,
type: detailY.value.type type: detailY.value.type
// payStyle: detailY.value.payStyle // payStyle: detailY.value.payStyle
@ -447,10 +718,14 @@ const getCount = async () => {
console.log('请求失败', error) console.log('请求失败', error)
} }
} }
getInit({})
getArea()
getPayType()
getCount()
onMounted(() => {
getInit({})
getPayType()
getCount()
getArea()
getType()
})
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.filter-box { .filter-box {
@ -483,4 +758,37 @@ getCount()
align-items: center; align-items: center;
margin-top: 10px; margin-top: 10px;
} }
.filter-box {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px;
padding-bottom: 0px;
box-sizing: border-box;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
margin-bottom: 20px;
border-radius: 5px;
.el-form {
display: flex;
flex-wrap: wrap;
row-gap: 20px;
column-gap: 20px;
}
}
.table-box {
width: 100%;
padding: 20px;
box-sizing: border-box;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
border-radius: 5px;
}
.pagination {
display: flex;
align-items: center;
margin-top: 10px;
}
</style> </style>

572
gold-system/src/views/goldBeen/onLineDetail.vue

@ -1,14 +1,19 @@
<template> <template>
<!-- 这是线上充值明细页面 -->
<!-- 这是搜索表单 -->
<div class="filter-box"> <div class="filter-box">
<el-form :model="detailY" ref="ruleFormRef"> <el-form :model="detailY" ref="ruleFormRef">
<el-form-item prop="jwcode" label="精网号">
<el-form-item prop="jwcode">
<el-text class="mx-1" size="large">精网号</el-text>
<el-input <el-input
v-model="detailY.jwcode" v-model="detailY.jwcode"
placeholder="请输入精网号" placeholder="请输入精网号"
style="width: 220px" style="width: 220px"
/> />
</el-form-item> </el-form-item>
<el-form-item prop="deptName" label="地区">
<el-form-item prop="deptName">
<el-text class="mx-1" size="large">地区</el-text>
<el-select <el-select
v-model="detailY.deptName" v-model="detailY.deptName"
placeholder="请选择所属地区" placeholder="请选择所属地区"
@ -23,21 +28,16 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item prop="orderNo" label="订单号">
<el-form-item prop="orderNo">
<el-text class="mx-1" size="large">订单号</el-text>
<el-input <el-input
v-model="detailY.orderNo" v-model="detailY.orderNo"
placeholder="请输入订单号" placeholder="请输入订单号"
style="width: 220px" style="width: 220px"
/> />
</el-form-item> </el-form-item>
<!-- <el-form-item prop="type" label="充值类型">
<el-input
v-model="detailY.type"
placeholder="请输入充值类型"
style="width: 220px"
/>
</el-form-item> -->
<el-form-item prop="payStyle" label="充值平台">
<el-form-item prop="payStyle">
<el-text class="mx-1" size="large">充值平台</el-text>
<el-select <el-select
v-model="detailY.payStyle" v-model="detailY.payStyle"
placeholder="请选择充值平台" placeholder="请选择充值平台"
@ -52,27 +52,45 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item prop="createTime" label="充值时间">
<el-form-item prop="startTime">
<el-text class="mx-1" size="large">开始时间</el-text>
<el-date-picker <el-date-picker
v-model="detailY.createTime"
type="daterange"
start-placeholder="开始日期"
end-placeholder="结束日期"
v-model="detailY.startTime"
type="date"
placeholder="开始日期"
style="width: 240px" style="width: 240px"
format="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
:unlinkPanels="true"
/> />
</el-form-item> </el-form-item>
<el-form-item>
<el-button type="primary" @click="search">查询</el-button>
<el-button type="success" @click="reset(ruleFormRef)">重置</el-button>
<el-button type="primary" @click="exportExcel">导出excel</el-button>
<el-form-item prop="endTime">
<el-text class="mx-1" size="large">结束时间</el-text>
<el-date-picker
v-model="detailY.endTime"
type="date"
placeholder="结束日期"
style="width: 240px"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
/>
<el-button style="margin-left: 10px" @click="getToday()"></el-button>
<el-button @click="getYesterday()"></el-button>
<el-button @click="get7Days()">近7天</el-button>
</el-form-item> </el-form-item>
<el-col :span="10">
<el-form-item>
<el-button type="primary" @click="search">查询</el-button>
<el-button type="success" @click="reset(ruleFormRef)">重置</el-button>
<!-- 这是重置参数formEl: FormInstance -->
<!-- 为啥要这个参数 -->
<el-button type="primary" @click="showExportInfoPanel = true">导出excel</el-button>
</el-form-item>
</el-col>
</el-form> </el-form>
</div> </div>
<div class="table-box"> <div class="table-box">
<p>金豆总数充值金豆总数{{ countValue }}合计金额数:{{ priceValue }}</p>
<div>金豆总数充值金豆总数{{ countValue }}合计金额数{{ priceValue }}</div>
<el-table :data="tableData" style="width: 100%" height="584px"> <el-table :data="tableData" style="width: 100%" height="584px">
<el-table-column type="index" label="序号" width="100px" fixed="left"> <el-table-column type="index" label="序号" width="100px" fixed="left">
<template #default="scope"> <template #default="scope">
@ -85,17 +103,9 @@
<el-table-column fixed="left" prop="jwcode" label="精网号" width="120" /> <el-table-column fixed="left" prop="jwcode" label="精网号" width="120" />
<el-table-column prop="deptName" label="地区" width="120" /> <el-table-column prop="deptName" label="地区" width="120" />
<el-table-column prop="orderNo" label="订单号" width="120" /> <el-table-column prop="orderNo" label="订单号" width="120" />
<el-table-column prop="count" label="金豆数量" width="120">
</el-table-column>
<!-- <el-table-column prop="moneyBuy" label="付费金豆" width="120">
</el-table-column>
<el-table-column prop="moneyFree" label="免费金豆" width="120">
</el-table-column> -->
<el-table-column prop="price" label="金额"></el-table-column>
<!-- <el-table-column prop="type" label="类型"></el-table-column> -->
<el-table-column prop="payStyle" label="充值平台" width="140">
</el-table-column>
<!-- <el-table-column prop="notes" label="备注" width="210"></el-table-column> -->
<el-table-column prop="count" label="金豆数量" width="120" />
<el-table-column prop="price" label="金额" />
<el-table-column prop="payStyle" label="充值平台" width="140" />
<el-table-column <el-table-column
prop="successTime" prop="successTime"
label="充值时间" label="充值时间"
@ -105,7 +115,7 @@
<template #default="scope"> <template #default="scope">
<span>{{ <span>{{
!!scope.row.successTime !!scope.row.successTime
? moment.unix(scope.row.time).format('YYYY-MM-DD HH:mm:ss')
? moment.unix(scope.row.successTime).format('YYYY-MM-DD HH:mm:ss')
: '-' : '-'
}}</span> }}</span>
</template> </template>
@ -125,274 +135,208 @@
</el-pagination> </el-pagination>
</div> </div>
</div> </div>
<!-- 这是导出excel的弹窗 -->
<!-- 导出excel提前展示的信息面板 -->
<el-dialog <el-dialog
v-model="dialogVisible"
title="请选择导出条件"
width="500"
v-model="showExportInfoPanel"
title="导出信息确认"
width="400px"
:close-on-click-modal="false" :close-on-click-modal="false"
@close="
() => {
dialogVisible = false
isExport = false
}
"
> >
<div class="info-panel-header">导出信息</div>
<div v-if="!detailY.jwcode && !detailY.deptName && !detailY.orderNo && !detailY.payStyle && !detailY.startTime && !detailY.endTime">
你正在导出所有数据
</div>
<div v-else>
你正在导出以下数据
</div>
<div v-if="detailY.jwcode">精网号{{ detailY.jwcode || '' }}</div>
<div v-if="detailY.deptName">所属地区{{ detailY.deptName || '' }}</div>
<div v-if="detailY.orderNo">订单号{{ detailY.orderNo || '' }}</div>
<div v-if="detailY.payStyle">充值平台{{ platformList.find(item => item === detailY.payStyle) || '' }}</div>
<div v-if="detailY.startTime || detailY.endTime">
<span>更新时间</span>
<span>{{ detailY.startTime || '无起始时间' }} {{ detailY.endTime || '无结束时间' }}</span>
</div>
<template #footer> <template #footer>
<el-form
ref="ruleFormRef"
style="max-width: 600px"
:model="excelData"
:rules="rules"
label-width="auto"
class="demo-ruleForm"
status-icon
>
<el-form-item prop="activityName" label="精网号:">
<el-input
v-model="excelData.jwcode"
placeholder="请输入精网号"
style="width: 220px"
/>
</el-form-item>
<el-form-item label="所属地区:"
><el-select
v-model="excelData.area"
placeholder="请选择所属地区"
style="width: 240px"
clearable
>
<el-option
v-for="item in areaList"
:key="item"
:label="item"
:value="item"
/>
</el-select>
</el-form-item>
<span class="dialog-footer">
<el-button @click="showExportInfoPanel = false">取消</el-button>
<el-button type="primary" @click="doExportExcel">导出</el-button>
</span>
</template>
</el-dialog>
<el-form-item label="更新时间:">
<el-radio-group v-model="excelData.timegap">
<el-radio value="1">今天</el-radio>
<el-radio value="3">近三天</el-radio>
<el-radio value="7">近一周</el-radio>
<el-radio value="30">近一个月</el-radio>
</el-radio-group>
</el-form-item>
<el-button
type="primary"
size="small"
style="margin-left: 10px"
@click="exportConfirm()"
>确定</el-button
>
</el-form>
<!-- 导出进度弹窗 -->
<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) * totalExport) }} / {{ totalExport }}
</div>
<template #footer>
<el-button type="danger" @click="cancelExport">取消导出</el-button>
</template> </template>
</el-dialog> </el-dialog>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { reactive, ref } from 'vue'
import { reactive, ref, onMounted } from 'vue'
import { FormInstance } from 'element-plus' import { FormInstance } from 'element-plus'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import moment from 'moment' import moment from 'moment'
import API from '@/util/http' import API from '@/util/http'
import { utils, write } from 'xlsx' import { utils, write } from 'xlsx'
import { saveAs } from 'file-saver' import { saveAs } from 'file-saver'
// //
const tableData = ref([]) const tableData = ref([])
//
//
const total = ref(100) const total = ref(100)
const dialogVisible = ref(false)
const excelData = reactive({
jwcode: '',
area: '',
timegap: '',
startTime: '',
endTime: ''
})
const priceValue = ref(0) const priceValue = ref(0)
const countValue = ref(0) const countValue = ref(0)
const areaList = ref<string[]>([]) const areaList = ref<string[]>([])
const isExport = ref<boolean>(false)
const rules = ref({
jwcode: [{ required: true, message: '请输入精网号', trigger: 'blur' }],
area: [{ required: true, message: '请选择所属地区', trigger: 'change' }]
})
const handlePageSizeChange = (val) => {
const platformList = ref<string[]>([])
//
const getToday = () => {
const today = new Date()
//
const startDate = moment(today).startOf('day').format('YYYY-MM-DD HH:mm:ss')
//
const endDate = moment(today).endOf('day').format('YYYY-MM-DD HH:mm:ss')
detailY.value.startTime = startDate
detailY.value.endTime = endDate
search()
}
//
const getYesterday = () => {
const yesterday = moment().subtract(1, 'days')
//
const startDate = yesterday.startOf('day').format('YYYY-MM-DD HH:mm:ss')
//
const endDate = yesterday.endOf('day').format('YYYY-MM-DD HH:mm:ss')
detailY.value.startTime = startDate
detailY.value.endTime = endDate
search()
}
// 7
const get7Days = () => {
//
const startDate = moment().subtract(6, 'days').startOf('day').format('YYYY-MM-DD HH:mm:ss')
//
const endDate = moment().endOf('day').format('YYYY-MM-DD HH:mm:ss')
detailY.value.startTime = startDate
detailY.value.endTime = endDate
search()
}
const handlePageSizeChange = (val: number) => {
getObj.value.pageSize = val getObj.value.pageSize = val
getObj.value.pageNum = 1 getObj.value.pageNum = 1
getInit({}) getInit({})
} }
const handleCurrentChange = function (val) {
const handleCurrentChange = (val: number) => {
getObj.value.pageNum = val getObj.value.pageNum = val
getInit({}) getInit({})
} }
const platformList = ref<string[]>([
// 'stripe',
// 'ios',
// 'FirstData',
// 'paymentasia',
// 'system',
// ''
])
const typeList = ref<string[]>([
'金币换金豆',
'金币换免费金豆',
'赠送金豆',
'购买金豆',
'客服操作'
])
//
//
const detailY = ref({ const detailY = ref({
jwcode: '', jwcode: '',
deptName: '', deptName: '',
orderNo: '', orderNo: '',
payStyle: '', payStyle: '',
type: '',
createTime: ''
startTime: '',
endTime: ''
}) })
const getObj = ref({ const getObj = ref({
pageNum: 1, pageNum: 1,
pageSize: 50 pageSize: 50
}) })
const exportExcel = function () {
dialogVisible.value = true
isExport.value = true
}
const exportConfirm = function () {
if (excelData.timegap == '1') {
excelData.startTime = moment().startOf('day').format('YYYY-MM-DD HH:mm:ss')
excelData.endTime = moment().endOf('day').format('YYYY-MM-DD HH:mm:ss')
} else if (excelData.timegap == '3') {
excelData.startTime = moment()
.subtract(3, 'days')
.startOf('day')
.format('YYYY-MM-DD HH:mm:ss')
excelData.endTime = moment().endOf('day').format('YYYY-MM-DD HH:mm:ss')
} else if (excelData.timegap == '7') {
excelData.startTime = moment()
.subtract(7, 'days')
.startOf('day')
.format('YYYY-MM-DD')
excelData.endTime = moment().endOf('day').format('YYYY-MM-DD HH:mm:ss')
} else if (excelData.timegap == '30') {
excelData.startTime = moment()
.subtract(30, 'days')
.startOf('day')
.format('YYYY-MM-DD HH:mm:ss')
excelData.endTime = moment().endOf('day').format('YYYY-MM-DD HH:mm:ss')
}
getInit(
{
sortField: '',
sortOrder: ''
},
(data) => {
console.log('导出数据', data)
//
data = data.map((item) => {
return {
姓名: item.name,
精网号: item.jwcode,
地区: item.deptName,
订单号: item.orderNo,
充值平台: item.payStyle,
金豆数量: item.count,
充值时间: moment(item.successTime).format('YYYY-MM-DD'),
金额: item.price
}
})
if (data.length == 0) {
ElMessage.error('没有数据')
isExport.value = false
dialogVisible.value = false
return
}
console.log('导出数据', data)
excelExport(data)
}
)
}
//excel
const excelExport = async function (data) {
const worksheet = utils.json_to_sheet(data)
const workbook = utils.book_new()
utils.book_append_sheet(workbook, worksheet, 'Sheet1')
const wbout = write(workbook, { bookType: 'xlsx', type: 'array' })
saveAs(
new Blob([wbout], { type: 'application/octet-stream' }),
'数据导出.xlsx'
)
isExport.value = false
dialogVisible.value = false
}
//
const ruleFormRef = ref<FormInstance>() const ruleFormRef = ref<FormInstance>()
//
const getInit = async function (
//
const getInit = async (
{ {
sortField = '', sortField = '',
sortOrder = '' sortOrder = ''
}: { }: {
sortField?: string sortField?: string
sortOrder?: string sortOrder?: string
},
callback?: Function
) {
}
) => {
try { try {
console.log('搜索参数', getObj.value) console.log('搜索参数', getObj.value)
const [startTime, endTime] = detailY.value.createTime
const startTime = detailY.value.startTime
const endTime = detailY.value.endTime
console.log(startTime, endTime) console.log(startTime, endTime)
// POST // POST
const result = await API({ const result = await API({
url: '/dou/SearchPay', url: '/dou/SearchPay',
data: { data: {
pay: { pay: {
jwcode: isExport.value ? excelData.jwcode : detailY.value.jwcode,
deptName: isExport.value ? excelData.area : detailY.value.deptName,
startTime: isExport.value ? excelData.startTime : startTime || '',
endTime: isExport.value ? excelData.endTime : endTime || '',
payStyle: isExport.value ? '' : detailY.value.payStyle,
// type: isExport.value ? '' : detailY.value.type,
orderNo: isExport.value ? '' : detailY.value.orderNo,
jwcode: detailY.value.jwcode,
deptName: detailY.value.deptName,
startTime: startTime || '',
endTime: endTime || '',
payStyle: detailY.value.payStyle,
orderNo: detailY.value.orderNo,
sortField, sortField,
sortOrder sortOrder
}, },
pageNum: isExport.value ? '' : getObj.value.pageNum,
pageSize: isExport.value ? '' : getObj.value.pageSize
pageNum: getObj.value.pageNum,
pageSize: getObj.value.pageSize
} }
}) })
if (isExport.value) {
!!callback && callback(result.data)
} else {
tableData.value = result.data.list
total.value = result.data.total
}
tableData.value = result.data.list
total.value = result.data.total
} catch (error) { } catch (error) {
console.log('请求失败', error) console.log('请求失败', error)
// //
} }
} }
// const handleSortChange = (column) => {
// const { prop, order } = column
// if (order === 'ascending') {
// getInit({ sortField: prop, sortOrder: 'ASC' })
// } else if (order === 'descending') {
// getInit({ sortField: prop, sortOrder: 'DESC' })
// }
// }
//
const trimJwCode = () => {
if (detailY.value.jwcode) {
detailY.value.jwcode = detailY.value.jwcode.replace(/\s/g, '')
}
if (detailY.value.orderNo) {
detailY.value.orderNo = detailY.value.orderNo.replace(/\s/g, '')
}
}
// //
const search = function () {
const search = () => {
trimJwCode()
getObj.value.pageNum = 1 getObj.value.pageNum = 1
getInit({}) getInit({})
getCount() getCount()
} }
// //
const reset = function (formEl) {
const reset = (formEl: FormInstance) => {
formEl.resetFields() formEl.resetFields()
} }
//
//
const getPayPlatform = async () => { const getPayPlatform = async () => {
try { try {
const result = await API({ const result = await API({
@ -403,7 +347,8 @@ const getPayPlatform = async () => {
console.log('请求失败', error) console.log('请求失败', error)
} }
} }
//
//
const getArea = async () => { const getArea = async () => {
try { try {
const result = await API({ const result = await API({
@ -414,33 +359,39 @@ const getArea = async () => {
console.log('请求失败', error) console.log('请求失败', error)
} }
} }
//
//
const getPayType = async () => { const getPayType = async () => {
try { try {
const result = await API({ const result = await API({
url: '/dou/getStyle' url: '/dou/getStyle'
}) })
platformList.value = result.data platformList.value = result.data
// typeList.value = result.data
} catch (error) { } catch (error) {
console.log('请求失败', error) console.log('请求失败', error)
} }
} }
//
//
const getCount = async () => { const getCount = async () => {
try { try {
// let startTime = ''
// let endTime = ''
// if (Array.isArray(detailY.value.createTime) && detailY.value.createTime.length === 2) {
// [startTime, endTime] = detailY.value.createTime
// }
const result = await API({ const result = await API({
url: '/dou/getRechargeTotal', url: '/dou/getRechargeTotal',
data: { data: {
jwcode: detailY.value.jwcode, jwcode: detailY.value.jwcode,
deptName: detailY.value.deptName, deptName: detailY.value.deptName,
startTime: detailY.value.createTime[0],
endTime: detailY.value.createTime[1],
startTime: detailY.value.startTime,
endTime: detailY.value.endTime,
orderNo: detailY.value.orderNo, orderNo: detailY.value.orderNo,
payStyle: detailY.value.payStyle payStyle: detailY.value.payStyle
} }
}) })
if (!!result.data) {
if (result.data) {
console.log('合计数', result.data) console.log('合计数', result.data)
const { priceTotal, countTotal } = result.data const { priceTotal, countTotal } = result.data
console.log('金豆总数', priceTotal, countTotal) console.log('金豆总数', priceTotal, countTotal)
@ -454,12 +405,144 @@ const getCount = async () => {
console.log('请求失败', error) console.log('请求失败', error)
} }
} }
getInit({})
getArea()
getPayType()
getCount()
getPayPlatform()
//
const showExportInfoPanel = ref(false)
const isExporting = ref(false)
const exportProgress = ref(0)
const totalExport = ref(0)
let allExportData: any[] = []
let cancelToken: any = null
//
const cancelExport = () => {
if (cancelToken) {
cancelToken.cancel('导出已取消')
}
isExporting.value = false
exportProgress.value = 0
allExportData = []
ElMessage.info('导出已取消')
}
// Excel
const doExportExcel = async () => {
try {
isExporting.value = true
exportProgress.value = 0
allExportData = []
// let startTime = ''
// let endTime = ''
// if (Array.isArray(detailY.value.createTime) && detailY.value.createTime.length === 2) {
// [startTime, endTime] = detailY.value.createTime
// }
// startTime = detailY.value.startTime
// endTime = detailY.value.endTime
//
const totalResult = await API({
url: '/dou/SearchPay',
data: {
pay: {
jwcode: detailY.value.jwcode,
deptName: detailY.value.deptName,
startTime: detailY.value.startTime || '',
endTime: detailY.value.endTime || '',
payStyle: detailY.value.payStyle,
orderNo: detailY.value.orderNo
},
pageNum: 1,
pageSize: 1
}
})
totalExport.value = totalResult.data.total
if (totalExport.value === 0) {
ElMessage.error('没有数据可导出')
isExporting.value = false
showExportInfoPanel.value = false
return
}
const pageSize = 1000 // 100
const totalPages = Math.ceil(totalExport.value / pageSize)
for (let page = 1; page <= totalPages; page++) {
if (!isExporting.value) break //
const result = await API({
url: '/dou/SearchPay',
data: {
pay: {
jwcode: detailY.value.jwcode,
deptName: detailY.value.deptName,
startTime: detailY.value.startTime || '',
endTime: detailY.value.endTime || '',
payStyle: detailY.value.payStyle,
orderNo: detailY.value.orderNo
},
pageNum: page,
pageSize: pageSize
}
})
const data = result.data.list
allExportData = allExportData.concat(data)
const exportedCount = allExportData.length
exportProgress.value = Math.round((exportedCount / totalExport.value) * 100)
}
if (isExporting.value) {
//
const exportData = allExportData.map((item, index) => {
return {
序号: index + 1, //
姓名: item.name,
精网号: item.jwcode,
地区: item.deptName,
订单号: item.orderNo,
金豆数量: item.count,
金额: item.price,
充值平台: item.payStyle,
充值时间: !!item.successTime ? moment.unix(item.successTime).format('YYYY-MM-DD HH:mm:ss') : '-'
}
})
const worksheet = utils.json_to_sheet(exportData)
const workbook = utils.book_new()
utils.book_append_sheet(workbook, worksheet, 'Sheet1')
const wbout = write(workbook, { bookType: 'xlsx', type: 'array' })
saveAs(
new Blob([wbout], { type: 'application/octet-stream' }),
'线上充值明细导出.xlsx'
)
isExporting.value = false
showExportInfoPanel.value = false
ElMessage.success('导出成功')
}
} catch (error) {
if (error instanceof Error && error.message === '导出已取消') {
return
}
console.log('导出失败', error)
isExporting.value = false
showExportInfoPanel.value = false
ElMessage.error('导出失败,请稍后重试')
}
}
onMounted(() => {
getInit({})
getArea()
getPayType()
getCount()
getPayPlatform()
})
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.filter-box { .filter-box {
width: 100%; width: 100%;
@ -492,3 +575,8 @@ getPayPlatform()
margin-top: 10px; margin-top: 10px;
} }
</style> </style>
<<<<<<< HEAD
=======
>>>>>>> 703486fc8c3f87173c028d61161e502a2e07fdfc

9
gold-system/src/views/index.vue

@ -1,4 +1,6 @@
<script setup> <script setup>
//
// index
import { ref, onMounted, reactive, computed, watch } from 'vue' import { ref, onMounted, reactive, computed, watch } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import ElementPlus from 'element-plus' import ElementPlus from 'element-plus'
@ -20,6 +22,7 @@ const { currentArea, updateArea } = storeToRefs(areaStore)
const adminData = ref({ const adminData = ref({
name: '' name: ''
}) })
const getAdminData = async function () { const getAdminData = async function () {
try { try {
const result = await API({ url: '/admin/userinfo', data: {} }) const result = await API({ url: '/admin/userinfo', data: {} })
@ -154,7 +157,7 @@ const changeDataByArea = (item) => {
</el-icon> </el-icon>
<span>充值管理</span> <span>充值管理</span>
</template> </template>
<el-menu-item index="/activity">活动管理</el-menu-item>
<!-- <el-menu-item index="/activity">活动管理</el-menu-item> -->
<el-menu-item index="/rate">汇率管理</el-menu-item> <el-menu-item index="/rate">汇率管理</el-menu-item>
</el-sub-menu> </el-sub-menu>
@ -222,7 +225,7 @@ const changeDataByArea = (item) => {
<el-menu-item index="/allRefund">退款明细</el-menu-item> <el-menu-item index="/allRefund">退款明细</el-menu-item>
</el-sub-menu> </el-sub-menu>
</el-sub-menu> </el-sub-menu>
<el-sub-menu index="10">
<!-- <el-sub-menu index="10">
<template #title <template #title
><el-icon> <Folder /> </el-icon></template ><el-icon> <Folder /> </el-icon></template
> >
@ -231,7 +234,7 @@ const changeDataByArea = (item) => {
<el-menu-item index="/onLineDetail">线上充值明细</el-menu-item> <el-menu-item index="/onLineDetail">线上充值明细</el-menu-item>
<el-menu-item index="/goldenBeenConsum">金豆消费明细</el-menu-item> <el-menu-item index="/goldenBeenConsum">金豆消费明细</el-menu-item>
<el-menu-item index="/goldenBeenBalance">客户金豆余额</el-menu-item> <el-menu-item index="/goldenBeenBalance">客户金豆余额</el-menu-item>
</el-sub-menu>
</el-sub-menu> -->
<el-menu-item <el-menu-item
index="/usergold" index="/usergold"
v-if=" v-if="

26
gold-system/src/views/login.vue

@ -49,7 +49,7 @@ const login = async function () {
result.data.permission == '2' || result.data.permission == '2' ||
result.data.permission == '3' result.data.permission == '3'
) { ) {
router.push('/usergold')
router.push('/workspace')
} else if (result.data.permission == '4') { } else if (result.data.permission == '4') {
router.push('/noPermission') router.push('/noPermission')
} }
@ -66,6 +66,8 @@ const login = async function () {
// //
} }
} }
</script> </script>
<template> <template>
<el-row class="login-page"> <el-row class="login-page">
@ -79,14 +81,14 @@ const login = async function () {
<!-- <div style="height: 100vh; width: 1000px" class="container"></div> --> <!-- <div style="height: 100vh; width: 1000px" class="container"></div> -->
<el-col :span="6" :offset="3" class="form"> <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> <el-form-item>
<h1 style="color: #409eff">金币系统登录</h1> <h1 style="color: #409eff">金币系统登录</h1>
</el-form-item> </el-form-item>
<el-form-item prop="jwcode"> <el-form-item prop="jwcode">
<el-input v-model="form.jwcode" placeholder="请输入精网号"></el-input>
<el-input v-model="form.jwcode" placeholder="请输入精网号" @keyup.enter="login"></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="password">
<el-form-item prop="password" @keyup.enter="login">
<el-input <el-input
v-model="form.password" v-model="form.password"
type="password" type="password"
@ -223,3 +225,19 @@ More comprehensive version at shenanigans.shoghisimon.ca/collection/css
background-size: 100% 2px, 100% 100%, 100% 100%; background-size: 100% 2px, 100% 100%, 100% 100%;
} }
</style> </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>
-->

377
gold-system/src/views/managerecharge/activity.vue

@ -1,4 +1,5 @@
<script setup> <script setup>
//
import { ref, onMounted, reactive, computed } from 'vue' import { ref, onMounted, reactive, computed } from 'vue'
import ElementPlus from 'element-plus' import ElementPlus from 'element-plus'
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
@ -25,7 +26,6 @@ const getAdminData = async function () {
} }
} }
//
// //
const tableData = ref([]) const tableData = ref([])
// //
@ -43,19 +43,10 @@ const getObj = ref({
const addObj = ref({ const addObj = ref({
add: '' add: ''
}) })
//
// //
const delObj = ref({}) const delObj = ref({})
// //
// const tableHeight = computed(function () {
// return (getObj.value.pageSize + 1) * 50 + "px";
// });
// ref
const Ref = ref(null)
//
//
//
const get = async function (val) { const get = async function (val) {
try { try {
// //
@ -63,26 +54,34 @@ const get = async function (val) {
getObj.value.pageNum = val getObj.value.pageNum = val
} }
// //
if (getTime.value != null) {
if (getTime.value.startDate != '' && getTime.value.endDate != '') {
activity.value.startDate = getTime.value[0]
activity.value.endDate = getTime.value[1]
}
if (getTime.value.length === 2) {
activity.value.startDate = getTime.value[0]
activity.value.endDate = getTime.value[1]
} else { } else {
activity.value.startDate = ''
activity.value.endDate = ''
activity.value.startDate = null
activity.value.endDate = null
} }
console.log('搜索参数', getObj.value)
const requestData = {
pageNum: getObj.value.pageNum,
pageSize: getObj.value.pageSize,
activity: {
...activity.value,
activityName: activity.value.activityName,
status: activity.value.status
}
};
console.log('搜索参数', requestData)
// POST // POST
const result = await request({ const result = await request({
url: '/recharge/activity/select', url: '/recharge/activity/select',
data: {
...getObj.value,
activity: { ...activity.value }
}
method: 'post',
data: requestData
}) })
//
console.log('响应数据', result);
// //
console.log('请求成功', result) console.log('请求成功', result)
// //
@ -93,227 +92,163 @@ const get = async function (val) {
console.log('total', total.value) console.log('total', total.value)
} catch (error) { } catch (error) {
console.log('请求失败', error) console.log('请求失败', error)
//
ElMessage.error('请求失败')
}
}
//
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 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 trim = () => {
if (activity.value.activityName) {
activity.value.activityName = activity.value.activityName.replace(/\s/g, '');
} }
} }
// //
const search = function () { const search = function () {
trim();
getObj.value.pageNum = 1 getObj.value.pageNum = 1
get() get()
} }
// //
const reset = function () { const reset = function () {
getObj.value = {}
getObj.value.pageNum = 1
getObj.value.pageSize = 10
getTime.value = {}
getObj.value = {
pageNum: 1,
pageSize: 10
}
getTime.value = []
activity.value = {} activity.value = {}
} }
//
//
onMounted(async function () {
await getAdminData()
get()
})
// false
const addActivityVisible = ref(false) const addActivityVisible = ref(false)
//
const openAddActivityVisible = function () {
addActivityVisible.value = true
}
//
const closeAddActivityVisible = function (done) {
addActivityVisible.value = false
}
//
const addActicity = function () {
console.log('Date', new Date())
//
addObj.value = {}
addObj.value.adminId = adminData.value.adminId
addObj.value.adminName = adminData.value.name
addObj.value.freeGold = '0'
addObj.value.rechargeRatio = 0
addObj.value.startTime = null
addObj.value.endTime = null
openAddActivityVisible()
}
//
const add = async function () {
Ref.value.validate(async (valid) => {
console.log('valid', valid)
if (valid) {
try {
console.log('添加对象', addObj.value)
// POST
const result = await request({
url: '/recharge/activity/add',
data: addObj.value
})
// addActivity
const addActivity = () => {
console.log('点击了新增活动按钮');
// addActivityVisible true
addActivityVisible.value = true;
};
//
console.log('请求成功', result)
//
get()
//
closeAddActivityVisible()
//
ElMessage({
type: 'success',
message: '活动添加成功!'
})
} catch (error) {
console.log('请求失败', error)
//
}
} else {
//
ElMessage({
type: 'error',
message: '请检查输入内容'
})
}
})
}
// 使 _.throttle trailing false
const throttledAdd = _.throttle(add, 5000, { trailing: false })
//
// let onceFunction = true;
//
// const throttledAdd = (...args) => {
// if (onceFunction) {
// add.apply(null, args);
// onceFunction = false; // false
// timer = setTimeout(() => {
// onceFunction = true; //
// timer = null;
// }, 1000); // 10001
// }
// };
// =========================================================
//
const del = function (row) {
delObj.value.activityId = row.activityId
console.log('delObj', delObj.value)
}
//
const delConfirm = async function () {
try {
console.log('delObj', delObj.value)
// POST
const result = await request({
url: '/recharge/activity/edit',
data: delObj.value
})
if (result.code == 200) {
ElMessage({
type: 'success',
message: '删除成功'
})
//
console.log('请求成功', result)
//
get()
} else {
ElMessage({
type: 'error',
message: '删除失败'
})
}
} catch (error) {
console.log('请求失败', error)
//
}
}
//
const closeAddActivityVisible = () => {
addActivityVisible.value = false;
};
//
const handlePageSizeChange = function (val) { const handlePageSizeChange = function (val) {
getObj.value.pageSize = val getObj.value.pageSize = val
get() get()
} }
//
const handleCurrentChange = function (val) { const handleCurrentChange = function (val) {
getObj.value.pageNum = val getObj.value.pageNum = val
get() get()
} }
//
//
const handleStartTimeChange = () => {
Ref.value.validateField('endTime')
}
const checkFreeGoldRadio = function (rule, value, callback) {
if (addObj.value.freeGold == 1) {
if (value == '0' || value == null || value == '') {
callback(new Error('请输入免费金币兑换比'))
} else if (value < 0 || isNaN(value)) {
callback(new Error('请输入正确的格式'))
} else {
callback()
}
} else {
callback()
}
}
const checkStartTime = function (rule, value, callback) {
if (value < new Date()) {
callback(new Error('开始时间不能小于当前时间'))
} else {
callback()
}
}
//
const throttledAdd = async () => {
try {
// 'add'
const { add, ...validData } = addObj.value;
const checkEndTime = function (rule, value, callback) {
if (value < new Date()) {
callback(new Error('结束时间不能小于当前时间'))
} else if (value <= addObj.value.startTime) {
callback(new Error('结束时间不能小于开始时间'))
} else {
callback()
// POST
const result = await request({
url: '/recharge/activity/add', //
method: 'post',
data: validData
})
console.log('新增活动成功', result)
ElMessage.success('新增活动成功')
//
closeAddActivityVisible()
//
get()
} catch (error) {
console.log('新增活动失败', error)
ElMessage.error('新增活动失败')
} }
} }
const rules = reactive({
activityName: [
{ required: true, message: '请输入活动名称', trigger: 'blur' }
],
freeGold: [
{ required: true, message: '请选择是否赠送免费金币', trigger: 'blur' }
],
rechargeRatio: [{ validator: checkFreeGoldRadio, trigger: 'blur' }],
startTime: [
{ required: true, message: '请选择开始时间', trigger: 'blur' },
{ validator: checkStartTime, trigger: 'blur' }
],
endTime: [
{ required: true, message: '请选择结束时间', trigger: 'blur' },
{ validator: checkEndTime, trigger: 'blur' }
]
})
//
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: '请检查输入内容'
//
const delConfirm = async (row) => {
try {
delObj.value = row
//
const result = await request({
url: '/recharge/activity/edit', //
method: 'post',
data: delObj.value
}) })
console.log('删除活动成功', result)
ElMessage.success('删除活动成功')
//
get()
} catch (error) {
console.log('删除活动失败', error)
ElMessage.error('删除活动失败')
} }
} }
//
onMounted(async function () {
await getAdminData()
get()
})
//
const del = (row) => {
delObj.value = row
}
</script> </script>
<template> <template>
@ -339,9 +274,14 @@ onMounted(async function () {
start-placeholder="起始时间" start-placeholder="起始时间"
end-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> </div>
<div class="head-card-btn"> <div class="head-card-btn">
<el-button @click="reset()">重置</el-button>
<el-button type="success" @click="reset()">重置</el-button>
<el-button type="primary" @click="search()">查询</el-button> <el-button type="primary" @click="search()">查询</el-button>
</div> </div>
</div> </div>
@ -354,13 +294,13 @@ onMounted(async function () {
<div> <div>
<el-button <el-button
plain plain
@click="addActicity()"
@click="addActivity()"
style="color: #048efb; border: 1px solid #048efb" style="color: #048efb; border: 1px solid #048efb"
>新增活动</el-button >新增活动</el-button
> >
</div> </div>
<div> <div>
<el-table :data="tableData" :height="tableHeight" style="width: 100%">
<el-table :data="tableData" style="width: 100%">
<el-table-column <el-table-column
type="index" type="index"
label="序号" label="序号"
@ -384,6 +324,7 @@ onMounted(async function () {
{{ moment(scope.row.endTime).format('YYYY-MM-DD HH:mm:ss') }} {{ moment(scope.row.endTime).format('YYYY-MM-DD HH:mm:ss') }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="rechargeRatio" label="免费兑换比"> <el-table-column prop="rechargeRatio" label="免费兑换比">
<template #default="scope"> <template #default="scope">
<span>{{ scope.row.rechargeRatio }}:1</span> <span>{{ scope.row.rechargeRatio }}:1</span>
@ -421,7 +362,7 @@ onMounted(async function () {
<template #default="scope"> <template #default="scope">
<el-popconfirm <el-popconfirm
title="确定将此条活动删除吗?" title="确定将此条活动删除吗?"
@confirm="delConfirm"
@confirm="delConfirm(delObj.value)"
> >
<template #reference> <template #reference>
<el-button type="primary" text @click="del(scope.row)"> <el-button type="primary" text @click="del(scope.row)">
@ -445,7 +386,7 @@ onMounted(async function () {
<el-pagination <el-pagination
background background
:page-size="getObj.pageSize" :page-size="getObj.pageSize"
:page-sizes="[5, 10, 20, 50, 100]"
:page-sizes="[5, 10, 20, 50]"
layout="total, sizes, prev, pager, next, jumper" layout="total, sizes, prev, pager, next, jumper"
:total="total" :total="total"
@size-change="handlePageSizeChange" @size-change="handlePageSizeChange"

175
gold-system/src/views/managerecharge/rate.vue

@ -22,7 +22,7 @@ const getAdminData = async function () {
rateAdd.value.adminId = adminData.value.adminId rateAdd.value.adminId = adminData.value.adminId
rateEdit.value.adminId = adminData.value.adminId rateEdit.value.adminId = adminData.value.adminId
console.log('请求成功', result) console.log('请求成功', result)
console.log('用户信息', user.value)
// console.log('', user.value)
} catch (error) { } catch (error) {
console.log('请求失败', error) console.log('请求失败', error)
} }
@ -31,7 +31,6 @@ getAdminData()
const regeAdd = ref(false) const regeAdd = ref(false)
const regeEdit = ref(false) const regeEdit = ref(false)
// //
const tableData = ref([]) const tableData = ref([])
// //
@ -39,64 +38,99 @@ const getObj = ref({
pageNum: 1, pageNum: 1,
pageSize: 10 pageSize: 10
}) })
const total = ref(0) const total = ref(0)
// //
//
const value1 = ref({
startTime: '',
endTime: ''
}) //
function handleDateChange(value) {
if (value && value.length === 2) {
value1.value.startTime = value[0] //
value1.value.endTime = value[1] //
}
console.log(value1)
}
//
// const value1 = ref([]) //
// function handleDateChange(value) {
// if (value && value.length === 2) {
// value1.value.startTime = value[0] //
// value1.value.endTime = value[1] //
// }
// console.log(value1)
// }
const time = ref({}) const time = ref({})
const get = async function (val) { const get = async function (val) {
// //
if (value1.value != null) {
if (value1.value.startDate != '' && value1.value.endDate != '') {
time.value.startTime = value1.value[0]
time.value.endTime = value1.value[1]
}
} else {
time.value.startTime = ''
time.value.endTime = ''
}
// if (value1.value && value1.value.length === 2) {
// time.value.startTime = value1.value[0];
// time.value.endTime = value1.value[1];
// } else {
// time.value.startTime = '';
// time.value.endTime = '';
// }
try { try {
// //
if (typeof val === 'number') { if (typeof val === 'number') {
getObj.value.pageNum = val
getObj.value.pageNum = val;
} }
console.log('搜索参数', getObj.value)
console.log('搜索参数', {
...getObj.value,
rate: { ...time.value }
});
// POST // POST
const result = await request({ const result = await request({
url: '/rates/search', url: '/rates/search',
method: 'POST',
data: { data: {
...getObj.value, ...getObj.value,
rate: { ...time.value } rate: { ...time.value }
} }
})
});
// //
console.log('请求成功', result)
console.log('请求成功', result);
// //
tableData.value = result.data.list
console.log('tableData', tableData.value)
// UI
tableData.value = result.data.list;
console.log('tableData', tableData.value);
// //
total.value = result.data.total
console.log('total', total.value)
total.value = result.data.total;
console.log('total', total.value);
} catch (error) { } catch (error) {
console.log('请求失败', error)
//
console.log('请求失败', error);
ElMessage.error('请求失败');
} }
} }
//
const getToday = () => {
const today = new Date()
//
const startDate = moment(today).startOf('day').format('YYYY-MM-DD HH:mm:ss')
//
const endDate = moment(today).endOf('day').format('YYYY-MM-DD HH:mm:ss')
time.value.startTime = startDate
time.value.endTime = endDate
search()
}
//
const getYesterday = () => {
const yesterday = moment().subtract(1, 'days')
//
const startDate = yesterday.startOf('day').format('YYYY-MM-DD HH:mm:ss')
//
const endDate = yesterday.endOf('day').format('YYYY-MM-DD HH:mm:ss')
time.value.startTime = startDate
time.value.endTime = endDate
search()
}
// 7
const get7Days = () => {
//
const startDate = moment().subtract(6, 'days').startOf('day').format('YYYY-MM-DD HH:mm:ss')
//
const endDate = moment().endOf('day').format('YYYY-MM-DD HH:mm:ss')
time.value.startTime = startDate
time.value.endTime = endDate
search()
}
// //
const search = function () { const search = function () {
getObj.value.pageNum = 1 getObj.value.pageNum = 1
@ -129,6 +163,11 @@ const addRate = async function () {
}) })
if (result.code == 0) { if (result.code == 0) {
ElMessage.error(result.msg) ElMessage.error(result.msg)
}else{
ElMessage({
type: 'success',
message: '新增汇率成功'
})
} }
// //
console.log('请求成功', result) console.log('请求成功', result)
@ -454,30 +493,50 @@ function handleInput(value) {
<el-card> <el-card>
<!-- 这是时间 --> <!-- 这是时间 -->
<div class="demo-range"> <div class="demo-range">
时间
<el-date-picker
v-model="value1"
type="daterange"
range-separator="至"
start-placeholder="开始时间"
end-placeholder="结束时间"
:size="size"
value-format="YYYY-MM-DD"
/>
<!-- 按钮 -->
<el-button
class="button-item"
type="primary"
style="float: right"
@click="search()"
>查询</el-button
>
<el-button
class="button-item"
style="float: right"
@click="handledelete"
>重置</el-button
>
<el-row>
<el-col :span="6">
<el-form-item prop="startTime">
<el-text class="mx-1" size="large">开始时间</el-text>
<el-date-picker
v-model="time.startTime"
type="date"
placeholder="开始日期"
style="width: 210px"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item prop="endTime">
<el-text class="mx-1" size="large">结束时间</el-text>
<el-date-picker
v-model="time.endTime"
type="date"
placeholder="结束日期"
style="width: 210px"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
/>
</el-form-item>
</el-col>
<el-col :span="4">
<el-button @click="getToday"></el-button>
<el-button @click="getYesterday"></el-button>
<el-button @click="get7Days">近7天</el-button>
</el-col>
<el-col :span="4">
<el-button
type="primary"
@click="search"
>查询</el-button>
<el-button
class="button-item"
type="success"
@click="handledelete"
>重置</el-button>
</el-col>
</el-row>
</div> </div>
</el-card> </el-card>
</el-col> </el-col>

12
gold-system/src/views/permissions/index.vue

@ -62,8 +62,15 @@ const get = async function (val) {
console.log('请求失败', error) console.log('请求失败', error)
} }
} }
//
const trimJwCode = () => {
if (admin.value.jwcode) {
admin.value.jwcode = admin.value.jwcode.replace(/\s/g, '');
}
}
// //
const search = function () { const search = function () {
trimJwCode();
getObj.value.pageNum = 1 getObj.value.pageNum = 1
get() get()
} }
@ -466,7 +473,7 @@ const handleCurrentChange = function (val) {
</div> </div>
<div class="head-card-btn"> <div class="head-card-btn">
<el-button @click="reset()">重置</el-button>
<el-button type="success" @click="reset()">重置</el-button>
<el-button type="primary" @click="search()">查询</el-button> <el-button type="primary" @click="search()">查询</el-button>
</div> </div>
</div> </div>
@ -524,7 +531,7 @@ const handleCurrentChange = function (val) {
修改权限 修改权限
</el-button> </el-button>
<el-popconfirm <el-popconfirm
title="确定将此条活动删除吗?"
title="确定将此用户删除吗?"
@confirm="delConfirm" @confirm="delConfirm"
> >
<template #reference> <template #reference>
@ -862,6 +869,7 @@ const handleCurrentChange = function (val) {
</template> </template>
<style scoped> <style scoped>
.permissionVisible { .permissionVisible {
font-size: 16px; font-size: 16px;
font-weight: bold; font-weight: bold;

230
gold-system/src/views/recharge/addRecharge.vue

@ -9,7 +9,12 @@ import moment from 'moment'
import { range, re } from 'mathjs' import { range, re } from 'mathjs'
import { utils, read } from 'xlsx' import { utils, read } from 'xlsx'
import throttle from 'lodash/throttle' import throttle from 'lodash/throttle'
//
const trimJwCode = () => {
if (addRecharge.value.jwcode) {
addRecharge.value.jwcode = addRecharge.value.jwcode.replace(/\s/g, '');
}
}
// //
const beforeAvatarUpload = (file) => { const beforeAvatarUpload = (file) => {
const isJPG = file.type === 'image/jpeg' const isJPG = file.type === 'image/jpeg'
@ -127,26 +132,53 @@ const rules = reactive({
jwcode: [{ required: true, message: '请输入精网号', trigger: 'blur' }], jwcode: [{ required: true, message: '请输入精网号', trigger: 'blur' }],
activityId: [{ required: true, message: '请选择活动名称', trigger: 'blur' }], activityId: [{ required: true, message: '请选择活动名称', trigger: 'blur' }],
paidGold: [ paidGold: [
{ required: true, message: '请输入充值金额', trigger: 'blur' },
{ required: true, message: '请输入永久金币数', trigger: 'blur' },
{ {
validator: (rule, value, callback) => { validator: (rule, value, callback) => {
if (value > 0) {
if (value >= 0) {
callback() callback()
} else { } else {
callback(new Error('输入大于0的金额'))
callback(new Error('输入金额至少为0'))
} }
} }
} }
], ],
//
rechargeGold: [
freeGold: [
{ {
required: true, required: true,
message: '请选择充值方式',
message: '请输入免费金币数',
trigger: 'blur'
},
{
validator: (rule, value, callback) => {
// ()
//
const numValue = Number(value);
if (isNaN(numValue)) {
callback(new Error('请输入有效的数字'));
} else if (numValue >= 0) {
callback();
} else {
callback(new Error('输入金额至少为 0'));
}
},
trigger: 'blur' trigger: 'blur'
} }
], ],
//
rechargeGold: [
{
required: true,message: '请选择充值方式',trigger: 'blur'
},{
validator: (rule, value, callback) => {
if (value >= 0) {
callback()
} else {
callback(new Error('输入金额至少为0'))
}
}
}
],
payWay: [{ required: true, message: '请选择付款方式', trigger: 'blur' }], payWay: [{ required: true, message: '请选择付款方式', trigger: 'blur' }],
rechargeTime: [{ required: true, message: '请选择交款时间', trigger: 'blur' }] rechargeTime: [{ required: true, message: '请选择交款时间', trigger: 'blur' }]
}) })
@ -154,12 +186,14 @@ const rules = reactive({
// //
const user = ref({}) const user = ref({})
const getUser = async function (jwcode) { const getUser = async function (jwcode) {
trimJwCode();
try { try {
// POST // POST
const result = await API({ const result = await API({
url: '/recharge/user', url: '/recharge/user',
data: { data: {
jwcode: jwcode,
jwcode: addRecharge.value.jwcode,
area: adminData.value.area area: adminData.value.area
} }
}) })
@ -238,28 +272,20 @@ const handleAvatarSuccess = (response, uploadFile) => {
// //
const options = [ const options = [
{ {
value: '微信',
label: '微信'
value: '现金',
label: '现金'
}, },
{ {
value: '支付宝',
label: '支付宝'
value: '支',
label: '支'
}, },
{ {
value: '银联',
label: '银联'
value: '刷卡',
label: '刷卡'
}, },
{ {
value: '信用卡',
label: '信用卡'
},
{
value: '借记卡',
label: '借记卡'
},
{
value: '现金充值',
label: '现金充值'
value: '其他(各地区电子支付)',
label: '其他(各地区电子支付)'
} }
] ]
@ -286,23 +312,23 @@ function handleActivityChange(value) {
console.log('看看', addRecharge.value) console.log('看看', addRecharge.value)
} }
// paidGold // paidGold
const calculatedFree = computed(() => {
const result = addRecharge.value.paidGold / addRecharge.value.rechargeRatio
if (isNaN(result) || result < 1 || addRecharge.value.rechargeRatio == 0) {
return 0
} else {
return Math.trunc(result)
}
})
watch(calculatedFree, (newVal) => {
addRecharge.value.freeGold = newVal
})
const calculatedRecharge = computed(() => {
return addRecharge.value.paidGold * Rate.value
})
watch(calculatedRecharge, (newVal) => {
addRecharge.value.rechargeGold = newVal
})
// const calculatedFree = computed(() => {
// const result = addRecharge.value.paidGold / addRecharge.value.rechargeRatio
// if (isNaN(result) || result < 1 || addRecharge.value.rechargeRatio == 0) {
// return 0
// } else {
// return Math.trunc(result)
// }
// })
// watch(calculatedFree, (newVal) => {
// addRecharge.value.freeGold = newVal
// })
// const calculatedRecharge = computed(() => {
// return addRecharge.value.paidGold * Rate.value
// })
// watch(calculatedRecharge, (newVal) => {
// addRecharge.value.rechargeGold = newVal
// })
// //
const deleteRecharge = function () { const deleteRecharge = function () {
addRecharge.value = { addRecharge.value = {
@ -541,55 +567,6 @@ const batchDel = function () {
}) })
}) })
} }
//
const del = function (row) {
console.log('row===', row)
delObj.value.line = row.line
}
//
const delConfirm = function () {
batchData.value = batchData.value.filter(
(item) => item.line != delObj.value.line
)
console.log('batchData===', batchData.value)
}
//
const reset = function (row) {
resetObj.value.line = row.line
}
//
const resetConfirm = function () {
for (let i = 0; i < batchData.value.length; i++) {
if (batchData.value[i].line == resetObj.value.line) {
batchData.value[i] = {}
batchData.value[i].line = resetObj.value.line
batchData.value[i].showInput = true
break
}
}
}
//
const cancelBatch = function () {
ElMessageBox.confirm('确认取消吗?此操作将不会保存任何数据。', '确认取消', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(() => {
batchData.value = [{ line: 1, showInput: true }]
closeBatchRechargeVisible()
ElMessage({
type: 'success',
message: '操作成功'
})
})
.catch(() => {
ElMessage({
type: 'info',
message: '操作撤销'
})
})
}
// //
const changeActivity = function (row) { const changeActivity = function (row) {
console.log('row===', row) console.log('row===', row)
@ -611,36 +588,36 @@ const changeActivity = function (row) {
} }
} }
} }
//
const changePaidGold = function (row) {
console.log('row===', row)
let ratio = 0
if (row.activityId == null || row.activityId == '') {
row.freeGold = 0
} else {
for (let i = 0; i < activity.value.length; i++) {
if (activity.value[i].activityId == row.activityId) {
ratio = activity.value[i].rechargeRatio
break
}
}
if (ratio == 0) {
row.freeGold = 0
} else {
row.freeGold = Math.ceil(Number(row.paidGold) / ratio)
}
}
let rate = row.rate
if (rate == null || rate == '') {
row.rechargeGold = 0
} else {
if (row.paidGold == null || row.paidGold == '') {
row.rechargeGold = 0
} else {
row.rechargeGold = Math.ceil(Number(row.paidGold) * rate)
}
}
}
// //
// const changePaidGold = function (row) {
// console.log('row===', row)
// let ratio = 0
// if (row.activityId == null || row.activityId == '') {
// row.freeGold = 0
// } else {
// for (let i = 0; i < activity.value.length; i++) {
// if (activity.value[i].activityId == row.activityId) {
// ratio = activity.value[i].rechargeRatio
// break
// }
// }
// if (ratio == 0) {
// row.freeGold = 0
// } else {
// row.freeGold = Math.ceil(Number(row.paidGold) / ratio)
// }
// }
// let rate = row.rate
// if (rate == null || rate == '') {
// row.rechargeGold = 0
// } else {
// if (row.paidGold == null || row.paidGold == '') {
// row.rechargeGold = 0
// } else {
// row.rechargeGold = Math.ceil(Number(row.paidGold) * rate)
// }
// }
// }
// //
const changeRate = function (row) { const changeRate = function (row) {
console.log('row===', row) console.log('row===', row)
@ -924,6 +901,7 @@ onMounted(async function () {
type="primary" type="primary"
@click="getUser(addRecharge.jwcode)" @click="getUser(addRecharge.jwcode)"
style="margin-left: 20px" style="margin-left: 20px"
>查询</el-button >查询</el-button
> >
</el-form-item> </el-form-item>
@ -1036,7 +1014,7 @@ onMounted(async function () {
placeholder="提交人姓名" placeholder="提交人姓名"
/> />
</el-form-item> </el-form-item>
<el-button @click="deleteRecharge" style="margin-left: 280px"
<el-button @click="deleteRecharge" style="margin-left: 280px" type="success"
>重置</el-button >重置</el-button
> >
<el-button type="primary" @click="addBefore"> 提交 </el-button> <el-button type="primary" @click="addBefore"> 提交 </el-button>
@ -1106,12 +1084,12 @@ onMounted(async function () {
<p style="color: #2fa1ff">{{ user.rechargeTimes }}</p> <p style="color: #2fa1ff">{{ user.rechargeTimes }}</p>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="10">
<!-- <el-col :span="10">
<el-form-item label="负责客服"> <el-form-item label="负责客服">
<p>{{ adminData.name }}</p> <p>{{ adminData.name }}</p>
</el-form-item> </el-form-item>
</el-col>
<el-col :span="14">
</el-col> -->
<el-col :span="10">
<el-form-item label="消费次数"> <el-form-item label="消费次数">
<p style="color: #2fa1ff">{{ user.spendTimes }}</p> <p style="color: #2fa1ff">{{ user.spendTimes }}</p>
</el-form-item> </el-form-item>
@ -1389,7 +1367,7 @@ onMounted(async function () {
@confirm="resetConfirm" @confirm="resetConfirm"
> >
<template #reference> <template #reference>
<el-button type="primary" text @click="reset(scope.row)">
<el-button type="success" text @click="reset(scope.row)">
重置 重置
</el-button> </el-button>
</template> </template>

2
gold-system/src/views/recharge/adminRecharge.vue

@ -517,7 +517,7 @@ const handleSortChange = (column) => {
</el-col> </el-col>
<el-col :span="3"> <el-col :span="3">
<div class="head-card-btn"> <div class="head-card-btn">
<el-button @click="reset()">重置</el-button>
<el-button type="success" @click="reset()">重置</el-button>
<el-button type="primary" @click="search()">查询</el-button> <el-button type="primary" @click="search()">查询</el-button>
</div> </div>
</el-col> </el-col>

320
gold-system/src/views/recharge/allRecharge.vue

@ -1,11 +1,16 @@
<script setup> <script setup>
import { ref, onMounted, reactive, computed } from 'vue'
import { ref, onMounted, reactive, computed, nextTick } from 'vue'
import ElementPlus from 'element-plus' import ElementPlus from 'element-plus'
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import { AiFillRead } from 'vue-icons-plus/ai' import { AiFillRead } from 'vue-icons-plus/ai'
import axios from 'axios' import axios from 'axios'
import moment from 'moment' import moment from 'moment'
import API from '@/util/http' import API from '@/util/http'
import * as XLSX from 'xlsx' // xlsx
// XLSX
const { utils, writeFile } = XLSX
// //
// //
const adminData = ref({}) const adminData = ref({})
@ -23,7 +28,14 @@ const getAdminData = async function () {
const tableData = ref([]) const tableData = ref([])
// ====================================== // ======================================
// rechargeVo // rechargeVo
const rechargeVo = ref({})
const rechargeVo = ref({
activityId: '',
rechargeWay: '',
area: '',
startDate: '',
endDate: '',
status: ''
})
// //
const getObj = ref({ const getObj = ref({
pageNum: 1, pageNum: 1,
@ -57,14 +69,8 @@ const getPayWay = async function () {
} }
} }
// //
// const tableHeight = computed(function () {
// return (getObj.value.pageSize + 2) * 60 + "px";
// });
// //
// //
//
const trueGold = ref(0) const trueGold = ref(0)
const trueRGold = ref(0) const trueRGold = ref(0)
const trueFGold = ref(0) const trueFGold = ref(0)
@ -100,7 +106,7 @@ const get = async function (val) {
} }
// //
if (getTime.value != null) { if (getTime.value != null) {
if (getTime.value.startDate != '' && getTime.value.endDate != '') {
if (getTime.value[0] && getTime.value[1]) {
rechargeVo.value.startDate = getTime.value[0] rechargeVo.value.startDate = getTime.value[0]
rechargeVo.value.endDate = getTime.value[1] rechargeVo.value.endDate = getTime.value[1]
} }
@ -194,7 +200,7 @@ const reset = function () {
rechargeVo.value.endDate = '' rechargeVo.value.endDate = ''
sortField.value = '' sortField.value = ''
sortOrder.value = '' sortOrder.value = ''
getTime.value = {}
getTime.value = []
} }
// //
const getToday = function () { const getToday = function () {
@ -204,15 +210,21 @@ const getToday = function () {
today.getMonth(), today.getMonth(),
today.getDate() today.getDate()
) )
// 23:59:59
const endDate = new Date( const endDate = new Date(
today.getFullYear(), today.getFullYear(),
today.getMonth(), today.getMonth(),
today.getDate() + 1
today.getDate(),
23, 59, 59
) )
getTime.value = [startDate, endDate] getTime.value = [startDate, endDate]
//
rechargeVo.value.startDate = moment(startDate).format('YYYY-MM-DD HH:mm:ss')
rechargeVo.value.endDate = moment(endDate).format('YYYY-MM-DD HH:mm:ss')
console.log('getTime', getTime.value) console.log('getTime', getTime.value)
get() get()
} }
// //
const getYesterday = function () { const getYesterday = function () {
const yesterday = new Date() const yesterday = new Date()
@ -222,15 +234,21 @@ const getYesterday = function () {
yesterday.getMonth(), yesterday.getMonth(),
yesterday.getDate() yesterday.getDate()
) )
// 23:59:59
const endDate = new Date( const endDate = new Date(
yesterday.getFullYear(), yesterday.getFullYear(),
yesterday.getMonth(), yesterday.getMonth(),
yesterday.getDate() + 1
yesterday.getDate(),
23, 59, 59
) )
getTime.value = [startDate, endDate] getTime.value = [startDate, endDate]
//
rechargeVo.value.startDate = moment(startDate).format('YYYY-MM-DD HH:mm:ss')
rechargeVo.value.endDate = moment(endDate).format('YYYY-MM-DD HH:mm:ss')
console.log('getTime', getTime.value) console.log('getTime', getTime.value)
get() get()
} }
// 7 // 7
const get7Days = function () { const get7Days = function () {
const today = new Date() const today = new Date()
@ -239,12 +257,17 @@ const get7Days = function () {
today.getMonth(), today.getMonth(),
today.getDate() - 6 today.getDate() - 6
) )
// 23:59:59
const endDate = new Date( const endDate = new Date(
today.getFullYear(), today.getFullYear(),
today.getMonth(), today.getMonth(),
today.getDate() + 1
today.getDate(),
23, 59, 59
) )
getTime.value = [startDate, endDate] getTime.value = [startDate, endDate]
//
rechargeVo.value.startDate = moment(startDate).format('YYYY-MM-DD HH:mm:ss')
rechargeVo.value.endDate = moment(endDate).format('YYYY-MM-DD HH:mm:ss')
console.log('getTime', getTime.value) console.log('getTime', getTime.value)
get() get()
} }
@ -314,7 +337,6 @@ const getActivity = async function () {
} }
} }
// //
//
const getArea = async function () { const getArea = async function () {
console.log('888888888880000000') console.log('888888888880000000')
try { try {
@ -364,10 +386,10 @@ onMounted(async function () {
getAdminData() getAdminData()
get() get()
getActivity() getActivity()
getPayWay() getPayWay()
getArea()
}) })
getArea()
const handlePageSizeChange = function (val) { const handlePageSizeChange = function (val) {
getObj.value.pageSize = val getObj.value.pageSize = val
get() get()
@ -397,6 +419,207 @@ const handleSortChange = (column) => {
sortOrder.value = column.order === 'ascending' ? 'ASC' : 'DESC' sortOrder.value = column.order === 'ascending' ? 'ASC' : 'DESC'
get() 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 platformMap = {
// 0: '',
// 1: 'ERP',
// 2: 'Homily Chart',
// 3: 'Homily Link',
// 4: ''
// };
// const updateTypeMap = {
// 0: '',
// 1: '',
// 2: '退',
// 3: ''
// };
//
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: '/recharge/recharge',
method: 'post',
data: {
pageNum: 1,
pageSize,
rechargeVo: { ...rechargeVo.value }
}
})
totalRecords = firstResult.data.total
//
const CancelToken = axios.CancelToken
exportCancelToken.value = CancelToken.source()
//
const firstData = firstResult.data.list
if (firstData.length) {
const rows = firstData.map((row, index) => [
totalExported + index + 1,
row.username || '',
row.jwcode || '',
row.area || '',
row.activityName || '',
// currencyName
row.currencyName || '',
(row.paidGold / 100).toFixed(2) || '0.00',
row.rechargeWay || '',
(row.paidGold / 100).toFixed(2) || '0.00',
(row.freeGold / 100).toFixed(2) || '0.00',
row.remark || '',
row.payWay || '',
row.name || '',
//
row.status === 1 ? '已通过' : row.status === 0 ? '待审核' : row.status === 2 ? '已驳回' : '',
row.reson || '',
moment(row.rechargeTime).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: '/recharge/recharge',
method: 'post',
data: {
pageNum: page,
pageSize,
rechargeVo: { ...rechargeVo.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 || '',
row.activityName || '',
// currencyName
row.currencyName || '',
(row.paidGold / 100).toFixed(2) || '0.00',
row.rechargeWay || '',
(row.paidGold / 100).toFixed(2) || '0.00',
(row.freeGold / 100).toFixed(2) || '0.00',
row.remark || '',
row.payWay || '',
row.name || '',
//
row.status === 1 ? '已通过' : row.status === 0 ? '待审核' : row.status === 2 ? '已驳回' : '',
row.reson || '',
moment(row.rechargeTime).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))
})
</script> </script>
<template> <template>
@ -404,7 +627,7 @@ const handleSortChange = (column) => {
<el-col> <el-col>
<el-card style="margin-bottom: 20px"> <el-card style="margin-bottom: 20px">
<el-row style="margin-bottom: 10px"> <el-row style="margin-bottom: 10px">
<el-col :span="8">
<el-col :span="6">
<div class="head-card-element"> <div class="head-card-element">
<el-text class="mx-1" size="large">活动名称</el-text> <el-text class="mx-1" size="large">活动名称</el-text>
<el-select <el-select
@ -423,8 +646,8 @@ const handleSortChange = (column) => {
</el-select> </el-select>
</div> </div>
</el-col> </el-col>
<el-col :span="8">
<!-- <div class="head-card-element">
<!-- <el-col :span="8">
<div class="head-card-element">
<el-text class="mx-1" size="large">充值方式</el-text> <el-text class="mx-1" size="large">充值方式</el-text>
<el-select <el-select
v-model="rechargeVo.rechargeWay" v-model="rechargeVo.rechargeWay"
@ -440,8 +663,8 @@ const handleSortChange = (column) => {
:value="item" :value="item"
/> />
</el-select> </el-select>
</div> -->
</el-col>
</div>
</el-col>-->
<el-col :span="8"> <el-col :span="8">
<div class="head-card-element" v-if="adminData.area == '总部'"> <div class="head-card-element" v-if="adminData.area == '总部'">
<el-text class="mx-1" size="large">所属地区</el-text> <el-text class="mx-1" size="large">所属地区</el-text>
@ -463,7 +686,7 @@ const handleSortChange = (column) => {
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="21">
<el-col :span="16">
<div class="head-card-element"> <div class="head-card-element">
<el-text class="mx-1" size="large">充值时间</el-text> <el-text class="mx-1" size="large">充值时间</el-text>
<el-date-picker <el-date-picker
@ -480,10 +703,12 @@ const handleSortChange = (column) => {
<el-button @click="get7Days()">近7天</el-button> <el-button @click="get7Days()">近7天</el-button>
</div> </div>
</el-col> </el-col>
<el-col :span="3">
<el-col :span="6">
<div class="head-card-btn"> <div class="head-card-btn">
<el-button @click="reset()">重置</el-button>
<el-button type="success" @click="reset()">重置</el-button>
<el-button type="primary" @click="search()">查询</el-button> <el-button type="primary" @click="search()">查询</el-button>
<!-- 新增导出按钮 -->
<el-button type="primary" @click="exportExcel">导出excel</el-button>
</div> </div>
</el-col> </el-col>
</el-row> </el-row>
@ -670,6 +895,53 @@ const handleSortChange = (column) => {
</el-card> </el-card>
</el-col> </el-col>
</el-row> </el-row>
<!-- 导出excel提前展示的信息面板 -->
<el-dialog
v-model="showExportInfoPanel"
title="导出信息确认"
width="400px"
:close-on-click-modal="false"
>
<div class="info-panel-header">导出信息</div>
<div v-if="!rechargeVo.activityId && !rechargeVo.area && !rechargeVo.startDate && !rechargeVo.endDate">
你正在导出所有数据
</div>
<div v-else>
你正在导出以下数据
</div>
<div v-if="rechargeVo.activityId">活动名称{{ rechargeVo.activityId || '' }}</div>
<div v-if="rechargeVo.area">所属地区{{ rechargeVo.area || '' }}</div>
<div v-if="rechargeVo.startDate || rechargeVo.endDate">
<span>充值时间</span>
<span>{{ rechargeVo.startDate ? moment(rechargeVo.startDate).format('YYYY-MM-DD HH:mm:ss') : '无起始时间' }} {{ rechargeVo.endDate ? moment(rechargeVo.endDate).format('YYYY-MM-DD HH:mm:ss') : '无结束时间' }}</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"
:format="(percentage) => `${percentage}%`"
/>
<template #footer>
<span class="dialog-footer">
<el-button type="danger" @click="cancelExport">取消导出</el-button>
</span>
</template>
</el-dialog>
</template> </template>
<style scoped> <style scoped>

22
gold-system/src/views/refund/addRefund.vue

@ -25,7 +25,12 @@ const getAdminData = async function () {
console.log('请求失败', error) console.log('请求失败', error)
} }
} }
//
const trimJwCode = () => {
if (addRefund.value.jwcode) {
addRefund.value.jwcode = addRefund.value.jwcode.replace(/\s/g, '');
}
}
// 退 // 退
const addRefund = ref({ const addRefund = ref({
updateType: '3', updateType: '3',
@ -134,12 +139,13 @@ const user = ref({
firstRechargeTime: '' firstRechargeTime: ''
}) })
const getUser = async function (jwcode) { const getUser = async function (jwcode) {
trimJwCode();
try { try {
// POST // POST
const result = await API({ const result = await API({
url: '/recharge/user', url: '/recharge/user',
data: { data: {
jwcode: jwcode,
jwcode: addRefund.value.jwcode,
area: adminData.value.area area: adminData.value.area
} }
}) })
@ -188,14 +194,16 @@ const refundType = [
] ]
// //
//
const goods = ref([]) const goods = ref([])
const getGoods = async function (jwcode) { const getGoods = async function (jwcode) {
trimJwCode();
try { try {
// POST // POST
const result = await API({ const result = await API({
url: '/consume/getDeatil', url: '/consume/getDeatil',
data: { data: {
jwcode: jwcode,
jwcode: addRefund.value.jwcode,
area: adminData.value.area area: adminData.value.area
} }
}) })
@ -388,7 +396,7 @@ onMounted(async function () {
placeholder="提交人姓名" placeholder="提交人姓名"
/> />
</el-form-item> </el-form-item>
<el-button @click="cancel()" style="margin-left: 280px">重置</el-button>
<el-button type="success" @click="cancel()" style="margin-left: 280px">重置</el-button>
<el-button type="primary" @click="addBefore"> 提交 </el-button> <el-button type="primary" @click="addBefore"> 提交 </el-button>
</el-form> </el-form>
@ -452,12 +460,12 @@ onMounted(async function () {
<p style="color: #2fa1ff">{{ user.rechargeTimes }}</p> <p style="color: #2fa1ff">{{ user.rechargeTimes }}</p>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="10">
<!-- <el-col :span="10">
<el-form-item label="负责客服"> <el-form-item label="负责客服">
<p>{{ adminData.name }}</p> <p>{{ adminData.name }}</p>
</el-form-item> </el-form-item>
</el-col>
<el-col :span="14">
</el-col> -->
<el-col :span="10">
<el-form-item label="消费次数"> <el-form-item label="消费次数">
<p style="color: #2fa1ff">{{ user.spendTimes }}</p> <p style="color: #2fa1ff">{{ user.spendTimes }}</p>
</el-form-item> </el-form-item>

3
gold-system/src/views/refund/allRefund.vue

@ -1,4 +1,5 @@
<script setup> <script setup>
// 退
import { ref, onMounted, reactive, computed } from 'vue' import { ref, onMounted, reactive, computed } from 'vue'
import ElementPlus from 'element-plus' import ElementPlus from 'element-plus'
import { AiFillRead } from 'vue-icons-plus/ai' import { AiFillRead } from 'vue-icons-plus/ai'
@ -512,7 +513,7 @@ const handleCurrentChange = function (val) {
</el-col> </el-col>
<el-col :span="3"> <el-col :span="3">
<div class="head-card-btn"> <div class="head-card-btn">
<el-button @click="reset()">重置</el-button>
<el-button type="success" @click="reset()">重置</el-button>
<el-button type="primary" @click="search()">查询</el-button> <el-button type="primary" @click="search()">查询</el-button>
</div> </div>
</el-col> </el-col>

725
gold-system/src/views/usergold/index.vue

@ -1,14 +1,14 @@
<!-- 这是客户金币明细页面 -->
<script setup> <script setup>
import { ref, onMounted, reactive, computed } from 'vue'
import ElementPlus from 'element-plus'
import { ElMessage, ElMessageBox } from 'element-plus'
import { ref, onMounted, computed ,nextTick} from 'vue'
import { ElMessage } from 'element-plus'
import axios from 'axios' import axios from 'axios'
import moment from 'moment' import moment from 'moment'
import { ta } from 'element-plus/es/locales.mjs'
import API from '@/util/http' import API from '@/util/http'
import { writeFile, utils } from 'xlsx' import { writeFile, utils } from 'xlsx'
// //
//
const adminData = ref({}) const adminData = ref({})
const getAdminData = async function () { const getAdminData = async function () {
try { try {
@ -24,10 +24,34 @@ const getAdminData = async function () {
console.log('请求失败', 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 tableData = ref([])
//
// const tableAllData = ref([]);
// //
const rechargeCoin = ref(0) const rechargeCoin = ref(0)
const freeCoin = ref(0) const freeCoin = ref(0)
@ -39,14 +63,12 @@ const total = ref(100)
const getTime = ref([]) const getTime = ref([])
// detailY // detailY
const detailY = ref({}) const detailY = ref({})
//
const getAllObj = ref({})
// //
const getObj = ref({ const getObj = ref({
pageNum: 1, pageNum: 1,
pageSize: 50 pageSize: 50
}) })
//excel
// excel
const getPutEX = ref(false) const getPutEX = ref(false)
// //
@ -61,10 +83,6 @@ const num = [
} }
] ]
// //
// const tableHeight = computed(function () {
// return (getObj.value.pageSize + 2) * 38 + "px";
// });
// //
// =========================================================================== // ===========================================================================
@ -81,12 +99,9 @@ const get = async function (val) {
if (typeof val === 'number') { if (typeof val === 'number') {
getObj.value.pageNum = val getObj.value.pageNum = val
} }
//
if (getTime.value != null) {
if (getTime.value.startDate != '' && getTime.value.endDate != '') {
detailY.value.startDate = getTime.value[0]
detailY.value.endDate = getTime.value[1]
}
if (getTime.value.length === 2) {
detailY.value.startDate = getTime.value[0]
detailY.value.endDate = getTime.value[1]
} else { } else {
detailY.value.startDate = '' detailY.value.startDate = ''
detailY.value.endDate = '' detailY.value.endDate = ''
@ -101,116 +116,62 @@ const get = async function (val) {
method: 'post', method: 'post',
data: { ...getObj.value, detailY: { ...detailY.value } } data: { ...getObj.value, detailY: { ...detailY.value } }
}) })
// const result2 = await API.post("http://54.251.137.151:10702/detailY", {
// ...getAllObj.value,
// detailY: { ...detailY.value },
// });
//
console.log('请求成功', result)
// console.log("2", result2);
//
tableData.value = result.data.list tableData.value = result.data.list
console.log('tableData', tableData.value)
// tableAllData.value = result2.data;
// console.log("tableAllData", tableAllData.value);
//
total.value = result.data.total total.value = result.data.total
console.log('total', total.value)
// 100
// 100
// rechargeCoin.value = parseFloat((tableAllData.value.sumR / 100).toFixed(2));
// freeCoin.value = parseFloat((tableAllData.value.sumF / 100).toFixed(2));
// taskCoin.value = parseFloat((tableAllData.value.sumT / 100).toFixed(2));
// for (let i = 0; i < tableAllData.value.length; i++) {
// rechargeCoin.value += tableAllData.value[i].rechargeCoin;
// freeCoin.value += tableAllData.value[i].freeCoin;
// taskCoin.value += tableAllData.value[i].taskCoin;
// }
// console.log(
// "",
// rechargeCoin.value,
// freeCoin.value,
// taskCoin.value
// );
} catch (error) { } catch (error) {
console.log('请求失败', error) console.log('请求失败', error)
//
} }
} }
// detailY jwcode
const trimJwCode = () => {
if (detailY.value.jwcode) {
detailY.value.jwcode = detailY.value.jwcode.replace(/\s/g, '');
}
}
// //
const search = function () { const search = function () {
trimJwCode();
getObj.value.pageNum = 1 getObj.value.pageNum = 1
get() get()
} }
// //
const reset = function () { const reset = function () {
//
delete detailY.value.jwcode delete detailY.value.jwcode
//
delete detailY.value.num delete detailY.value.num
//
delete detailY.value.startDate delete detailY.value.startDate
//
delete detailY.value.endDate delete detailY.value.endDate
//
delete detailY.value.area delete detailY.value.area
delete sortField.value delete sortField.value
delete sortOrder.value delete sortOrder.value
getTime.value = {}
//
getTime.value = []
delete detailY.value.consumePlatform delete detailY.value.consumePlatform
} }
// //
const getToday = function () { 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
)
const today = moment()
const startDate = today.startOf('day').toDate()
const endDate = today.endOf('day').toDate()
getTime.value = [startDate, endDate] getTime.value = [startDate, endDate]
console.log('getTime', getTime.value)
get()
search()
} }
// //
const getYesterday = function () { 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
)
const yesterday = moment().subtract(1, 'day')
const startDate = yesterday.startOf('day').toDate()
const endDate = yesterday.endOf('day').toDate()
getTime.value = [startDate, endDate] getTime.value = [startDate, endDate]
console.log('getTime', getTime.value)
get()
search()
} }
// 7 // 7
const get7Days = function () { 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
)
const startDate = moment().subtract(6, 'day').startOf('day').toDate()
const endDate = moment().endOf('day').toDate()
getTime.value = [startDate, endDate] getTime.value = [startDate, endDate]
console.log('getTime', getTime.value)
get()
search()
} }
// //
@ -242,153 +203,226 @@ const checkNumber = function () {
// //
onMounted(async function () { onMounted(async function () {
await getArea()
await getAdminData() await getAdminData()
await get() await get()
}) })
// excel
// Excel // Excel
//
const json_fields = (row) => {
return [
row.jwcode, //
row.area, //
row.platform, //
row.consumePlatform, //
row.gold, //
row.rechargeCoin, //
row.freeCoin, //
row.taskCoin, //
row.createAdmin, //
row.createTime,
row.name,
row.id
]
}
//
const json_meta = [
[
{
key: 'charset',
value: 'utf-8'
}
]
]
const headers = [ const headers = [
'序号',
'姓名',
'精网号', '精网号',
'地区',
'所属地区',
'平台信息', '平台信息',
'数量',
'数量更新类型',
'更新数量',
'更新类型',
'永久金币', '永久金币',
'免费金币', '免费金币',
'任务金币', '任务金币',
'提交人', '提交人',
'更新时间',
'用户名',
'id'
'更新时间'
] ]
const exportExcel = () => {
// json_fields
const data = excelInfo.value.map(json_fields)
const ws = utils.aoa_to_sheet(data)
//
utils.sheet_add_aoa(ws, [headers], { origin: 'A1' })
const wb = utils.book_new()
utils.book_append_sheet(wb, ws, 'Sheet1')
writeFile(wb, '客户金币明细.xlsx')
}
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
)
const putExcel = ref({
startDate: startDate,
endDate: endDate
})
const excelInfo = ref({})
const loading = ref(false)
const areyour = async function () {
const showExportInfoPanel = ref(false)
//
const exportExcel = async () => {
try { try {
loading.value = true
const result = await API({
url: '/detailY/searchAll',
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', method: 'post',
data: { ...putExcel.value }
data: {
pageNum: 1,
pageSize,
detailY: { ...detailY.value }
}
}) })
excelInfo.value = result.data
// excelInfo
if (Array.isArray(excelInfo.value)) {
excelInfo.value.forEach((item) => {
if (item.rechargeCoin) {
item.rechargeCoin = item.rechargeCoin / 100
}
if (item.freeCoin) {
item.freeCoin = item.freeCoin / 100
}
if (item.taskCoin) {
item.taskCoin = item.taskCoin / 100
}
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++
} }
areyouright.value = true
ElMessage({
type: 'success',
message: '查询成功'
})
loading.value = false
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) { } catch (error) {
console.log('请求失败', error)
loading.value = false
if (!axios.isCancel(error)) {
ElMessage.error(`导出失败: ${error.message}`)
}
} finally {
isExporting.value = false
exportCancelToken.value = null
} }
} }
const areyouright = ref(false)
//
const cancelExport = () => {
if (exportCancelToken.value) {
exportCancelToken.value.cancel('用户取消导出')
ElMessage.warning('导出已取消')
isExporting.value = false
}
}
//
const area = [
{
value: '马来西亚',
label: '马来西亚'
},
{
value: '新加坡',
label: '新加坡'
},
{
value: '香港',
label: '香港'
},
{
value: '泰国',
label: '泰国'
},
{
value: '加拿大',
label: '加拿大'
},
{
value: '越南HCM',
label: '越南HCM'
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 = [ const platform = [
{ {
value: '4', value: '4',
label: '金币系统' label: '金币系统'
}, },
{ {
value: '1', value: '1',
label: 'ERP系统' label: 'ERP系统'
@ -406,84 +440,12 @@ const platform = [
label: '初始化金币' label: '初始化金币'
} }
] ]
const TimeGet = ref('1')
//
const getT = 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
)
putExcel.value.startDate = startDate
putExcel.value.endDate = endDate
console.log('putExcel', putExcel.value)
}
//3
const get3 = function () {
const today = new Date()
const startDate = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate() - 2
)
const endDate = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate() + 1
)
putExcel.value.startDate = startDate
putExcel.value.endDate = endDate
console.log('putExcel', putExcel.value)
}
// 7
const get7 = 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
)
putExcel.value.startDate = startDate
putExcel.value.endDate = endDate
console.log('putExcel', putExcel.value)
}
// 30
const get30 = function () {
const today = new Date()
const startDate = new Date(
today.getFullYear(),
today.getMonth() - 1,
today.getDate()
)
const endDate = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate() + 1
)
putExcel.value.startDate = startDate
putExcel.value.endDate = endDate
console.log('putExcel', putExcel.value)
}
// //
const sortField = ref('') const sortField = ref('')
const sortOrder = ref('') const sortOrder = ref('')
// //
const handleSortChange = (column) => { const handleSortChange = (column) => {
console.log('排序字段:', column.prop)
console.log('排序方式:', column.order)
if (column.prop === 'rechargeCoin') { if (column.prop === 'rechargeCoin') {
sortField.value = 'recharge_coin' sortField.value = 'recharge_coin'
} else if (column.prop === 'taskCoin') { } else if (column.prop === 'taskCoin') {
@ -497,11 +459,14 @@ const handleSortChange = (column) => {
} }
sortOrder.value = column.order === 'ascending' ? 'ASC' : 'DESC' sortOrder.value = column.order === 'ascending' ? 'ASC' : 'DESC'
} }
get() get()
const handlePageSizeChange = function (val) { const handlePageSizeChange = function (val) {
getObj.value.pageSize = val getObj.value.pageSize = val
get() get()
} }
const handleCurrentChange = function (val) { const handleCurrentChange = function (val) {
getObj.value.pageNum = val getObj.value.pageNum = val
get() get()
@ -509,73 +474,64 @@ const handleCurrentChange = function (val) {
</script> </script>
<template> <template>
<!-- 导出excel提前展示的信息面板 -->
<el-dialog <el-dialog
v-model="areyouright"
title=""
width="500"
v-model="showExportInfoPanel"
title="导出信息确认"
width="400px"
:close-on-click-modal="false" :close-on-click-modal="false"
> >
<el-button type="success" @click="exportExcel()">导出</el-button>
<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>
<!-- 这是导出excel的弹窗 -->
<!-- 导出进度弹窗 -->
<el-dialog <el-dialog
v-model="getPutEX"
title="请选择导出条件"
width="500"
v-model="isExporting"
title="正在导出"
width="400px"
:close-on-click-modal="false" :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> <template #footer>
<el-form
v-loading="loading"
ref="ruleFormRef"
style="max-width: 600px"
:model="putExcel"
:rules="rules"
label-width="auto"
class="demo-ruleForm"
:size="formSize"
status-icon
>
<el-form-item prop="activityName" label="精网号:">
<el-input
v-model="putExcel.jwcode"
placeholder="请输入精网号"
style="width: 220px"
/>
</el-form-item>
<el-form-item label="所属地区:"
><el-select
v-model="putExcel.area"
placeholder="请选择所属地区"
style="width: 240px"
clearable
>
<el-option
v-for="item in area"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="更新时间:">
<el-radio-group v-model="TimeGet">
<el-radio value="1" @click="getT()">今天</el-radio>
<el-radio value="3" @click="get3()">近三天</el-radio>
<el-radio value="7" @click="get7()">近一周</el-radio>
<el-radio value="30" @click="get30()">近一个月</el-radio>
</el-radio-group>
</el-form-item>
<el-button
type="primary"
size="small"
style="margin-left: 10px"
@click="areyour()"
>确定</el-button
>
</el-form>
<el-button type="danger" @click="cancelExport">取消导出</el-button>
</template> </template>
</el-dialog> </el-dialog>
@ -636,14 +592,15 @@ const handleCurrentChange = function (val) {
<el-select <el-select
v-model="detailY.area" v-model="detailY.area"
placeholder="请选择所属地区" placeholder="请选择所属地区"
style="width: 200px"
style="width: 240px"
clearable clearable
:loading="isLoadingArea"
> >
<el-option <el-option
v-for="item in area" v-for="item in area"
:key="item.value"
:label="item.label"
:value="item.value"
:key="item.value || item"
:label="item.label || item"
:value="item.value || item"
/> />
</el-select> </el-select>
</div> </div>
@ -658,12 +615,13 @@ const handleCurrentChange = function (val) {
range-separator="至" range-separator="至"
start-placeholder="起始时间" start-placeholder="起始时间"
end-placeholder="结束时间" end-placeholder="结束时间"
style="margin-right: 700px"
style="margin-right: 50px"
/> />
<el-button type="success" @click="getPutEX = true"
>导出Excel表格</el-button
>
<el-button @click="reset()">重置</el-button>
<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> <el-button type="primary" @click="search()">查询</el-button>
</div> </div>
</el-card> </el-card>
@ -672,12 +630,6 @@ const handleCurrentChange = function (val) {
<el-row> <el-row>
<el-col> <el-col>
<el-card> <el-card>
<!-- <div>
现有金币永久金币{{ Math.abs(rechargeCoin) }}免费金币{{
Math.abs(freeCoin)
}}任务金币{{ Math.abs(taskCoin) }}
</div> -->
<!-- 设置表格容器的高度和滚动样式 -->
<div style="height: 584px; overflow-y: auto"> <div style="height: 584px; overflow-y: auto">
<el-table <el-table
:data="tableData" :data="tableData"
@ -728,7 +680,7 @@ const handleCurrentChange = function (val) {
prop="gold" prop="gold"
label="更新数量" label="更新数量"
width="120" width="120"
sortable="custom"
sortable="custom"
> >
<template #default="scope"> <template #default="scope">
<span>{{ scope.row.gold / 100 }}</span> <span>{{ scope.row.gold / 100 }}</span>
@ -737,23 +689,15 @@ const handleCurrentChange = function (val) {
<el-table-column prop="updateType" label="更新类型" width="110"> <el-table-column prop="updateType" label="更新类型" width="110">
<!-- 模板内容 --> <!-- 模板内容 -->
<template #default="scope"> <template #default="scope">
<span v-if="scope.row.updateType == 1">
<span>消费</span>
</span>
<span v-if="scope.row.updateType == 0">
<span>充值</span>
</span>
<span v-if="scope.row.updateType == 2">
<span>退款</span>
</span>
<span v-if="scope.row.updateType == 3">
<span>其他</span>
</span>
<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> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="rechargeCoin" prop="rechargeCoin"
sortable="custom"
sortable="custom"
label="永久金币" label="永久金币"
width="110" width="110"
> >
@ -763,7 +707,7 @@ const handleCurrentChange = function (val) {
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="freeCoin" prop="freeCoin"
sortable="custom"
sortable="custom"
label="免费金币" label="免费金币"
width="110" width="110"
> >
@ -771,10 +715,9 @@ const handleCurrentChange = function (val) {
<span>{{ scope.row.freeCoin / 100 }}</span> <span>{{ scope.row.freeCoin / 100 }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="taskCoin" prop="taskCoin"
sortable="custom"
sortable="custom"
label="任务金币" label="任务金币"
width="110" width="110"
> >
@ -785,7 +728,7 @@ const handleCurrentChange = function (val) {
<el-table-column prop="name" label="提交人" width="110" /> <el-table-column prop="name" label="提交人" width="110" />
<el-table-column <el-table-column
prop="createTime" prop="createTime"
sortable="custom"
sortable="custom"
label="更新时间" label="更新时间"
width="210" width="210"
show-overflow-tooltip show-overflow-tooltip
@ -799,8 +742,7 @@ const handleCurrentChange = function (val) {
</el-table> </el-table>
</div> </div>
<!-- 分页 -->
<!-- 分页 -->
<!-- 此处分页 -->
<div class="pagination" style="margin-top: 20px"> <div class="pagination" style="margin-top: 20px">
<el-pagination <el-pagination
background background
@ -830,11 +772,24 @@ const handleCurrentChange = function (val) {
display: flex; display: flex;
} }
/* .head-card-element {
margin-right: 20px;
} */
.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;
}
/* .head-card-btn {
margin-left: auto;
} */
</style> </style>

59
gold-system/src/views/usergoldInfo/index.vue

@ -1,4 +1,5 @@
<script setup> <script setup>
//
import { ref, onMounted, reactive, computed } from 'vue' import { ref, onMounted, reactive, computed } from 'vue'
import ElementPlus from 'element-plus' import ElementPlus from 'element-plus'
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
@ -77,7 +78,6 @@ const updateType = [
const get = async function (val) { const get = async function (val) {
try { try {
// //
//
if (adminData.value.area === '泰国') { if (adminData.value.area === '泰国') {
detailY.value.areas = ['泰国', '越南'] detailY.value.areas = ['泰国', '越南']
} else if (adminData.value.area !== '总部') { } else if (adminData.value.area !== '总部') {
@ -89,7 +89,7 @@ const get = async function (val) {
} }
// //
if (getTime.value != null) { if (getTime.value != null) {
if (getTime.value.startDate != '' && getTime.value.endDate != '') {
if (getTime.value[0] != '' && getTime.value[1] != '') {
detailY.value.startDate = getTime.value[0] detailY.value.startDate = getTime.value[0]
detailY.value.endDate = getTime.value[1] detailY.value.endDate = getTime.value[1]
} }
@ -114,30 +114,49 @@ const get = async function (val) {
detailY: { ...detailY.value } detailY: { ...detailY.value }
} }
}) })
//
console.log('请求成功', result)
// console.log("2", result2);
//
tableData.value = result.data.list
console.log('tableData', tableData.value)
tableAllData.value = result2.data
// 100
//
rechargeCoin.value = parseFloat((tableAllData.value.sumR / 100).toFixed(2))
freeCoin.value = parseFloat((tableAllData.value.sumF / 100).toFixed(2))
taskCoin.value = parseFloat((tableAllData.value.sumT / 100).toFixed(2))
// console.log("tableAllData", tableAllData.value);
//
total.value = result.data.total
console.log('total', total.value)
// result.data.list
if (result.data.list.length === 0) {
//
tableData.value = []
// 0
rechargeCoin.value = 0
freeCoin.value = 0
taskCoin.value = 0
// null
tableAllData.value = null
// 0
total.value = 0
// ElMessage.warning('')
} else {
//
console.log('请求成功', result)
//
tableData.value = result.data.list
console.log('tableData', tableData.value)
tableAllData.value = result2.data
// 100
rechargeCoin.value = parseFloat((tableAllData.value.sumR / 100).toFixed(2))
freeCoin.value = parseFloat((tableAllData.value.sumF / 100).toFixed(2))
taskCoin.value = parseFloat((tableAllData.value.sumT / 100).toFixed(2))
//
total.value = result.data.total
console.log('total', total.value)
}
} catch (error) { } catch (error) {
console.log('请求失败', error) console.log('请求失败', error)
// //
} }
} }
// detailY putExcel jwcode
const trimJwCode = () => {
if (detailY.value.jwcode) {
detailY.value.jwcode = detailY.value.jwcode.replace(/\s/g, '');
}
}
// //
const search = function () { const search = function () {
trimJwCode();
getObj.value.pageNum = 1 getObj.value.pageNum = 1
get() get()
} }
@ -278,7 +297,7 @@ const handleCurrentChange = function (val) {
</div> </div>
<div class="head-card-btn"> <div class="head-card-btn">
<el-button @click="reset()">重置</el-button>
<el-button type="success" @click="reset()">重置</el-button>
<el-button type="primary" @click="search()">查询</el-button> <el-button type="primary" @click="search()">查询</el-button>
</div> </div>
</div> </div>

7
gold-system/src/views/workspace/index.vue

@ -1,6 +1,6 @@
<script setup> <script setup>
import * as echarts from 'echarts' import * as echarts from 'echarts'
//
import { ref, onMounted, reactive, computed } from 'vue' import { ref, onMounted, reactive, computed } from 'vue'
import { VscInfo } from 'vue-icons-plus/vsc' import { VscInfo } from 'vue-icons-plus/vsc'
import * as bs from 'vue-icons-plus/bs' import * as bs from 'vue-icons-plus/bs'
@ -1019,6 +1019,7 @@ onMounted(async function () {
tooltip: { tooltip: {
trigger: 'item', trigger: 'item',
position: ['15%', '-3%'], position: ['15%', '-3%'],
show:true, //
formatter: function (params) { formatter: function (params) {
return params.seriesName + '<br/>' + params.name return params.seriesName + '<br/>' + params.name
} }
@ -1026,7 +1027,9 @@ onMounted(async function () {
legend: { legend: {
bottom: '-1%', bottom: '-1%',
left: 'center', left: 'center',
orient: 'vertical'
orient: 'vertical',
//
selectedMode: true,
}, },
series: [ series: [
{ {

2
gold-system/stats.html
File diff suppressed because it is too large
View File

Loading…
Cancel
Save