Browse Source

Merge branch 'milestone-20251104-现金二期' of http://39.101.133.168:8807/huangqizhen/gold-vue into milestone-20251104-现金二期

master
ZhangYong 2 days ago
parent
commit
15bcde1cd6
  1. 16
      src/views/activityManage/activity.vue
  2. 3
      src/views/channelManage/cart/cart.vue
  3. 2
      src/views/channelManage/fans/fans.vue
  4. 4
      src/views/channelManage/reward/reward.vue
  5. 6
      src/views/consume/bean/articleVideo.vue
  6. 5
      src/views/consume/bean/dieHardFan.vue
  7. 102
      src/views/consume/bean/liveStream.vue
  8. 21
      src/views/home.vue
  9. 48
      src/views/moneyManage/executor/executor.vue
  10. 55
      src/views/moneyManage/receiveDetail/receiveFinance.vue
  11. 52
      src/views/moneyManage/receiveDetail/receiveHead.vue
  12. 47
      src/views/moneyManage/receiveDetail/receiveManage.vue
  13. 26
      src/views/moneyManage/receiveDetail/receiveService.vue
  14. 32
      src/views/moneyManage/refundDetail/refundCharge.vue
  15. 37
      src/views/moneyManage/refundDetail/refundFinance.vue
  16. 41
      src/views/moneyManage/refundDetail/refundHeader.vue
  17. 66
      src/views/moneyManage/refundDetail/refundService.vue
  18. 911
      src/views/workspace/index_.vue

16
src/views/activityManage/activity.vue

@ -193,6 +193,10 @@ const editForm = ref({
})
const marketOptions = ref([])
const getActivity = async function () {
if (!hasMenuPermission(permissionMapping.view_activity)) {
ElMessage.error('无此权限')
return
}
const rechargeActivity = {
activityName: searchForm.value.activityName,
businessBelong: searchForm.value.businessBelong,
@ -219,6 +223,10 @@ const getActivity = async function () {
}
}
const handleAdd = async function () {
if (!hasMenuPermission(permissionMapping.add_activity)) {
ElMessage.error('无此权限')
return
}
const activityName = addForm.value.activityName
if (!validateActivityName(activityName)) return
@ -274,6 +282,10 @@ const handleAdd = async function () {
//
const throttleGetActivity = _.throttle(handleAdd, 5000, { trailing: false });
const handleEdit = async function () {
if (!hasMenuPermission(permissionMapping.edit_activity)) {
ElMessage.error('无此权限')
return
}
const activityName = editForm.value.activityName
if (!validateActivityName(activityName)) return
@ -323,6 +335,10 @@ const handleEdit = async function () {
}
}
const handleDel = async function (row) {
if (!hasMenuPermission(permissionMapping.delete_activity)) {
ElMessage.error('无此权限')
return
}
if (!currentDelRow.value) {
ElMessage.error('当前选择无数据')
return

3
src/views/channelManage/cart/cart.vue

@ -156,6 +156,7 @@ const searchCart = async function () {
...beanCart.value,
sortField: sortField.value,
sortOrder: sortOrder.value,
roleId: adminData.value.roleId
}
}
})
@ -282,6 +283,8 @@ const exportExcel = async function () {
...beanCart.value,
sortField: sortField.value,
sortOrder: sortOrder.value,
roleId: adminData.value.roleId
},
}
const res = await API({ url: '/export/exportArticle', data: params })

2
src/views/channelManage/fans/fans.vue

@ -399,6 +399,8 @@ const exportExcel = async function () {
...beanConsumeFan.value,
sortField: sortField.value,
sortOrder: sortOrder.value,
roleId: adminData.value.roleId
},
}
const res = await API({ url: '/export/exportFan', data: params })

4
src/views/channelManage/reward/reward.vue

@ -419,7 +419,9 @@ const exportExcel = async function () {
startTime: beanConsumeLive.value.startTime || '',
endTime: beanConsumeLive.value.endTime || '',
sortField: sortField.value || 'consumeTime',
sortOrder: sortOrder.value || 'desc'
sortOrder: sortOrder.value || 'desc',
roleId: adminData.value.roleId
}
}
// 便

6
src/views/consume/bean/articleVideo.vue

@ -195,7 +195,9 @@ const ConsumeSelectBy = async function (val) {
endTime: beanConsumeArticle.value.endTime,
sortField: beanConsumeArticle.value.sortField,
sortOrder: beanConsumeArticle.value.sortOrder,
flag: flag.value
flag: flag.value ,
roleId: adminData.value.roleId
}
}
})
@ -394,6 +396,8 @@ const exportExcel = async function () {
...beanConsumeArticle.value,
sortField: sortField.value,
sortOrder: sortOrder.value,
roleId: adminData.value.roleId
},
}
const res = await API({ url: '/export/exportArticle', data: params })

5
src/views/consume/bean/dieHardFan.vue

@ -196,7 +196,8 @@ const ConsumeSelectBy = async function (val) {
endTime: beanConsumeFan.value.endTime || '',
sortField: beanConsumeFan.value.sortField || 'consumeTime',
sortOrder: beanConsumeFan.value.sortOrder || 'desc',
flag: flag.value
flag: flag.value,
roleId: adminData.value.roleId
}
}
})
@ -398,6 +399,8 @@ const exportExcel = async function () {
...beanConsumeFan.value,
sortField: sortField.value,
sortOrder: sortOrder.value,
roleId: adminData.value.roleId
},
}
const res = await API({ url: '/export/exportFan', data: params })

102
src/views/consume/bean/liveStream.vue

@ -1,16 +1,17 @@
<script setup>
import { computed, onMounted, ref, watch } from 'vue'
import { dayjs, ElMessage } from 'element-plus'
import {computed, onMounted, ref, watch} from 'vue'
import {dayjs, ElMessage} from 'element-plus'
import request from '@/util/http.js'
import API from '@/util/http.js'
import moment from 'moment'
import { useAdminStore } from "@/store/index.js";
import { storeToRefs } from "pinia";
import {useAdminStore} from "@/store/index.js";
import {storeToRefs} from "pinia";
const adminStore = useAdminStore();
const { flag } = storeToRefs(adminStore);
const {flag} = storeToRefs(adminStore);
// flag
watch(flag, (newFlag, oldFlag) => {
watch(flag, (newFlag, oldFlag) => {
// flag
if (newFlag !== oldFlag) {
selectLiveBy()
@ -62,7 +63,7 @@ const getGift = async function () {
try {
const result = await request({
url: '/beanConsume/getLiveGift', // todo
data: { account: adminData.value.account }
data: {account: adminData.value.account}
})
console.log('请求礼物列表成功', result)
//
@ -84,7 +85,7 @@ const getChannel = async function () {
try {
const result = await request({
url: '/beanConsume/getLiveChannel', // todo
data: { account: adminData.value.account }
data: {account: adminData.value.account}
})
console.log('请求频道列表成功', result)
//
@ -101,12 +102,12 @@ const getChannel = async function () {
//
const consumeTypes = ref([
{ label: '发礼物', value: 1 },
{ label: '发红包', value: 2 },
{ label: '发福袋', value: 3 },
{ label: '付费直播', value: 4 },
{ label: '加入粉丝团', value: 5 },
{ label: '发弹幕', value: 6 }
{label: '发礼物', value: 1},
{label: '发红包', value: 2},
{label: '发福袋', value: 3},
{label: '付费直播', value: 4},
{label: '加入粉丝团', value: 5},
{label: '发弹幕', value: 6}
])
//
const handleTypeChange = (value) => {
@ -149,7 +150,7 @@ const getDept = async function () {
// url: '/general/dept',
url: '/beanConsume/getDept', // todo
data: { account: adminData.value.account }
data: {account: adminData.value.account}
})
console.log('请求地区列表成功', result)
//
@ -237,7 +238,8 @@ const selectLiveBy = async function (val) {
endTime: beanConsumeLive.value.endTime || '',
sortField: beanConsumeLive.value.sortField || 'consumeTime',
sortOrder: beanConsumeLive.value.sortOrder || 'desc',
flag: flag.value
flag: flag.value,
roleId: adminData.value.roleId
}
}
})
@ -253,7 +255,7 @@ const selectLiveBy = async function (val) {
payType: 1, // payType 1
beanConsumeLive: {
...beanConsumeLive.value,
flag: flag.value
flag: flag.value
}
};
@ -418,7 +420,9 @@ const exportExcel = async function () {
startTime: beanConsumeLive.value.startTime || '',
endTime: beanConsumeLive.value.endTime || '',
sortField: sortField.value || 'consumeTime',
sortOrder: sortOrder.value || 'desc'
sortOrder: sortOrder.value || 'desc',
roleId: adminData.value.roleId
}
}
// 便
@ -426,7 +430,7 @@ const exportExcel = async function () {
try {
console.log('2')
const res = await API({ url: '/export/exportLive', data: params });
const res = await API({url: '/export/exportLive', data: params});
console.log('导出请求响应:', res);
if (res.code === 200) {
ElMessage.success('导出成功');
@ -455,7 +459,7 @@ const exportListLoading = ref(false)
const getExportList = async () => {
exportListLoading.value = true
try {
const result = await API({ url: '/export/export' })
const result = await API({url: '/export/export'})
if (result.code === 200) {
const filteredData = result.data.filter(item => {
return item.type === 6; //6
@ -520,31 +524,32 @@ const getTagText = (state) => {
<div class="select">
<div class="selectRow">
<el-text class="text">精网号</el-text>
<el-input class="selectContent" v-model="beanConsumeLive.jwcode" placeholder="请输入精网号" clearable />
<el-input class="selectContent" v-model="beanConsumeLive.jwcode" placeholder="请输入精网号" clearable/>
</div>
<div class="selectRow">
<el-text class="text">地区</el-text>
<el-select class="selectContent" v-model="beanConsumeLive.dept" placeholder="请选择地区" clearable>
<el-option v-for="(item, index) in dept" :key="index" :label="item" :value="item" />
<el-option v-for="(item, index) in dept" :key="index" :label="item" :value="item"/>
</el-select>
</div>
<div class="selectRow" style="width: 14vw;">
<el-text class="text">礼物名称</el-text>
<el-select class="selectContent" v-model="beanConsumeLive.gift" placeholder="请选择礼物名称" clearable filterable
allow-create default-first-option>
<el-option v-for="(item, index) in gifts" :key="index" :label="item" :value="item" />
<el-select class="selectContent" v-model="beanConsumeLive.gift" placeholder="请选择礼物名称" clearable
filterable
allow-create default-first-option>
<el-option v-for="(item, index) in gifts" :key="index" :label="item" :value="item"/>
</el-select>
</div>
<div class="selectRow" style="width: 12vw;">
<el-text class="textB" size="large">频道</el-text>
<el-select class="selectContent" v-model="beanConsumeLive.liveChannel" placeholder="请选择频道" clearable
filterable allow-create default-first-option>
<el-option v-for="(item, index) in channels" :key="index" :label="item" :value="item" />
filterable allow-create default-first-option>
<el-option v-for="(item, index) in channels" :key="index" :label="item" :value="item"/>
</el-select>
</div>
<div class="selectRow" style="width: 12vw;">
<el-text class="textB" size="large">直播间</el-text>
<el-input class="selectContent" v-model="beanConsumeLive.liveName" placeholder="请输入直播间" clearable />
<el-input class="selectContent" v-model="beanConsumeLive.liveName" placeholder="请输入直播间" clearable/>
</div>
</div>
</el-col>
@ -553,8 +558,8 @@ const getTagText = (state) => {
<div class="selectRow" style="width: 31.4vw;">
<el-text class="text">消费时间</el-text>
<el-date-picker class="selectContent" v-model="getTime" type="datetimerange" range-separator=""
start-placeholder="起始时间" end-placeholder="结束时间" style="margin-right:1vw;width:480px"
@change="handleDatePickerChange" :default-time="defaultTime" />
start-placeholder="起始时间" end-placeholder="结束时间" style="margin-right:1vw;width:480px"
@change="handleDatePickerChange" :default-time="defaultTime"/>
<div v-if="false">
<el-button @click="getToday()" :type="activeTimeRange === 'today' ? 'primary' : ''"> </el-button>
<el-button @click="getYesterday()" :type="activeTimeRange === 'yesterday' ? 'primary' : ''"> </el-button>
@ -578,43 +583,44 @@ const getTagText = (state) => {
</div>
<div style="overflow-y: auto">
<el-table :data="tableData" style="width: 82vw" height="56vh" @sort-change="handleSortChange"
:row-style="{ height: '50px' }">
:row-style="{ height: '50px' }">
<el-table-column type="index" label="序号" width="80px" fixed="left">
<template #default="scope">
<span>{{
scope.$index + 1 + (getObj.pageNum - 1) * getObj.pageSize
}}</span>
scope.$index + 1 + (getObj.pageNum - 1) * getObj.pageSize
}}</span>
</template>
</el-table-column>
<!-- 固定姓名列 -->
<el-table-column prop="name" label="姓名" width="150px" fixed="left" show-overflow-tooltip />
<el-table-column prop="name" label="姓名" width="150px" fixed="left" show-overflow-tooltip/>
<!-- 固定精网号列 -->
<el-table-column prop="jwcode" label="精网号" width="110px" fixed="left" />
<el-table-column prop="dept" label="地区" width="110px" />
<el-table-column prop="jwcode" label="精网号" width="110px" fixed="left"/>
<el-table-column prop="dept" label="地区" width="110px"/>
<el-table-column prop="gift" label="礼物" width="140px">
</el-table-column>
<el-table-column prop="beanNum" label="金豆数量" sortable="custom" width="120px" />
<el-table-column prop="beanNum" label="金豆数量" sortable="custom" width="120px"/>
<el-table-column prop="isBackpack" label="背包礼物" width="120px">
<template #default="scope">
{{ scope.row.isBackpack == 1 ? '是' : '否' }}
</template>
</el-table-column>
<el-table-column prop="buyBean" label="付费金豆数" sortable="custom" width="120px" />
<el-table-column prop="freeBean" label="免费金豆数" sortable="custom" width="120px" />
<el-table-column prop="liveChannel" label="频道" width="120px" show-overflow-tooltip />
<el-table-column prop="liveName" label="直播间名称" width="160px" show-overflow-tooltip />
<el-table-column prop="consumeTime" label="消费时间" sortable="custom" width="180px" />
<el-table-column prop="buyBean" label="付费金豆数" sortable="custom" width="120px"/>
<el-table-column prop="freeBean" label="免费金豆数" sortable="custom" width="120px"/>
<el-table-column prop="liveChannel" label="频道" width="120px" show-overflow-tooltip/>
<el-table-column prop="liveName" label="直播间名称" width="160px" show-overflow-tooltip/>
<el-table-column prop="consumeTime" label="消费时间" sortable="custom" width="180px"/>
</el-table>
</div>
<el-pagination background :current-page="getObj.pageNum" :page-size="getObj.pageSize" :page-sizes="[5, 10, 20, 50, 100]" style="margin-top: 20px;"
layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="handlePageSizeChange"
@current-change="handleCurrentChange"></el-pagination>
<el-pagination background :current-page="getObj.pageNum" :page-size="getObj.pageSize"
:page-sizes="[5, 10, 20, 50, 100]" style="margin-top: 20px;"
layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="handlePageSizeChange"
@current-change="handleCurrentChange"></el-pagination>
</el-card>
<!-- 导出弹窗 -->
<el-dialog v-model="exportListVisible" title="导出列表" width="80%">
<el-table :data="exportList" style="width: 100% ;height: 60vh;" :loading="exportListLoading">
<el-table-column prop="fileName" label="文件名" />
<el-table-column prop="fileName" label="文件名"/>
<el-table-column prop="state" label="状态">
<template #default="scope">
<el-tag :type="getTagType(scope.row.state)" :effect="scope.row.state === 3 ? 'light' : 'plain'">
@ -630,7 +636,7 @@ const getTagText = (state) => {
<el-table-column label="操作">
<template #default="scope">
<el-button type="primary" size="small" @click="downloadExportFile(scope.row)"
:disabled="scope.row.state !== 2">
:disabled="scope.row.state !== 2">
下载
</el-button>
</template>
@ -671,7 +677,7 @@ const getTagText = (state) => {
:deep(.el-table__header-wrapper),
:deep(.el-table__body-wrapper),
:deep(.el-table__cell),
/* 表格 */
/* 表格 */
:deep(.el-table__body td) {
background-color: #F3FAFE !important;
}

21
src/views/home.vue

@ -142,10 +142,15 @@ const selectStatusById = () => {
if (hasPermission(permissionMapping.area_finance_collection_pending)) {
status.push(0);
}
//
else if (hasPermission(permissionMapping.area_manager_collection_pending)) {
status.push(0);
//
if (hasPermission(permissionMapping.collection_area_customer_service)) {
status.push(2);
}
//
// else if (hasPermission(permissionMapping.area_manager_collection_pending)) {
// status.push(0);
// }
// ===== 退 =====
@ -154,17 +159,21 @@ const selectStatusById = () => {
status.push(10);
}
// 退
else if (hasPermission(permissionMapping.audit_area_manager_refund)) {
if (hasPermission(permissionMapping.audit_area_manager_refund)) {
status.push(20);
}
// 退
else if (hasPermission(permissionMapping.audit_headquarters_refund)) {
if (hasPermission(permissionMapping.audit_headquarters_refund)) {
status.push(30);
}
//
else if (hasPermission(permissionMapping.view_execution_details)) {
if (hasPermission(permissionMapping.view_execution_details)) {
status.push(40);
}
//退
if (hasPermission(permissionMapping.refund_area_customer_service)) {
status.push(12,22,32);
}
//
return [...new Set(status)];

48
src/views/moneyManage/executor/executor.vue

@ -41,8 +41,8 @@
<div class="search2" style="width: 25.5vw;">
<el-text size="large" style="width:4vw;">退款时间</el-text>
<el-date-picker v-model="dateRange" type="datetimerange" range-separator="" start-placeholder="起始时间"
end-placeholder="结束时间" style="width:18vw;" clearable
:disabled-date="disabledDate" :default-time="defaultTime" />
end-placeholder="结束时间" style="width:18vw;" clearable :disabled-date="disabledDate"
:default-time="defaultTime" />
</div>
<div>
<el-button type="primary" size="medium" @click="getRefund">查询</el-button>
@ -54,10 +54,10 @@
<el-card style="background-color: rgb(231,244,253);height:80vh;">
<el-table :data="tableData" style="height:70vh;width:82vw;">
<el-table-column type="index" label="序号" width="60" fixed="left">
<template #default="scope">
{{ scope.$index + 1 + (pagination.pageNum - 1) * pagination.pageSize }}
</template>
</el-table-column>
<template #default="scope">
{{ scope.$index + 1 + (pagination.pageNum - 1) * pagination.pageSize }}
</template>
</el-table-column>
<el-table-column prop="jwcode" label="Homily ID" width="120" fixed="left" />
<el-table-column prop="name" label="姓名" width="120" fixed="left" show-overflow-tooltip />
<el-table-column prop="marketName" label="所属地区" width="120" />
@ -123,11 +123,12 @@
</el-table-column>
</el-table>
<el-pagination v-model:current-page="pagination.pageNum" v-model:page-size="pagination.pageSize"
@size-change="handlePageSizeChange" @current-change="handleCurrentChange"
@size-change="handlePageSizeChange" @current-change="handleCurrentChange"
layout="total, sizes, prev, pager, next, jumper" :total="pagination.total" style="margin-top: 1vh;" />
</el-card>
<el-dialog v-model="showEdit" class="edit" overflow draggable style="width: 40vw; background-color: #F3FAFE !important;">
<el-dialog v-model="showEdit" class="edit" overflow draggable
style="width: 40vw; background-color: #F3FAFE !important;">
<div style="display: flex;">
<div class="left">
<div class="dialog-item">
@ -175,7 +176,8 @@
</div>
<div class="dialog-item">
<el-text style="width:4vw;">转账凭证</el-text>
<img v-if="editRow.payVoucher" :src="editRow.payVoucher" style="width: 80px; height: 80px; object-fit: cover;">
<img v-if="editRow.payVoucher" :src="editRow.payVoucher"
style="width: 80px; height: 80px; object-fit: cover;">
<div v-else>
无转账凭证
</div>
@ -282,12 +284,20 @@ const getRefund = async function () {
}
const goodsName = searchForm.value.goodsName && searchForm.value.goodsName.length > 0
? searchForm.value.goodsName[searchForm.value.goodsName.length - 1] : ''
? searchForm.value.goodsName[searchForm.value.goodsName.length - 1] : ''
if(searchForm.value.jwcode && !isNumber(searchForm.value.jwcode)){
ElMessage.error('精网号必须为数字')
return
}
if (searchForm.value.jwcode) {
const isPositiveInteger = /^[1-9]\d*$/.test(searchForm.value.jwcode);
if (!isPositiveInteger) {
ElMessage.error('请输入正确的精网号')
return;
}
}
// 400
if (searchForm.value.jwcode.length > 8) {
ElMessage.error('精网号长度不能超过8位')
return;
}
const params = {
pageNum: pagination.value.pageNum,
@ -295,7 +305,7 @@ const getRefund = async function () {
cashRecordDTO: {
jwcode: searchForm.value.jwcode,
name: searchForm.value.name,
markets: searchForm.value.markets && searchForm.value.markets.length > 0 ? [searchForm.value.markets[searchForm.value.markets.length - 1]] : [],
markets: searchForm.value.markets && searchForm.value.markets.length > 0 ? [searchForm.value.markets[searchForm.value.markets.length - 1]] : [],
goodsName: goodsName,
statuses: statusesParam.value,//1012
// 2022
@ -495,12 +505,12 @@ const reset = function () {
getRefund()
}
const handlePageSizeChange = function (val) {
pagination.value.pageSize = val
getRefund()
pagination.value.pageSize = val
getRefund()
}
const handleCurrentChange = function (val) {
pagination.value.pageNum = val
getRefund()
pagination.value.pageNum = val
getRefund()
}
onMounted(() => {
console.log('???????????????????', adminData.value)

55
src/views/moneyManage/receiveDetail/receiveFinance.vue

@ -209,7 +209,7 @@
@click="openAuditForm(scope.row)">审核
</el-link>
<el-link
v-else-if="activeTab == 'pass' && !(scope.row.status == 6 || scope.row.status == 4) && scope.row.receivedMarket == scope.row.submitterMarket"
v-else-if="activeTab == 'pass' && !(scope.row.status == 6 || scope.row.status == 4) && scope.row.receivedMarket == adminData.markets"
style="color: #2741DE;" @click="openEditForm(scope.row)">编辑
</el-link>
<el-link
@ -762,10 +762,10 @@ const exportExcel = async function () {
payCurrencySelect = CurrencyForId(searchData.value.paymentCurrency);
}
if (searchData.value.jwcode && !isNumber(searchData.value.jwcode)) {
ElMessage.error('精网号只能是数字')
return
}
// if (searchData.value.jwcode && !isNumber(searchData.value.jwcode)) {
// ElMessage.error('')
// return
// }
const cashRoleId = '1';
const submitterMarket = adminData.value.markets;
@ -882,10 +882,10 @@ const getlist = async () => {
payCurrencySelect = CurrencyForId(searchData.value.paymentCurrency);
}
if (searchData.value.jwcode && !isNumber(searchData.value.jwcode)) {
ElMessage.error('精网号只能是数字')
return
}
// if (searchData.value.jwcode && !isNumber(searchData.value.jwcode)) {
// ElMessage.error('')
// return
// }
// ID=1
const cashRoleId = '1';
@ -907,6 +907,11 @@ const getlist = async () => {
ElMessage.error('请输入正确的精网号')
return;
}
// 400
if (searchData.value.jwcode.length > 8) {
ElMessage.error('精网号长度不能超过8位')
return;
}
}
const result = await request({
url: '/cashCollection/selectCollection',
@ -956,6 +961,16 @@ const submitRefund = async () => {
if (!refundFormData.value.refundReason) {
return ElMessage.error('请输入退款原因');
}
//
if (refundFormData.value.jwcode) {
const isPositiveInteger = /^[1-9]\d*$/.test(refundFormData.value.jwcode);
if (!isPositiveInteger) {
return ElMessage.error('请输入正确的精网号');
}
if (refundFormData.value.jwcode.length > 8) {
return ElMessage.error('精网号长度不能超过8位');
}
}
if (refundFormData.value.refundModel == 0) {
refundFormData.value.partRefundGold = refundFormData.value.permanentGold,
refundFormData.value.partRefundFree = refundFormData.value.freeGold
@ -1238,17 +1253,17 @@ const getAdminData = async () => {
adminData.value = result;
//
if (adminData.value.roleId === 2) {
superAdmin.value = true;
//
if (adminData.value.markets === '总部' || adminData.value.markets === '研发部') {
ElMessageBox.alert(
'管理员账号仅显示所属地区的财务数据,请确认地区设置',
'温馨提示',
{ type: 'warning' }
);
}
}
// if (adminData.value.roleId === 2) {
// superAdmin.value = true;
// //
// if (adminData.value.markets === '' || adminData.value.markets === '') {
// ElMessageBox.alert(
// '',
// '',
// { type: 'warning' }
// );
// }
// }
} catch (error) {
console.error('管理员信息获取失败:', error);
ElMessage.error('管理员信息加载异常');

52
src/views/moneyManage/receiveDetail/receiveHead.vue

@ -617,10 +617,10 @@ const exportExcel = async function () {
payCurrencySelect = CurrencyForId(searchData.value.paymentCurrency);
}
if (searchData.value.jwcode && !isNumber(searchData.value.jwcode)) {
ElMessage.error('精网号只能是数字')
return
}
// if (searchData.value.jwcode && !isNumber(searchData.value.jwcode)) {
// ElMessage.error('')
// return
// }
const cashRoleId = '2';
const submitterMarket = adminData.value.markets;
@ -783,12 +783,17 @@ const getlist = async () => {
ElMessage.error('请输入正确的精网号')
return;
}
// 8
if (searchData.value.jwcode.length > 8) {
ElMessage.error('精网号长度不能超过8位')
return;
}
}
if (searchData.value.jwcode && !isNumber(searchData.value.jwcode)) {
ElMessage.error('精网号只能是数字')
return
}
// if (searchData.value.jwcode && !isNumber(searchData.value.jwcode)) {
// ElMessage.error('')
// return
// }
const result = await request({
url: '/cashCollection/selectCollection',
@ -829,7 +834,6 @@ const resetRefund = () => {
const submitRefund = async () => {
try {
if (refundFormData.value.goodsName != '金币充值') {
return ElMessage.error('线上数据仅支持金币充值退款');
}
if (!refundFormData.value.refundModel) {
@ -838,6 +842,16 @@ const submitRefund = async () => {
if (!refundFormData.value.refundReason) {
return ElMessage.error('请输入退款原因');
}
//
if (refundFormData.value.jwcode) {
const isPositiveInteger = /^[1-9]\d*$/.test(refundFormData.value.jwcode);
if (!isPositiveInteger) {
return ElMessage.error('精网号格式不正确,必须为正整数');
}
if (refundFormData.value.jwcode.length > 20) {
return ElMessage.error('精网号长度不能超过20位');
}
}
if (refundFormData.value.refundModel == 0) {
refundFormData.value.partRefundGold = refundFormData.value.permanentGold,
refundFormData.value.partRefundFree = refundFormData.value.freeGold
@ -1043,16 +1057,16 @@ const getAdminData = async () => {
adminData.value = result;
//
if (adminData.value.roleId === 2) {
//
if (adminData.value.markets === '总部' || adminData.value.markets === '研发部') {
ElMessageBox.alert(
'管理员账号仅显示所属地区的财务数据,请确认地区设置',
'温馨提示',
{ type: 'warning' }
);
}
}
// if (adminData.value.roleId === 2) {
// //
// if (adminData.value.markets === '' || adminData.value.markets === '') {
// ElMessageBox.alert(
// '',
// '',
// { type: 'warning' }
// );
// }
// }
} catch (error) {
console.error('管理员信息获取失败:', error);
ElMessage.error('管理员信息加载异常');

47
src/views/moneyManage/receiveDetail/receiveManage.vue

@ -209,7 +209,7 @@
@click="openAuditForm(scope.row)">审核
</el-link>
<el-link
v-else-if="activeTab == 'pass' && !(scope.row.status == 6 || scope.row.status == 4) && scope.row.receivedMarket == scope.row.submitterMarket"
v-else-if="activeTab == 'pass' && !(scope.row.status == 6 || scope.row.status == 4) && scope.row.receivedMarket == adminData.markets"
style="color: #2741DE;" @click="openEditForm(scope.row)">编辑
</el-link>
<el-link
@ -622,9 +622,6 @@ import _ from 'lodash';
import { Plus } from '@element-plus/icons-vue';
import { startsWith } from './utils/util.js'
import { isNumber } from 'lodash'
//
const market = ref([])
//
import CurrencySelect from '@/components/MoneyManage/CurrencySelect.vue';
@ -649,6 +646,8 @@ const tableData = ref([]);
const total = ref(0);
const pageInfo = ref({ pageSize: 10, pageNum: 1 });
//
const market = ref([])
//
const searchData = ref({});
@ -763,10 +762,10 @@ const exportExcel = async function () {
payCurrencySelect = CurrencyForId(searchData.value.paymentCurrency);
}
if (searchData.value.jwcode && !isNumber(searchData.value.jwcode)) {
ElMessage.error('精网号只能是数字')
return
}
// if (searchData.value.jwcode && !isNumber(searchData.value.jwcode)) {
// ElMessage.error('')
// return
// }
const cashRoleId = '1';
const submitterMarket = adminData.value.markets;
@ -883,6 +882,11 @@ const getlist = async () => {
payCurrencySelect = CurrencyForId(searchData.value.paymentCurrency);
}
// if (searchData.value.jwcode && !isNumber(searchData.value.jwcode)) {
// ElMessage.error('')
// return
// }
// ID=1
const cashRoleId = '1';
const receivedMarket = adminData.value.markets;
@ -903,6 +907,11 @@ const getlist = async () => {
ElMessage.error('请输入正确的精网号')
return;
}
// 8
if (searchData.value.jwcode.length > 8) {
ElMessage.error('精网号长度不能超过8位')
return;
}
}
const result = await request({
url: '/cashCollection/selectCollection',
@ -1234,17 +1243,17 @@ const getAdminData = async () => {
adminData.value = result;
//
if (adminData.value.roleId === 2) {
superAdmin.value = true;
//
if (adminData.value.markets === '总部' || adminData.value.markets === '研发部') {
ElMessageBox.alert(
'管理员账号仅显示所属地区的财务数据,请确认地区设置',
'温馨提示',
{ type: 'warning' }
);
}
}
// if (adminData.value.roleId === 2) {
// superAdmin.value = true;
// //
// if (adminData.value.markets === '' || adminData.value.markets === '') {
// ElMessageBox.alert(
// '',
// '',
// { type: 'warning' }
// );
// }
// }
} catch (error) {
console.error('管理员信息获取失败:', error);
ElMessage.error('管理员信息加载异常');

26
src/views/moneyManage/receiveDetail/receiveService.vue

@ -525,12 +525,17 @@ const getlist = async () => {
ElMessage.error('请输入正确的精网号')
return;
}
//
if (searchData.value.jwcode.length > 8) {
ElMessage.error('精网号长度不能超过8位')
return;
}
}
if (searchData.value.jwcode && !isNumber(searchData.value.jwcode)) {
ElMessage.error('精网号只能是数字')
return
}
// if (searchData.value.jwcode && !isNumber(searchData.value.jwcode)) {
// ElMessage.error('')
// return
// }
const result = await request({
url: '/cashCollection/selectCollection',
@ -984,6 +989,19 @@ const submitRefund = async () => {
return
}
}
//
if (refundFormData.value.jwcode) {
const isPositiveInteger = /^[1-9]\d*$/.test(refundFormData.value.jwcode);
if (!isPositiveInteger) {
ElMessage.error('请输入正确的精网号')
return;
}
if (refundFormData.value.jwcode.length > 8) {
ElMessage.error('精网号长度不能超过8位')
return;
}
}
const result = await request({
url: '/Money/add',
data: {

32
src/views/moneyManage/refundDetail/refundCharge.vue

@ -117,11 +117,11 @@
</div>
<div class="top-item">
<el-text style="width:4vw;" size="small">永久金币</el-text>
<el-input v-model="auditRow.permanentGold" size="small" style="width:10vw;" disabled />&nbsp;
<el-input v-model="auditRow.gold" size="small" style="width:10vw;" disabled />&nbsp;
</div>
<div class="top-item">
<el-text style="width:4vw;" size="small">免费金币</el-text>
<el-input v-model="auditRow.freeGold" size="small" style="width:10vw;" disabled />&nbsp;
<el-input v-model="auditRow.free" size="small" style="width:10vw;" disabled />&nbsp;
</div>
<div class="top-item">
<el-text style="width:4vw;" size="small">退款理由</el-text>
@ -421,9 +421,17 @@ const getRefund = async function () {
const goodsName = searchForm.value.goodsName && searchForm.value.goodsName.length > 0
? searchForm.value.goodsName[searchForm.value.goodsName.length - 1] : ''
if (searchForm.value.jwcode && !isNumber(searchForm.value.jwcode)) {
ElMessage.error('精网号必须为数字')
return
if (searchForm.value.jwcode) {
const isPositiveInteger = /^[1-9]\d*$/.test(searchForm.value.jwcode);
if (!isPositiveInteger) {
ElMessage.error('请输入正确的精网号')
return;
}
}
// 400
if (searchForm.value.jwcode.length > 8) {
ElMessage.error('精网号长度不能超过8位')
return;
}
if (searchForm.value.paymentCurrency) {
@ -592,9 +600,17 @@ const exportExcel = async function () {
const goodsName = searchForm.value.goodsName && searchForm.value.goodsName.length > 0
? searchForm.value.goodsName[searchForm.value.goodsName.length - 1] : ''
if (searchForm.value.jwcode && !isNumber(searchForm.value.jwcode)) {
ElMessage.error('精网号必须为数字')
return
if (searchForm.value.jwcode) {
const isPositiveInteger = /^[1-9]\d*$/.test(searchForm.value.jwcode);
if (!isPositiveInteger) {
ElMessage.error('请输入正确的精网号')
return
}
}
// 400
if (searchForm.value.jwcode.length > 8) {
ElMessage.error('精网号长度不能超过8位')
return;
}
if (searchForm.value.paymentCurrency) {

37
src/views/moneyManage/refundDetail/refundFinance.vue

@ -103,7 +103,8 @@
style="margin-top: 1vh;"></el-pagination>
</el-card>
<el-dialog v-model="showAudit" title="审核" class="audit" width="35vw" overflow draggable style="background-color: #F3FAFE !important;">
<el-dialog v-model="showAudit" title="审核" class="audit" width="35vw" overflow draggable
style="background-color: #F3FAFE !important;">
<div class="top">
<el-button @click="" class="smallTitle" size="small">退款申请信息</el-button>
<div class="top-item">
@ -115,11 +116,11 @@
</div>
<div class="top-item">
<el-text style="width:4vw;" size="small">永久金币</el-text>
<el-input v-model="auditRow.permanentGold" size="small" style="width:10vw;" disabled />&nbsp;
<el-input v-model="auditRow.gold" size="small" style="width:10vw;" disabled />&nbsp;
</div>
<div class="top-item">
<el-text style="width:4vw;" size="small">免费金币</el-text>
<el-input v-model="auditRow.freeGold" size="small" style="width:10vw;" disabled />&nbsp;
<el-input v-model="auditRow.free" size="small" style="width:10vw;" disabled />&nbsp;
</div>
<div class="top-item">
<el-text style="width:4vw;" size="small">退款理由</el-text>
@ -479,9 +480,17 @@ const getRefund = async function () {
const goodsName = searchForm.value.goodsName && searchForm.value.goodsName.length > 0
? searchForm.value.goodsName[searchForm.value.goodsName.length - 1] : ''
if (searchForm.value.jwcode && !isNumber(searchForm.value.jwcode)) {
ElMessage.error('精网号必须为数字')
return
if (searchForm.value.jwcode) {
const isPositiveInteger = /^[1-9]\d*$/.test(searchForm.value.jwcode);
if (!isPositiveInteger) {
ElMessage.error('请输入正确的精网号')
return;
}
}
// 400
if (searchForm.value.jwcode.length > 8) {
ElMessage.error('精网号长度不能超过8位')
return;
}
const params = {
@ -645,11 +654,19 @@ const exportExcel = async function () {
}
const goodsName = searchForm.value.goodsName && searchForm.value.goodsName.length > 0
? searchForm.value.goodsName[searchForm.value.goodsName.length - 1] : ''
? searchForm.value.goodsName[searchForm.value.goodsName.length - 1] : '';
if (searchForm.value.jwcode && !isNumber(searchForm.value.jwcode)) {
ElMessage.error('精网号必须为数字')
return
if (searchForm.value.jwcode) {
const isPositiveInteger = /^[1-9]\d*$/.test(searchForm.value.jwcode);
if (!isPositiveInteger) {
ElMessage.error('请输入正确的精网号')
return;
}
}
// 400
if (searchForm.value.jwcode.length > 8) {
ElMessage.error('精网号长度不能超过8位')
return;
}
const params = {

41
src/views/moneyManage/refundDetail/refundHeader.vue

@ -104,7 +104,8 @@
style="margin-top: 1vh;"></el-pagination>
</el-card>
<el-dialog v-model="showAudit2" title="审核" class="audit2" width="35vw" overflow draggable style="background-color: #F3FAFE !important;">
<el-dialog v-model="showAudit2" title="审核" class="audit2" width="35vw" overflow draggable
style="background-color: #F3FAFE !important;">
<div class="top">
<el-button @click="" class="smallTitle" size="small">退款申请信息</el-button>
<div class="top-item">
@ -116,11 +117,11 @@
</div>
<div class="top-item">
<el-text style="width:4vw;" size="small">永久金币</el-text>
<el-input v-model="auditRow.permanentGold" size="small" style="width:10vw;" disabled />&nbsp;
<el-input v-model="auditRow.gold" size="small" style="width:10vw;" disabled />&nbsp;
</div>
<div class="top-item">
<el-text style="width:4vw;" size="small">免费金币</el-text>
<el-input v-model="auditRow.freeGold" size="small" style="width:10vw;" disabled />&nbsp;
<el-input v-model="auditRow.free" size="small" style="width:10vw;" disabled />&nbsp;
</div>
<div class="top-item">
<el-text style="width:4vw;" size="small">退款理由</el-text>
@ -477,9 +478,17 @@ const getRefund = async function () {
const goodsName = searchForm.value.goodsName && searchForm.value.goodsName.length > 0
? searchForm.value.goodsName[searchForm.value.goodsName.length - 1] : ''
if (searchForm.value.jwcode && !isNumber(searchForm.value.jwcode)) {
ElMessage.error('精网号必须为数字')
return
if (searchForm.value.jwcode) {
const isPositiveInteger = /^[1-9]\d*$/.test(searchForm.value.jwcode);
if (!isPositiveInteger) {
ElMessage.error('请输入正确的精网号')
return;
}
}
// 400
if (searchForm.value.jwcode.length > 8) {
ElMessage.error('精网号长度不能超过8位')
return;
}
const params = {
@ -528,7 +537,8 @@ const handlePass = async function () {
permanentGold: auditRow.value.permanentGold * 100,
freeGold: auditRow.value.freeGold * 100,
orderCode: auditRow.value.orderCode,
jwcode: auditRow.value.jwcode
jwcode: auditRow.value.jwcode,
adminId: adminData.value.id
}
const result = await API({
url: '/Money/finalReview',
@ -557,7 +567,8 @@ const handleReject = async function () {
rejectReason: addForm.value.remark,
headFinance: adminData.value.adminName,
auditId: auditRow.value.auditId,
orderCode: auditRow.value.orderCode
orderCode: auditRow.value.orderCode,
adminId: adminData.value.id
}
const result = await API({
url: '/Money/finalReview',
@ -624,9 +635,17 @@ const exportExcel = async function () {
const goodsName = searchForm.value.goodsName && searchForm.value.goodsName.length > 0
? searchForm.value.goodsName[searchForm.value.goodsName.length - 1] : ''
if (searchForm.value.jwcode && !isNumber(searchForm.value.jwcode)) {
ElMessage.error('精网号必须为数字')
return
if (searchForm.value.jwcode) {
const isPositiveInteger = /^[1-9]\d*$/.test(searchForm.value.jwcode);
if (!isPositiveInteger) {
ElMessage.error('请输入正确的精网号')
return;
}
}
// 400
if (searchForm.value.jwcode.length > 8) {
ElMessage.error('精网号长度不能超过8位')
return;
}
const params = {

66
src/views/moneyManage/refundDetail/refundService.vue

@ -115,7 +115,8 @@
style="margin-top: 1vh;"></el-pagination>
</el-card>
<el-dialog v-model="showEdit" title="退款" class="editDialog" overflow draggable style="width: 40vw; background-color: #F3FAFE !important;">
<el-dialog v-model="showEdit" title="退款" class="editDialog" overflow draggable
style="width: 40vw; background-color: #F3FAFE !important;">
<div style="display: flex;">
<div class="left">
<div class="add-item">
@ -287,9 +288,17 @@ const getRefund = async function () {
const goodsName = searchForm.value.goodsName && searchForm.value.goodsName.length > 0
? searchForm.value.goodsName[searchForm.value.goodsName.length - 1] : ''
if (searchForm.value.jwcode && !isNumber(searchForm.value.jwcode)) {
ElMessage.error('精网号必须为数字')
return
if (searchForm.value.jwcode) {
const isPositiveInteger = /^[1-9]\d*$/.test(searchForm.value.jwcode);
if (!isPositiveInteger) {
ElMessage.error('请输入正确的精网号')
return;
}
}
// 400
if (searchForm.value.jwcode.length > 8) {
ElMessage.error('精网号长度不能超过8位')
return;
}
const params = {
@ -298,7 +307,7 @@ const getRefund = async function () {
cashRecordDTO: {
jwcode: searchForm.value.jwcode,//
name: searchForm.value.name,//
markets: searchForm.value.market && searchForm.value.market.length > 0 ? [searchForm.value.market[searchForm.value.market.length - 1]] : [],
markets: searchForm.value.market && searchForm.value.market.length > 0 ? [searchForm.value.market[searchForm.value.market.length - 1]] : [],
goodsName: goodsName,//
statuses: statusParam.value,//1012
// 2022
@ -360,6 +369,27 @@ const submitEdit = async function () {
}
try {
console.log(editRow.value)
if(!editForm.value.refundModel) {
ElMessage.error('请选择退款方式')
return
}else if(!editForm.value.refundReason) {
ElMessage.error('请输入退款理由')
return
}else if(editForm.value.refundModel == 1 && (!editForm.value.partRefundGold || !editForm.value.partRefundFree)) {
ElMessage.error('请输入退款金币数和免费金币数')
return
}else if (editForm.value.refundModel == 1 && (editForm.value.partRefundGold || editForm.value.partRefundFree)) {
const isPositiveInteger = /^[1-9]\d*$/.test(editForm.value.partRefundGold)
if (!isPositiveInteger) {
ElMessage.error('请输入正确的永久金币数')
return
}
const isPositiveInteger1 = /^[1-9]\d*$/.test(editForm.value.partRefundFree)
if (!isPositiveInteger1) {
ElMessage.error('请输入正确的免费金币数')
return
}
}
let params = {
id: editRow.value.id,
status: editRow.value.status,
@ -368,25 +398,25 @@ const submitEdit = async function () {
jwcode: editRow.value.jwcode,
paymentAmount: editRow.value.paymentAmount,
paymentCurrency: editRow.value.paymentCurrency,
newRefundGold: (editForm.value.partRefundGold*100),
newRefundFree: (editForm.value.partRefundFree)*100
newRefundGold: (editForm.value.partRefundGold * 100),
newRefundFree: (editForm.value.partRefundFree) * 100
}
console.log(editRow.value.goodsName);
if (editRow.value.goodsName != '金币充值') {
params.newRefundGold = ''
params.newRefundFree = ''
params.newRefundFree = ''
}
if(editRow.value.goodsName == '金币充值'){
if(editForm.value.partRefundGold>editRow.value.gold){
ElMessage.error('退款金币数不能大于原金币数')
return
}
if(editForm.value.partRefundFree>editRow.value.free){
ElMessage.error('退款免费金币数不能大于原免费金币数')
return
}
if (editRow.value.goodsName == '金币充值') {
if (editForm.value.partRefundGold > editRow.value.gold) {
ElMessage.error('退款金币数不能大于原金币数')
return
}
if (editForm.value.partRefundFree > editRow.value.free) {
ElMessage.error('退款免费金币数不能大于原免费金币数')
return
}
}
const result = await API({
url: '/Money/update',

911
src/views/workspace/index_.vue

@ -1,911 +0,0 @@
<template>
<div class="top">
<el-card style="width:10vw" class="center-card">数据总览</el-card>
<span class="text">
最后更新时间{{
workDataUpdateTime && workDataUpdateTime !== '1970-01-01 08:00:00' ? workDataUpdateTime : '该地区暂无数据'
}}
</span>
</div>
<div class="card">
<!-- 第一个卡片 -->
<el-card class="card-item">
<template #header>
<div class="card-title">当前金币余量</div>
<div>
<span style="font-weight: bold">{{ currentGold / 100
}}</span>&nbsp;&nbsp;&nbsp;&nbsp;较前一日
{{ dailyChange / 100 }}
<template v-if="dailyChange > 0">
<el-icon style="color:red">
<ArrowUpBold />
</el-icon>
</template>
<template v-else-if="dailyChange < 0">
<el-icon style="color:forestgreen">
<ArrowDownBold />
</el-icon>
</template>
<template v-else>
<el-icon style="color:grey">
<SemiSelect />
</el-icon>
</template>
</div>
</template>
<div>
<div class="margin-bottom">永久金币{{ currentPermanent / 100 }}</div>
<div class="margin-bottom">免费金币{{ currentFree / 100 }}</div>
<div class="margin-bottom">[六月到期|{{ currentFreeJune / 100 }}]&nbsp;&nbsp;
[十二月到期|{{ currentFreeDecember / 100 }}]
</div>
<div>任务金币{{ currentTask / 100 }}</div>
</div>
</el-card>
<!-- 第二个卡片 -->
<el-card class="card-item">
<div class="card-title">全年累计充值金币数</div>
<div class="card-title">{{ yearlyRecharge / 100 }}</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div>
<div class="center-card">折合新币累计金额:{{ yearlyMoney / 100 }}</div>
<template #footer>
<el-col class="margin-bottom center-card">昨日新增金币{{ recharge / 100 }}</el-col>
<el-col class="margin-bottom center-card">其中永久金币{{ money / 100 }}</el-col>
</template>
</el-card>
<!-- 第三个卡片 -->
<el-card class="card-item">
<div class="card-title">全年累计消费金币数</div>
<div class="card-title">{{ yearlyReduce / 100 }}</div>
<div style="padding-left: 30%;">消耗{{ yearlyConsume / 100 }}</div>
<div style="padding-left: 30%;">退款{{ yearlyRefund / 100 }}</div>
<template #footer>
<div style="margin-bottom:0.5%;padding-left: 30%;">昨日新增消费{{ dailyConsume / 100 }}</div>
<div style="margin-bottom:0.5%;padding-left: 30%;">昨日新增消耗{{ dailyReduce / 100 }}</div>
<div style="margin-bottom:0.5%;padding-left: 30%;">昨日新增退款{{ dailyRefund / 100 }}</div>
</template>
</el-card>
<!-- 第四个卡片 -->
<el-card class="card-item">
<el-col class="card-title">全年累计充值人头数</el-col>
<el-col class="card-title">{{ yearlyRechargeNum }}</el-col>
<el-col style="padding-left: 35%;">周同比:{{ sumWow }}%&nbsp;&nbsp;&nbsp;&nbsp;
<template v-if="sumWow > 0">
<el-icon style="color:red">
<ArrowUpBold />
</el-icon>
</template>
<template v-else-if="sumWow < 0">
<el-icon style="color:forestgreen">
<ArrowDownBold />
</el-icon>
</template>
<template v-else>
<el-icon style="color:grey">
<SemiSelect />
</el-icon>
</template>
</el-col>
<el-col style="padding-left: 35%;">日环比:{{ sumDaily }}%&nbsp;&nbsp;&nbsp;&nbsp;
<template v-if="sumDaily > 0">
<el-icon style="color:red">
<ArrowUpBold />
</el-icon>
</template>
<template v-else-if="sumDaily < 0">
<el-icon style="color:forestgreen">
<ArrowDownBold />
</el-icon>
</template>
<template v-else>
<el-icon style="color:grey">
<SemiSelect />
</el-icon>
</template>
</el-col>
<template #footer>
<el-col style="padding-left: 35%;margin-bottom:0.5%">昨日充值人数{{ ydayRechargeNum }}</el-col>
<el-col style="padding-left: 35%;">其中首充{{ firstRecharge }}</el-col>
</template>
</el-card>
</div>
<div class="graph">
<el-card style="width:84vw;">
<div>
<el-tabs v-model="activeTab" @tab-change="handleTabChange">
<el-tab-pane label="金币充值" name="recharge"></el-tab-pane>
<el-tab-pane label="金币消费" name="consume"></el-tab-pane>
</el-tabs>
</div>
<div class="condition">
<div class="stats">
<div v-if="activeTab === 'consume'">合计{{ sumConsume / 100 }}</div>&nbsp;&nbsp;
永久金币: {{ activeTab === 'recharge' ? sumRechargePermanent / 100 : sumConsumePermanent / 100 }}&nbsp;&nbsp;
免费金币: {{ activeTab === 'recharge' ? sumRechargeFree / 100 : sumConsumeFree / 100 }}&nbsp;&nbsp;
任务金币: {{ activeTab === 'recharge' ? sumRechargeTask / 100 : sumConsumeTask / 100 }}&nbsp;&nbsp;
</div>
<div>
<el-button @click="getYes()" size="small" :type="activeTimeRange === 'yes' ? 'primary' : ''">昨天
</el-button>
<el-button @click="getToday()" size="small" :type="activeTimeRange === 'today' ? 'primary' : ''">今天
</el-button>
<el-button @click="getWeek()" size="small" :type="activeTimeRange === 'week' ? 'primary' : ''">本周
</el-button>
<el-button @click="getMonth()" size="small" :type="activeTimeRange === 'month' ? 'primary' : ''">本月
</el-button>
<el-button @click="getYear()" size="small" :type="activeTimeRange === 'year' ? 'primary' : ''">本年
</el-button>
</div>
<div>
<el-date-picker size="small" v-model="dateRange" type="datetimerange" range-separator=""
start-placeholder="开始时间" end-placeholder="结束时间" format="YYYY-MM-DD HH:mm:ss"
style="width:20vw;margin-left:0.5vw;" value-format="YYYY-MM-DD HH:mm:ss" :default-time="defaultTime"
:disabled-date="disabledDate" @change="handleDatePickerChange" />
<el-button type="primary" size="small" style="margin-left: 0.5vw" @click="getChartData">查询</el-button>
</div>
</div>
<div class="graph-content">
<div ref="chartRef" class="left"></div>
<div class="right">
<el-card>
<div class="card-large">金币{{ activeTab === 'recharge' ? '充值' : '消费' }}排名</div>
<el-select v-model="selectedType" style="width: 100%; margin-bottom: 15px">
<el-option label="全部类型" value="all"></el-option>
<el-option label="永久金币" value="permanent"></el-option>
<el-option label="免费金币" value="free"></el-option>
<el-option label="任务金币" value="task"></el-option>
</el-select>
<el-table :data="tableData" height="320px">
<el-table-column prop="rank" label="排名" width="60" align="center"></el-table-column>
<el-table-column prop="market" label="地区" align="center">
<template #default="scope">
<span>{{ marketMapping[scope.row.market] || scope.row.market }}</span>
</template>
</el-table-column>
<el-table-column prop="coinAmount" label="金币数量" align="center">
<template #default="{ row }">
{{ row.coinAmount.toLocaleString() }}
</template>
</el-table-column>
</el-table>
</el-card>
</div>
</div>
</el-card>
</div>
</template>
<script setup>
import * as echarts from 'echarts'
import { ref, onMounted, nextTick, watch, onUnmounted } from 'vue'
import API from '@/util/http'
import { ElMessage } from 'element-plus'
import dayjs from 'dayjs';
import utc from 'dayjs-plugin-utc'
import weekday from 'dayjs/plugin/weekday'
dayjs.extend(utc)
import { ArrowUpBold, ArrowDownBold, SemiSelect } from '@element-plus/icons-vue'
import { marketMapping } from "@/utils/marketMap.js";
const defaultTime = [
new Date(2000, 1, 1, 0, 0, 0),
new Date(2000, 2, 1, 23, 59, 59),
]
//
const markets = ref([])
//
const dateRange = ref([])
const activeTab = ref('recharge')
const selectedType = ref('all')
const tableData = ref([])
const chartRef = ref(null)
let chartInstance = null
//
const sumRechargePermanent = ref(0)
const sumRechargeFree = ref(0)
const sumRechargeTask = ref(0)
const sumConsumePermanent = ref(0)
const sumConsumeFree = ref(0)
const sumConsumeTask = ref(0)
const sumConsume = ref(0)
//
const adminData = ref({})
//
const currentGold = ref(0)
const dailyChange = ref(0)
const currentPermanent = ref(0)
const currentFree = ref(0)
const currentFreeJune = ref(0)
const currentFreeDecember = ref(0)
const currentTask = ref(0)
const yearlyRecharge = ref(0)
const yearlyMoney = ref(0)
const recharge = ref(0)
const money = ref(0)
const yearlyReduce = ref(0)
const yearlyConsume = ref(0)
const yearlyRefund = ref(0)
const dailyReduce = ref(0)
const dailyConsume = ref(0)
const dailyRefund = ref(0)
const yearlyRechargeNum = ref(0)
const sumWow = ref(0)
const sumDaily = ref(0)
const rechargeNum = ref(0)
const ydayRechargeNum = ref(0)
const firstRecharge = ref(0)
const length = ref(0)
//
const chartLoading = ref(true)
const handleResize = () => {
if (chartInstance.value) {
try {
chartInstance.value.resize()
console.log('resize一下')
} catch (error) {
console.error('图表resize失败:', error)
}
}
}
//
const initChart = () => {
if (!chartInstance && chartRef.value) {
chartInstance = echarts.init(chartRef.value)
window.addEventListener('resize', handleResize)
}
}
//
const destroyChart = () => {
if (chartInstance.value) {
try {
chartInstance.value.dispose()
} catch (error) {
console.error('图表销毁失败:', error)
}
chartInstance.value = null
}
window.removeEventListener('resize', handleResize)
}
const formatDate = function (date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
//
const getYes = function () {
const yesterday = dayjs().subtract(1, 'day')
const startTime = yesterday.startOf('day').format('YYYY-MM-DD HH:mm:ss')
const endTime = yesterday.endOf('day').format('YYYY-MM-DD HH:mm:ss')
dateRange.value = [startTime, endTime]
console.log('看看dateRange', dateRange.value)
activeTimeRange.value = 'yes' //
getChartData()
}
//
const getToday = function () {
const today = dayjs()
const startTime = today.startOf('day').format('YYYY-MM-DD HH:mm:ss')
const endTime = today.endOf('day').format('YYYY-MM-DD HH:mm:ss')
// const endTime = today.add(1, 'day').startOf('day').format('YYYY-MM-DD HH:mm:ss')
dateRange.value = [startTime, endTime]
console.log('看看dateRange', dateRange.value)
activeTimeRange.value = 'today' //
getChartData()
}
//
const getWeek = function () {
const today = dayjs();
// 01...6
const day = today.day();
// 6
let monday = today.subtract(day === 0 ? 6 : day - 1, 'day');
// (7 - day)
let sunday = today.add(day === 0 ? 0 : 7 - day, 'day');
//
const startTime = monday.startOf('day').format('YYYY-MM-DD HH:mm:ss');
const endTime = sunday.endOf('day').format('YYYY-MM-DD HH:mm:ss');
dateRange.value = [startTime, endTime];
console.log('本周时间范围(周一到周日):', dateRange.value);
activeTimeRange.value = 'week';
getChartData();
};
//
const getMonth = function () {
const today = dayjs()
const startTime = today.startOf('month').format('YYYY-MM-DD HH:mm:ss')
// const endTime = today.add(1, 'month').startOf('month').format('YYYY-MM-DD HH:mm:ss')
const endTime = today.endOf('month').format('YYYY-MM-DD HH:mm:ss')
dateRange.value = [startTime, endTime]
console.log('看看dateRange', dateRange.value)
activeTimeRange.value = 'month' //
getChartData()
}
//
const getYear = function () {
const today = dayjs()
const startTime = today.startOf('year').format('YYYY-MM-DD HH:mm:ss')
const endTime = today.endOf('year').format('YYYY-MM-DD HH:mm:ss')
// const endTime = today.add(1, 'year').startOf('year').format('YYYY-MM-DD HH:mm:ss')
dateRange.value = [startTime, endTime]
console.log('看看dateRange', dateRange.value)
activeTimeRange.value = 'year' //
getChartData()
}
// ( = + 6 + 12 + + )
const processData = (data) => {
const summary = {
currentGold: 0,
dailyChange: 0,
currentPermanent: 0,
currentFreeJune: 0,
currentFreeDecember: 0,
currentTask: 0,
currentFree: 0,
recharge: 0,
money: 0,
yearlyRecharge: 0,
yearlyMoney: 0,
consumePermanent: 0,
consumeFreeJune: 0,
consumeFreeDecember: 0,
consumeTask: 0,
refundPermanent: 0,
refundFreeJune: 0,
refundFreeDecember: 0,
refundTask: 0,
dailyReduce: 0,
yearlyConsume: 0,
yearlyRefund: 0,
yearlyReduce: 0,
rechargeNum: 0,
ydayRechargeNum: 0,
firstRecharge: 0,
sumWow: 0,
sumDaily: 0,
yearlyRechargeNum: 0
}
//
data.marketCards.forEach(market => {
for (const i in summary) {
if (market[i] !== undefined && market[i] !== null) { // number
summary[i] += market[i]
}
}
})
// wowdaily
length.value = data.markets.length
console.log(length.value)
// 退
const yesterdayConsume = summary.consumePermanent + summary.consumeFreeJune + summary.consumeFreeDecember + summary.consumeTask
const yesterdayRefund = summary.refundPermanent + summary.refundFreeJune + summary.refundFreeDecember + summary.refundTask
//
currentGold.value = summary.currentGold.toFixed(2)
dailyChange.value = summary.dailyChange.toFixed(2)
currentPermanent.value = summary.currentPermanent.toFixed(2)
currentFree.value = summary.currentFree.toFixed(2)
currentFreeJune.value = summary.currentFreeJune.toFixed(2)
currentFreeDecember.value = summary.currentFreeDecember.toFixed(2)
currentTask.value = summary.currentTask.toFixed(2)
yearlyRecharge.value = summary.yearlyRecharge.toFixed(2)
yearlyMoney.value = summary.yearlyMoney.toFixed(2)
recharge.value = summary.recharge.toFixed(2)
money.value = summary.money.toFixed(2)
yearlyReduce.value = summary.yearlyReduce.toFixed(2)
yearlyConsume.value = summary.yearlyConsume.toFixed(2)
yearlyRefund.value = summary.yearlyRefund.toFixed(2)
dailyReduce.value = summary.dailyReduce.toFixed(2)
dailyConsume.value = yesterdayConsume.toFixed(2)
dailyRefund.value = yesterdayRefund.toFixed(2)
yearlyRechargeNum.value = summary.yearlyRechargeNum
// //
// sumWow.value = (marketCards.sumWow / length.value).toFixed(2)
// //
// sumDaily.value = (marketCards.sumDaily / length.value).toFixed(2)
// rechargeNum.value = summary.rechargeNum
ydayRechargeNum.value = summary.ydayRechargeNum
firstRecharge.value = summary.firstRecharge
}
//
const disabledDate = (time) => {
const limitDate = new Date(2025, 0, 1);
return time.getTime() < limitDate.getTime();
}
//
const getMarkets = async () => {
console.log("adminData", adminData.value.account)
try {
const response = await API({
url: '/general/adminMarkets',
data: {
account: adminData.value.account
}
})
if (Array.isArray(response.data)) {
// markets.value = response.data.filter(data => data !== "1")
markets.value = response.data
console.log('市场列表获取成功:', markets.value)
} else {
console.error('获取市场列表失败', response)
ElMessage.error('获取市场列表失败')
}
} catch (error) {
console.error('获取市场列表失败:', error)
ElMessage.error('获取市场列表失败')
}
}
//
const getChartData = async () => {
try {
//
if (!markets.value || markets.value.length === 0) {
await getMarkets()
}
//
if (!dateRange.value || dateRange.value.length === 0) {
getYear()
}
const params = {
markets: markets.value,
startDate: dateRange.value[0],
endDate: dateRange.value[1]
};
const response = await API({
url: '/workbench/getGraph',
data: params
})
console.log('看看params', params)
if (Array.isArray(response.marketGraphs)) {
// const filteredGraphs = response.marketGraphs.filter(data => data.market !== "1");
//
processChartData(response.marketGraphs)
//
processRankingData(response.marketGraphs)
} else {
console.error('获取图表数据失败:', response)
ElMessage.error('获取图表数据失败')
}
} catch (error) {
console.error('获取图表数据失败:', error)
ElMessage.error('获取图表数据失败')
}
}
//
const processChartData = (marketCards) => {
const chartData = {
rechargePermanent: [],
rechargeFree: [],
rechargeTask: [],
consumePermanent: [],
consumeFree: [],
consumeTask: [],
sumConsume: []
}
//
const sumRechargePermanent1 = ref(0)
const sumRechargeFree1 = ref(0)
const sumRechargeTask1 = ref(0)
const sumConsumePermanent1 = ref(0)
const sumConsumeFree1 = ref(0)
const sumConsumeTask1 = ref(0)
const sumConsume1 = ref(0)
marketCards.forEach(market => {
chartData.rechargePermanent.push(market.sumRechargePermanent / 100 || 0)
chartData.rechargeFree.push(market.sumRechargeFree / 100 || 0)
chartData.rechargeTask.push(market.sumRechargeTask / 100 || 0)
chartData.consumePermanent.push(market.sumConsumePermanent / 100 || 0)
chartData.consumeFree.push(market.sumConsumeFree / 100 || 0)
chartData.consumeTask.push(market.sumConsumeTask / 100 || 0)
chartData.sumConsume.push(market.sumConsume / 100 || 0)
//
sumRechargePermanent1.value += (market.sumRechargePermanent || 0)
sumRechargeFree1.value += (market.sumRechargeFree || 0)
//sumRechargeTask1.value += (market.sumRechargeTask || 0)
sumConsumePermanent1.value += (market.sumConsumePermanent || 0)
sumConsumeFree1.value += (market.sumConsumeFree || 0)
sumConsumeTask1.value += (market.sumConsumeTask || 0)
sumConsume1.value += (market.sumConsume || 0)
})
sumRechargePermanent.value = sumRechargePermanent1.value
sumRechargeFree.value = sumRechargeFree1.value
sumRechargeTask.value = 0
sumConsumePermanent.value = sumConsumePermanent1.value
sumConsumeFree.value = sumConsumeFree1.value
sumConsumeTask.value = sumConsumeTask1.value
sumConsume.value = sumConsume1.value
updateChart(chartData)
}
const processRankingData = (marketCards) => {
//
const rankingData = marketCards.map(market => {
let coinAmount = 0;
if (activeTab.value === 'recharge') {
//
switch (selectedType.value) {
case 'all':
coinAmount = (market.sumRechargePermanent / 100 || 0) + (market.sumRechargeFree / 100 || 0) + (market.sumRechargeTask / 100 || 0);
break;
case 'permanent':
coinAmount = market.sumRechargePermanent / 100 || 0;
break;
case 'free':
coinAmount = market.sumRechargeFree / 100 || 0;
break;
case 'task':
coinAmount = market.sumRechargeTask / 100 || 0;
break;
}
} else {
//
switch (selectedType.value) {
case 'all':
coinAmount = (market.sumConsumePermanent / 100 || 0) + (market.sumConsumeFree / 100 || 0) + (market.sumConsumeTask / 100 || 0);
break;
case 'permanent':
coinAmount = market.sumConsumePermanent / 100 || 0;
break;
case 'free':
coinAmount = market.sumConsumeFree / 100 || 0;
break;
case 'task':
coinAmount = market.sumConsumeTask / 100 || 0;
break;
}
}
return {
market: market.market,
coinAmount: coinAmount
};
});
//
rankingData.sort((a, b) => b.coinAmount - a.coinAmount);
//
tableData.value = rankingData.map((item, index) => ({
rank: index + 1,
...item
}));
}
watch(selectedType, () => {
getChartData();
});
//
const updateChart = (chartData) => {
if (!chartInstance) {
initChart()
}
chartLoading.value = true
try {
let series = []
let legend = []
if (activeTab.value === 'recharge') {
series = [
{
name: '永久金币',
type: 'bar',
stack: 'recharge',
data: chartData.rechargePermanent,
itemStyle: { color: '#5470c6' },
barWidth: 30
},
{
name: '免费金币',
type: 'bar',
stack: 'recharge',
data: chartData.rechargeFree,
itemStyle: { color: '#91cc75' },
barWidth: 30
},
{
name: '任务金币',
type: 'bar',
stack: 'recharge',
data: chartData.rechargeTask,
itemStyle: { color: '#fac858' },
barWidth: 30
}
]
legend = ['永久金币', '免费金币', '任务金币']
} else {
series = [
{
name: '永久金币',
type: 'bar',
stack: 'consume',
data: chartData.consumePermanent,
itemStyle: { color: '#5470c6' },
barWidth: 30
},
{
name: '免费金币',
type: 'bar',
stack: 'consume',
data: chartData.consumeFree,
itemStyle: { color: '#91cc75' },
barWidth: 30
},
{
name: '任务金币',
type: 'bar',
stack: 'consume',
data: chartData.consumeTask,
itemStyle: { color: '#fac858' },
barWidth: 30
}
]
legend = ['永久金币', '免费金币', '任务金币']
}
const option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
},
formatter: function (params) {
let result = params[0].name + '<br/>'
let total = 0;
params.forEach(param => {
result += `${param.seriesName}: ${param.value.toLocaleString()}<br/>`;
total += param.value;
})
result += `${activeTab.value === 'recharge' ? '充值' : '消费'}: ${total.toLocaleString()}`;
return result
}
},
legend: {
data: legend,
bottom: 10
},
grid: {
left: '3%',
right: '4%',
bottom: '10%',
containLabel: true
},
xAxis: {
type: 'category',
data: markets.value,
axisLabel: {
interval: 0,
rotate: 30
}
},
yAxis: {
type: 'value',
axisLabel: {
formatter: function (value) {
return value.toLocaleString()
}
}
},
series: series,
// dataZoom: [
// {
// type: 'slider',
// show: true,
// start: 0,
// end: 100,
// maxSpan: 100,
// minSpan: 100,
//
// height: 2,
// },
// ]
}
chartInstance.setOption(option)
} catch (error) {
console.error('图表更新失败:', error)
ElMessage.error('图表渲染失败')
} finally {
setTimeout(() => {
chartLoading.value = false
}, 300)
}
}
//
const handleTabChange = () => {
getChartData()
console.log('标签切换调用图表')
}
const getAdminData = async function () {
try {
const result = await API({ url: '/admin/userinfo', data: {} })
adminData.value = result
console.log('用户信息', adminData.value)
} catch (error) {
console.log('请求失败', error)
}
}
//
const getCardData = async () => {
try {
const response = await API({ url: '/workbench/getCard', data: {} })
workDataUpdateTime.value = response.updateTime
//
sumWow.value = response.sumWow.toFixed(2)
//
sumDaily.value = response.sumDaily.toFixed(2)
if (response && response.data) {
processData(response.data)
} else if (Array.isArray(response?.marketCards)) {
processData(response)
} else {
console.error('无效的API响应结构:', response)
}
} catch (error) {
console.error('获取卡片数据失败:', error)
}
}
const workDataUpdateTime = ref(null)
//
const activeTimeRange = ref('')
//
const handleDatePickerChange = () => {
activeTimeRange.value = ''
}
onMounted(async () => {
await getAdminData()
await getCardData()
await getMarkets()
getYear()
window.addEventListener('resize', () => {
chartInstance.resize()
})
})
onUnmounted(() => {
destroyChart()
})
</script>
<style scoped>
.top {
height: 5.5vh;
width: 80vw;
display: flex;
margin-bottom: 0.5vh;
.text {
margin-left: 2vw;
width: 20vw;
display: flex;
align-items: center;
font-size: 18px;
}
}
.card {
height: 28vh;
margin-bottom: 0.5vh;
display: flex;
justify-content: center;
}
.graph {
width: 100%;
display: flex;
height: 64%;
.condition {
width: 100%;
height: 1%;
display: flex;
align-items: center;
.stats {
display: flex;
align-items: center;
width: 35vw;
font-size: 15px;
}
}
.graph-content {
flex: 1;
height: auto;
display: flex;
.left {
width: 70%;
height: auto;
}
.right {
flex: 1;
padding: 0.5vw 2vh;
}
}
}
.center-card {
display: flex;
justify-content: center;
align-items: center;
}
.margin-bottom {
margin-bottom: 0.5vh;
}
.card-item {
width: 25%;
height: 28vh;
display: flex;
flex-direction: column;
justify-content: center;
margin-right: 0.25vw;
}
.card-title {
font-weight: bold;
margin-bottom: 1vh;
display: flex;
justify-content: center;
align-items: center;
}
.card-large {
font-weight: bold;
font-size: 16px;
text-align: center;
margin-bottom: 15px;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>
Loading…
Cancel
Save