Browse Source

Merge branch 'refs/heads/milestone-20250728-金币前端三期' into lihui/feature-20250728114233-金币前端三期

zhangrenyuan/feature-20250728113353-金币前端三期
lihui 2 weeks ago
parent
commit
ed438fb656
  1. 6
      .env.development
  2. 6
      src/router/index.js
  3. 754
      src/views/consume/articleVideo.vue
  4. 725
      src/views/consume/dieHardFan.vue
  5. 720
      src/views/consume/liveStream.vue
  6. 292
      src/views/recharge/addBeanRecharge.vue
  7. 442
      src/views/recharge/addCoinRecharge.vue
  8. 16
      src/views/recharge/beanRecharge.vue

6
.env.development

@ -1,12 +1,12 @@
# VITE_API_BASE='https://hwjb.homilychart.com/dev/admin'
VITE_API_BASE='https://hwjb.homilychart.com/dev/admin'
# 测试环境
# VITE_API_BASE='http://18.143.76.3:10704/'
# VITE_API_BASE='http://192.168.9.52:10705/'
VITE_UPLOAD_URL=http://39.101.133.168:8828/hljw/api/aws/upload
VITE_API_BASE='http://192.168.9.28:8081/'
# VITE_API_BASE='http://192.168.9.28:8081/'
# VITE_API_BASE='http://192.168.9.28:8081/'
# sunjiabei
# VITE_API_BASE='http://192.168.9.28:8081/'
# VITE_API_BASE='http://192.168.5.92:8081/'
# zhangyong
# VITE_API_BASE='http://192.168.3.83:8081/'
# VITE_API_BASE='http://192.168.9.62:8081/'

6
src/router/index.js

@ -161,21 +161,21 @@ const routes = [
path: 'add',
name: "addBeanRecharge",
component: () => import("../views/recharge/addBeanRecharge.vue"),
meta: {permissionId: 17} // 对应"提交金币充值"id=17
meta: {permissionId: 46} // 对应"提交金豆充值"id=46
},
// 金豆系统充值
{
path: 'system',
name: "beanSystemRecharge",
component: () => import("../views/recharge/beanSystemRecharge.vue"),
meta: {permissionId: 18} // 对应"查看金币充值明细"id=18
meta: {permissionId: 47} // 对应"查看金豆系统充值明细"id=47
},
// 金豆线上充值
{
path: 'online',
name: "beanOnlineRecharge",
component: () => import("../views/recharge/beanOnlineRecharge.vue"),
meta: {permissionId: 18} // 对应"查看金币充值明细"id=18
meta: {permissionId: 48} // 对应"查看金豆线上充值明细"id=48
}
]
},

754
src/views/consume/articleVideo.vue

@ -1,11 +1,759 @@
<script setup lang="ts">
<script setup>
import { computed, onMounted, ref } from 'vue'
import { dayjs, ElMessage } from 'element-plus'
import request from '@/util/http'
import API from '@/util/http'
import moment from 'moment'
//
/*
====================工具方法==============================
*/
//
const formatTime = (val) => val ? dayjs(val).format('YYYY-MM-DD HH:mm:ss') : ''
/*
====================数据=================================
*/
//
const adminData = ref({})
//
const tableData = ref([])
// articleVideo
const articleVideo = ref({
jwcode: null,
dept: "",
type: "",
articleVideoId: "",
articleVideoTitle: "",
author: "",
startTime: '',
endTime: '',
})
//
const channels = ref([])
//
const consumeTypes = ref([
{ label: '发礼物', value: 1 },
{ label: '发红包', value: 2 },
{ label: '发福袋', value: 3 },
{ label: '付费直播', value: 4 },
{ label: '加入粉丝团', value: 5 },
{ label: '发弹幕', value: 6 }
])
//
const handleTypeChange = (value) => {
if (value !== 1) {
articleVideo.value.gift = ''
}
}
//------------------------
//
const activeTimeRange = ref('')
//
const handleDatePickerChange = () => {
activeTimeRange.value = ''
}
//
const getObj = ref({
pageNum: 1,
pageSize: 50
})
//
const total = ref(100)
//
const getTime = ref({
startTime: '',
endTime: ''
})
//
// const activity = ref([])
//
const dept = ref([])
//
const filterChannel = (query) => {
if (query) {
return channels.value.filter(item => item.toLowerCase().includes(query.toLowerCase()));
}
return channels.value;
};
//
const sortField = ref('')
const sortOrder = ref('')
// //
// const consumePlatform = [
// {
// value: '',
// label: ''
// },
// {
// value: 'HomilyChart',
// label: 'HomilyChart'
// },
// {
// value: 'HomilyLink',
// label: 'HomilyLink'
// },
// {
// value: 'ERP',
// label: 'ERP'
// },
// {
// value: '',
// label: ''
// },
// {
// value: '',
// label: ''
// },
// ]
// //
// const tableDataTotal = ref({})
// const permanentGold = ref(0)
// const freeGold = ref(0)
// const taskGold = ref(0)
// const totalGold = ref(0)
// //
// const permanentGolds = ref(0)
// const freeGolds = ref(0)
// const taskGolds = ref(0)
// //
// const goods = ref([])
// const totalGoldSearch = ref({
// jwcode: null,
// payPlatform: "",
// dept: "",
// startTime: "",
// endTime: "",
// goodsName: ""
// })
/*
====================方法=================================
*/
//
const getAdminData = async function () {
try {
const result = await request({
url: '/admin/userinfo',
data: {}
})
adminData.value = result
console.log('请求成功', result)
console.log('用户信息', adminData.value)
} catch (error) {
console.log('请求失败', error)
}
}
// todo
// const ConsumeSelectBy = async function (val) {
// try {
// //
// if (typeof val === 'number') {
// getObj.value.pageNum = val
// }
// //
// if (getTime.value != null) {
// if (getTime.value.startTime != '' && getTime.value.endTime != '') {
// articleVideo.value.startTime = formatTime(getTime.value[0])
// articleVideo.value.endTime = formatTime(getTime.value[1])
// }
// } else {
// articleVideo.value.startTime = ''
// articleVideo.value.endTime = ''
// }
// articleVideo.value.sortField = sortField.value
// articleVideo.value.sortOrder = sortOrder.value
// console.log('_', articleVideo.value.startTime)
// console.log('1', getObj.value)
// console.log('2', articleVideo.value)
// // POST
// const result = await request({
// url: '/consume/selectBy',
// data: {
// pageNum: getObj.value.pageNum,
// pageSize: getObj.value.pageSize,
// articleVideo: {
// ... articleVideo.value,
// sortField: sortField.value,
// sortOrder: sortOrder.value
// }
// }
// })
// console.log('2', sortField)
// //
// // detail.value
// const detailWithoutSort = { ... articleVideo.value }
// delete detailWithoutSort.sortField
// delete detailWithoutSort.sortOrder
// //
// totalGoldSearch.value.startTime = articleVideo.value.startTime
// totalGoldSearch.value.endTime = articleVideo.value.endTime
// totalGoldSearch.value.payPlatform = articleVideo.value.payPlatform
// totalGoldSearch.value.dept = articleVideo.value.dept
// totalGoldSearch.value.goodsName = articleVideo.value.goodsName
// totalGoldSearch.value.jwcode = articleVideo.value.jwcode
// //
// const resultTotalGold = await request({
// // url: '/consume/statsGold',
// url: '/consume/statsGold',
// data: totalGoldSearch.value
// })
// console.log("", resultTotalGold)
// if (resultTotalGold.code === 200 && resultTotalGold.data) {
// const data = resultTotalGold.data
// console.log(':', data)
// permanentGolds.value = Number(data.permanentGolds) || 0
// freeGolds.value = Number(data.freeGolds) || 0
// taskGolds.value = Number(data.taskGolds) || 0
// }
// //
// tableData.value = result.data.list
// tableDataTotal.value = resultTotalGold.data
// if (resultTotalGold.data == null) {
// console.log('2', resultTotalGold)
// // 西
// tableDataTotal.value = resultTotalGold.data
// }
// const sumGoldList = tableData.value.map(item => item.sumGold);
// console.log("sumGold", sumGoldList); // sumGold
// console.log('@@@@@@@@@@tableDataT', tableDataTotal.value.list)
// // totalGold.value = tableData.value.sum
// // //
// // permanentGold.value = parseFloat(
// // (tableDataTotal.value.list.sumGold / 100).toFixed(2)
// // )
// // freeGold.value = parseFloat(
// // (tableDataTotal.value.sumFcion / 100).toFixed(2)
// // )
// // taskGold.value = parseFloat(
// // (tableDataTotal.value.sumTcion / 100).toFixed(2)
// // )
// // totalGold.value = parseFloat(
// // (tableDataTotal.value.sumcion / 100).toFixed(2)
// // )
// console.log('tableData', tableData.value)
// //
// total.value = result.data.total
// console.log('total', total.value)
// } catch (error) {
// console.log('', error)
// //
// }
// }
//
const search = function () {
getObj.value.pageNum = 1
// ConsumeSelectBy() todo
}
//
const reset = function () {
console.log('兄弟,你点了重置')
articleVideo.value.jwcode = null
articleVideo.value.type = ''
articleVideo.value.gift = ''
articleVideo.value.channel = ''
articleVideo.value.liveRoom = ''
articleVideo.value.dept = ''
articleVideo.value.startTime = ''
articleVideo.value.endTime = ''
sortField.value = ''
sortOrder.value = ''
getTime.value = {}
activeTimeRange.value = '' //
//
// ConsumeSelectBy() todo
console.log(' articleVideo', articleVideo.value)
}
//
const getToday = function () {
const today = new Date()
const startTime = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate()
)
const endTime = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate() + 1
)
getTime.value = [startTime, endTime]
console.log('getTime', getTime.value)
activeTimeRange.value = 'today' //
// ConsumeSelectBy()
}
//
const getYesterday = function () {
const yesterday = new Date()
yesterday.setDate(yesterday.getDate() - 1)
const startTime = new Date(
yesterday.getFullYear(),
yesterday.getMonth(),
yesterday.getDate()
)
const endTime = new Date(
yesterday.getFullYear(),
yesterday.getMonth(),
yesterday.getDate() + 1
)
getTime.value = [startTime, endTime]
console.log('getTime', getTime.value)
activeTimeRange.value = 'yesterday' //
// ConsumeSelectBy() //todo
}
// 7
const get7Days = function () {
const today = new Date()
const startTime = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate() - 6
)
const endTime = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate() + 1
)
getTime.value = [startTime, endTime]
console.log('getTime', getTime.value)
activeTimeRange.value = '7days' //
// ConsumeSelectBy() todo
}
//
// const getGoods = async function () {
// try {
// // POST
// const result = await request({
// url: '/general/goods',
// data: {}
// })
// //
// console.log('product', result)
// //
// goods.value = result.data
// console.log('goods ', goods.value) //
// } catch (error) {
// console.log('', error)
// //
// }
// }
//
const getDept = async function () {
try {
//
const result = await request({
// url: '/general/dept',
url: '/beanConsume/getDept', // todo
data: {account:adminData.value.account}
})
console.log('请求地区列表成功', result)
//
dept.value = result.data
console.log('地区数据', dept.value)
} catch (error) {
console.log('请求地区列表失败', error)
ElMessage({
type: 'error',
message: '获取地区列表失败,请稍后重试'
})
}
}
// //
// const handleSortChange = (column) => {
// console.log('', column.prop)
// console.log('', column.order)
// if (column.prop === 'permanentGold') {
// sortField.value = 'permanentGold'
// } else if (column.prop === 'taskGold') {
// sortField.value = 'taskGold'
// } else if (column.prop === 'freeGold') {
// sortField.value = 'freeGold'
// } else if (column.prop === 'createTime') {
// sortField.value = 'createTime'
// }
// sortOrder.value = column.order === 'ascending' ? 'DESC' : 'ASC'
// ConsumeSelectBy()
// }
// const handlePageSizeChange = function (val) {
// getObj.value.pageSize = val
// ConsumeSelectBy()
// }
// const handleCurrentChange = function (val) {
// getObj.value.pageNum = val
// ConsumeSelectBy()
// }
/*
====================计算属性=================================
*/
//
// const sumGold = computed(() => permanentGolds.value + freeGolds.value + taskGolds.value)
/*
====================监听=================================
*/
/*
====================挂载=================================
*/
onMounted(async function () {
await getAdminData()
// await ConsumeSelectBy()
// // getActivity();
await getDept()
// await getGoods()
})
const exportExcel = async function () {
// const params = { //
// articleVideo: {
// jwcode: articleVideo.value.jwcode || '',
// payPlatform: articleVideo.value.payPlatform || '',
// dept: articleVideo.value.dept || '',
// startTime: articleVideo.value.startTime || '',
// endTime: articleVideo.value.endTime || '',
// goodsName: articleVideo.value.goodsName || '',
// sortField: sortField.value || '',
// sortOrder: sortOrder.value || ''
// }
// }
const res = await API({ url: '/export/exportConsume', data: params })
if (res.code === 200) {
ElMessage.success('导出成功')
}
}
const exportListVisible = ref(false)
//
const openExportList = () => {
getExportList()
exportListVisible.value = true
}
//
const exportList = ref([])
//
const exportListLoading = ref(false)
//
const getExportList = async () => {
exportListLoading.value = true
try {
const result = await API({ url: '/export/export' })
if (result.code === 200) {
const filteredData = result.data.filter(item => {
return item.type === 4; //4 // todo type
});
exportList.value = filteredData
} else {
ElMessage.error(result.msg || '获取导出列表失败')
}
} catch (error) {
console.error('获取导出列表出错:', error)
ElMessage.error('获取导出列表失败,请稍后重试')
} finally {
exportListLoading.value = false
}
}
//
const downloadExportFile = (item) => {
if (item.state === 2) {
const link = document.createElement('a')
link.href = item.url
link.download = item.fileName
link.click()
} else {
ElMessage.warning('文件还在导出中,请稍后再试')
}
}
//
const getTagType = (state) => {
switch (state) {
case 0:
return 'info';
case 1:
return 'primary';
case 2:
return 'success';
case 3:
return 'danger';
default:
return 'info';
}
}
//
const getTagText = (state) => {
switch (state) {
case 0:
return '待执行';
case 1:
return '执行中';
case 2:
return '执行完成';
case 3:
return '执行出错';
default:
return '未知状态';
}
}
</script>
<template>
<div>article videos</div>
<el-row>
<el-col>
<el-card style="margin-bottom: 20px;margin-top:10px">
<el-row style="margin-bottom: 10px">
<el-col :span="4">
<div class="head-card-element">
<el-text class="mx-1">精网号</el-text>
<el-input v-model="articleVideo.jwcode" placeholder="请输入精网号" style="width: 150px" clearable />
</div>
</el-col>
<el-col :span="4">
<div class="head-card-element">
<el-text class="mx-1">地区</el-text>
<el-select v-model="articleVideo.dept" placeholder="请选择地区" style="width: 140px" clearable>
<el-option v-for="(item, index) in dept" :key="index" :label="item" :value="item" />
</el-select>
</div>
</el-col>
<el-col :span="4">
<div class="head-card-element">
<el-text class="mx-1">类型</el-text>
<el-select v-model="articleVideo.type" placeholder="请选择类型" style="width: 140px" clearable>
<el-option label="打赏" value="打赏" />
<el-option label="付费" value="付费" />
</el-select>
</div>
</el-col>
<el-col :span="4">
<div class="head-card-element">
<el-text class="mx-1">文章/视频ID</el-text>
<el-input v-model="articleVideo.articleVideoId" placeholder="请输入文章/视频ID" style="width: 140px" clearable />
</div>
</el-col>
<el-col :span="4">
<div class="head-card-element">
<el-text class="mx-1">文章/视频标题</el-text>
<el-input v-model="articleVideo.articleVideoTitle" placeholder="请输入文章/视频标题" style="width: 140px" clearable />
</div>
</el-col>
<el-col :span="4">
<div class="head-card-element">
<el-text class="mx-1">作者</el-text>
<el-input v-model="articleVideo.author" placeholder="请输入作者" style="width: 140px" clearable />
</div>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<div class="head-card-element">
<el-text class="mx-1">付费时间</el-text>
<el-date-picker
v-model="getTime"
type="datetimerange"
range-separator="至"
start-placeholder="起始时间"
end-placeholder="结束时间"
style="width: 400px"
@change="handleDatePickerChange"
value-format="YYYY-MM-DD HH:mm:ss"
/>
<el-button @click="getToday()" style="margin-left: 10px" :type="activeTimeRange === 'today' ? 'primary' : ''"></el-button>
<el-button @click="getYesterday()" style="margin-left: 10px" :type="activeTimeRange === 'yesterday' ? 'primary' : ''"></el-button>
<el-button @click="get7Days()" style="margin-left: 10px" :type="activeTimeRange === '7days' ? 'primary' : ''">近7天</el-button>
<el-button type="success" @click="reset()">重置</el-button>
<el-button type="primary" @click="search()">查询</el-button>
<el-button type="primary" @click="exportExcel()">导出Excel</el-button>
<el-button type="primary" @click="openExportList">查看导出列表</el-button>
</div>
</el-col>
</el-row>
</el-card>
</el-col>
</el-row>
<el-row>
<el-col>
<el-card>
<div>
金豆总数{{ Math.abs(permanentGolds + freeGolds + taskGolds) / 100 }}付费金豆数{{ Math.abs(permanentGolds) / 100 }}免费金豆数{{
Math.abs(freeGolds) / 100
}}
</div>
<!-- 设置表格容器的高度和滚动样式 -->
<div style="height: 576px; overflow-y: auto">
<el-table :data="tableData" style="width: 100%" height="576px" @sort-change="handleSortChange">
<el-table-column type="index" label="序号" width="80px" fixed="left">
<template #default="scope">
<span>{{
scope.$index + 1 + (getObj.value.pageNum - 1) * getObj.value.pageSize
}}</span>
</template>
</el-table-column>
<!-- 固定姓名列 -->
<el-table-column prop="name" label="姓名" width="150px" fixed="left" />
<!-- 固定精网号列 -->
<el-table-column prop="jwcode" label="精网号" width="110px" fixed="left" />
<el-table-column prop="dept" label="地区" width="110px" />
<el-table-column prop="type" label="类型" width="120px">
<template #default="scope">
<!-- 假设 type 是数字需要转换为对应中文描述 -->
{{ consumeTypes.value.find(item => item.value === scope.row.type)?.label || '未知类型' }}
</template>
</el-table-column>
<el-table-column prop="sumGold" label="金豆总数" width="120px">
<template #default="scope">
{{
(scope.row.taskGold +
scope.row.freeGold +
scope.row.permanentGold) / 100
}}
</template>
</el-table-column>
<el-table-column prop="permanentGold" label="付费金豆数" width="120px">
<template #default="scope">
{{ scope.row.permanentGold / 100 }}
</template>
</el-table-column>
<el-table-column prop="freeGold" label="免费金豆数" width="120px">
<template #default="scope">
{{ scope.row.freeGold / 100 }}
</template>
</el-table-column>
<el-table-column prop="articleVideoId" label="文章/视频ID" width="150px" />
<el-table-column prop="articleVideoTitle" label="文章/视频标题" width="200px" show-overflow-tooltip />
<el-table-column prop="author" label="作者" width="120px" />
<el-table-column prop="payTime" label="付费时间" width="180px">
<template #default="scope">
{{ formatTime(scope.row.payTime) }}
</template>
</el-table-column>
</el-table>
</div>
<!-- 分页 -->
<div class="pagination">
<el-pagination background :page-size="getObj.pageSize" :page-sizes="[5, 10, 20, 50, 100]"
layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="handlePageSizeChange"
@current-change="handleCurrentChange"></el-pagination>
</div>
</el-card>
</el-col>
</el-row>
<!-- 导出弹窗 -->
<el-dialog v-model="exportListVisible" title="导出列表" width="80%">
<el-table :data="exportList" style="width: 100%" :loading="exportListLoading">
<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'">
{{ getTagText(scope.row.state) }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间">
<template #default="scope">
{{ moment(scope.row.createTime).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
<el-table-column label="操作">
<template #default="scope">
<el-button type="primary" size="small" @click="downloadExportFile(scope.row)"
:disabled="scope.row.state !== 2">
下载
</el-button>
</template>
</el-table-column>
</el-table>
<template #footer>
<div class="dialog-footer">
<el-button text @click="exportListVisible = false">关闭</el-button>
</div>
</template>
</el-dialog>
</template>
<style scoped>
.status {
display: flex;
}
.head-card {
display: flex;
}
.head-card-element {
margin-right: 20px;
}
.head-card-btn {
margin-left: auto;
}
</style>
.pagination {
display: flex;
margin-top: 20px;
}
</style>

725
src/views/consume/dieHardFan.vue

@ -1,11 +1,730 @@
<script setup lang="ts">
<script setup>
import { computed, onMounted, ref } from 'vue'
import { dayjs, ElMessage } from 'element-plus'
import request from '@/util/http'
import API from '@/util/http'
import moment from 'moment'
//
/*
====================工具方法==============================
*/
//
const formatTime = (val) => val ? dayjs(val).format('YYYY-MM-DD HH:mm:ss') : ''
/*
====================数据=================================
*/
//
const adminData = ref({})
//
const tableData = ref([])
// liveStream
const dieHardFan = ref({
jwcode: null,
dept: "",
type: "",
gift: "",
channel: "",
liveRoom: "",
startTime: '',
endTime: '',
})
//
const channels = ref([])
//
const consumeTypes = ref([
{ label: '发礼物', value: 1 },
{ label: '发红包', value: 2 },
{ label: '发福袋', value: 3 },
{ label: '付费直播', value: 4 },
{ label: '加入粉丝团', value: 5 },
{ label: '发弹幕', value: 6 }
])
//
const handleTypeChange = (value) => {
if (value !== 1) {
dieHardFan.value.gift = ''
}
}
//------------------------
//
const activeTimeRange = ref('')
//
const handleDatePickerChange = () => {
activeTimeRange.value = ''
}
//
const getObj = ref({
pageNum: 1,
pageSize: 50
})
//
const total = ref(100)
//
const getTime = ref({
startTime: '',
endTime: ''
})
//
// const activity = ref([])
//
const dept = ref([])
//
const filterChannel = (query) => {
if (query) {
return channels.value.filter(item => item.toLowerCase().includes(query.toLowerCase()));
}
return channels.value;
};
//
const sortField = ref('')
const sortOrder = ref('')
// //
// const consumePlatform = [
// {
// value: '',
// label: ''
// },
// {
// value: 'HomilyChart',
// label: 'HomilyChart'
// },
// {
// value: 'HomilyLink',
// label: 'HomilyLink'
// },
// {
// value: 'ERP',
// label: 'ERP'
// },
// {
// value: '',
// label: ''
// },
// {
// value: '',
// label: ''
// },
// ]
// //
// const tableDataTotal = ref({})
// const permanentGold = ref(0)
// const freeGold = ref(0)
// const taskGold = ref(0)
// const totalGold = ref(0)
// //
// const permanentGolds = ref(0)
// const freeGolds = ref(0)
// const taskGolds = ref(0)
// //
// const goods = ref([])
// const totalGoldSearch = ref({
// jwcode: null,
// payPlatform: "",
// dept: "",
// startTime: "",
// endTime: "",
// goodsName: ""
// })
/*
====================方法=================================
*/
//
const getAdminData = async function () {
try {
const result = await request({
url: '/admin/userinfo',
data: {}
})
adminData.value = result
console.log('请求成功', result)
console.log('用户信息', adminData.value)
} catch (error) {
console.log('请求失败', error)
}
}
// todo
// const ConsumeSelectBy = async function (val) {
// try {
// //
// if (typeof val === 'number') {
// getObj.value.pageNum = val
// }
// //
// if (getTime.value != null) {
// if (getTime.value.startTime != '' && getTime.value.endTime != '') {
// dieHardFan.value.startTime = formatTime(getTime.value[0])
// dieHardFan.value.endTime = formatTime(getTime.value[1])
// }
// } else {
// dieHardFan.value.startTime = ''
// dieHardFan.value.endTime = ''
// }
// dieHardFan.value.sortField = sortField.value
// dieHardFan.value.sortOrder = sortOrder.value
// console.log('_', dieHardFan.value.startTime)
// console.log('1', getObj.value)
// console.log('2', dieHardFan.value)
// // POST
// const result = await request({
// url: '/consume/selectBy',
// data: {
// pageNum: getObj.value.pageNum,
// pageSize: getObj.value.pageSize,
// dieHardFan: {
// ... dieHardFan.value,
// sortField: sortField.value,
// sortOrder: sortOrder.value
// }
// }
// })
// console.log('2', sortField)
// //
// // detail.value
// const detailWithoutSort = { ... dieHardFan.value }
// delete detailWithoutSort.sortField
// delete detailWithoutSort.sortOrder
// //
// totalGoldSearch.value.startTime = dieHardFan.value.startTime
// totalGoldSearch.value.endTime = dieHardFan.value.endTime
// totalGoldSearch.value.payPlatform = dieHardFan.value.payPlatform
// totalGoldSearch.value.dept = dieHardFan.value.dept
// totalGoldSearch.value.goodsName = dieHardFan.value.goodsName
// totalGoldSearch.value.jwcode = dieHardFan.value.jwcode
// //
// const resultTotalGold = await request({
// // url: '/consume/statsGold',
// url: '/consume/statsGold',
// data: totalGoldSearch.value
// })
// console.log("", resultTotalGold)
// if (resultTotalGold.code === 200 && resultTotalGold.data) {
// const data = resultTotalGold.data
// console.log(':', data)
// permanentGolds.value = Number(data.permanentGolds) || 0
// freeGolds.value = Number(data.freeGolds) || 0
// taskGolds.value = Number(data.taskGolds) || 0
// }
// //
// tableData.value = result.data.list
// tableDataTotal.value = resultTotalGold.data
// if (resultTotalGold.data == null) {
// console.log('2', resultTotalGold)
// // 西
// tableDataTotal.value = resultTotalGold.data
// }
// const sumGoldList = tableData.value.map(item => item.sumGold);
// console.log("sumGold", sumGoldList); // sumGold
// console.log('@@@@@@@@@@tableDataT', tableDataTotal.value.list)
// // totalGold.value = tableData.value.sum
// // //
// // permanentGold.value = parseFloat(
// // (tableDataTotal.value.list.sumGold / 100).toFixed(2)
// // )
// // freeGold.value = parseFloat(
// // (tableDataTotal.value.sumFcion / 100).toFixed(2)
// // )
// // taskGold.value = parseFloat(
// // (tableDataTotal.value.sumTcion / 100).toFixed(2)
// // )
// // totalGold.value = parseFloat(
// // (tableDataTotal.value.sumcion / 100).toFixed(2)
// // )
// console.log('tableData', tableData.value)
// //
// total.value = result.data.total
// console.log('total', total.value)
// } catch (error) {
// console.log('', error)
// //
// }
// }
//
const search = function () {
getObj.value.pageNum = 1
// ConsumeSelectBy() todo
}
//
const reset = function () {
console.log('兄弟,你点了重置')
dieHardFan.value.jwcode = null
dieHardFan.value.type = ''
dieHardFan.value.gift = ''
dieHardFan.value.channel = ''
dieHardFan.value.liveRoom = ''
dieHardFan.value.dept = ''
dieHardFan.value.startTime = ''
dieHardFan.value.endTime = ''
sortField.value = ''
sortOrder.value = ''
getTime.value = {}
activeTimeRange.value = '' //
//
// ConsumeSelectBy() todo
console.log(' dieHardFan', dieHardFan.value)
}
//
const getToday = function () {
const today = new Date()
const startTime = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate()
)
const endTime = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate() + 1
)
getTime.value = [startTime, endTime]
console.log('getTime', getTime.value)
activeTimeRange.value = 'today' //
// ConsumeSelectBy()
}
//
const getYesterday = function () {
const yesterday = new Date()
yesterday.setDate(yesterday.getDate() - 1)
const startTime = new Date(
yesterday.getFullYear(),
yesterday.getMonth(),
yesterday.getDate()
)
const endTime = new Date(
yesterday.getFullYear(),
yesterday.getMonth(),
yesterday.getDate() + 1
)
getTime.value = [startTime, endTime]
console.log('getTime', getTime.value)
activeTimeRange.value = 'yesterday' //
// ConsumeSelectBy() //todo
}
// 7
const get7Days = function () {
const today = new Date()
const startTime = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate() - 6
)
const endTime = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate() + 1
)
getTime.value = [startTime, endTime]
console.log('getTime', getTime.value)
activeTimeRange.value = '7days' //
// ConsumeSelectBy() todo
}
//
// const getGoods = async function () {
// try {
// // POST
// const result = await request({
// url: '/general/goods',
// data: {}
// })
// //
// console.log('product', result)
// //
// goods.value = result.data
// console.log('goods ', goods.value) //
// } catch (error) {
// console.log('', error)
// //
// }
// }
//
const getDept = async function () {
try {
//
const result = await request({
// url: '/general/dept',
url: '/beanConsume/getDept', // todo
data: {account:adminData.value.account}
})
console.log('请求地区列表成功', result)
//
dept.value = result.data
console.log('地区数据', dept.value)
} catch (error) {
console.log('请求地区列表失败', error)
ElMessage({
type: 'error',
message: '获取地区列表失败,请稍后重试'
})
}
}
// //
// const handleSortChange = (column) => {
// console.log('', column.prop)
// console.log('', column.order)
// if (column.prop === 'permanentGold') {
// sortField.value = 'permanentGold'
// } else if (column.prop === 'taskGold') {
// sortField.value = 'taskGold'
// } else if (column.prop === 'freeGold') {
// sortField.value = 'freeGold'
// } else if (column.prop === 'createTime') {
// sortField.value = 'createTime'
// }
// sortOrder.value = column.order === 'ascending' ? 'DESC' : 'ASC'
// ConsumeSelectBy()
// }
// const handlePageSizeChange = function (val) {
// getObj.value.pageSize = val
// ConsumeSelectBy()
// }
// const handleCurrentChange = function (val) {
// getObj.value.pageNum = val
// ConsumeSelectBy()
// }
/*
====================计算属性=================================
*/
//
// const sumGold = computed(() => permanentGolds.value + freeGolds.value + taskGolds.value)
/*
====================监听=================================
*/
/*
====================挂载=================================
*/
onMounted(async function () {
await getAdminData()
// await ConsumeSelectBy()
// // getActivity();
await getDept()
// await getGoods()
})
const exportExcel = async function () {
// const params = { //
// dieHardFan: {
// jwcode: dieHardFan.value.jwcode || '',
// payPlatform: dieHardFan.value.payPlatform || '',
// dept: dieHardFan.value.dept || '',
// startTime: dieHardFan.value.startTime || '',
// endTime: dieHardFan.value.endTime || '',
// goodsName: dieHardFan.value.goodsName || '',
// sortField: sortField.value || '',
// sortOrder: sortOrder.value || ''
// }
// }
const res = await API({ url: '/export/exportConsume', data: params })
if (res.code === 200) {
ElMessage.success('导出成功')
}
}
const exportListVisible = ref(false)
//
const openExportList = () => {
getExportList()
exportListVisible.value = true
}
//
const exportList = ref([])
//
const exportListLoading = ref(false)
//
const getExportList = async () => {
exportListLoading.value = true
try {
const result = await API({ url: '/export/export' })
if (result.code === 200) {
const filteredData = result.data.filter(item => {
return item.type === 4; //4 // todo type
});
exportList.value = filteredData
} else {
ElMessage.error(result.msg || '获取导出列表失败')
}
} catch (error) {
console.error('获取导出列表出错:', error)
ElMessage.error('获取导出列表失败,请稍后重试')
} finally {
exportListLoading.value = false
}
}
//
const downloadExportFile = (item) => {
if (item.state === 2) {
const link = document.createElement('a')
link.href = item.url
link.download = item.fileName
link.click()
} else {
ElMessage.warning('文件还在导出中,请稍后再试')
}
}
//
const getTagType = (state) => {
switch (state) {
case 0:
return 'info';
case 1:
return 'primary';
case 2:
return 'success';
case 3:
return 'danger';
default:
return 'info';
}
}
//
const getTagText = (state) => {
switch (state) {
case 0:
return '待执行';
case 1:
return '执行中';
case 2:
return '执行完成';
case 3:
return '执行出错';
default:
return '未知状态';
}
}
</script>
<template>
<div>die-hard fans</div>
<el-row>
<el-col>
<el-card style="margin-bottom: 20px;margin-top:10px">
<el-row style="margin-bottom: 10px">
<el-col :span="4">
<div class="head-card-element">
<el-text class="mx-1">精网号</el-text>
<el-input v-model="dieHardFan.jwcode" placeholder="请输入精网号" style="width: 150px" clearable />
</div>
</el-col>
<el-col :span="4">
<div class="head-card-element">
<el-text class="mx-1">地区</el-text>
<el-select v-model="dieHardFan.dept" placeholder="请选择地区" style="width: 150px" clearable>
<el-option v-for="(item, index) in dept" :key="index" :label="item" :value="item" />
</el-select>
</div>
</el-col>
<el-col :span="5">
<div class="head-card-element">
<el-text class="mx-1">频道</el-text>
<el-select
v-model="dieHardFan.channel"
placeholder="请选择频道"
style="width: 180px"
clearable
filterable
allow-create
default-first-option
:filter-method="filterChannel"
>
<el-option v-for="(item, index) in channels" :key="index" :label="item" :value="item" />
</el-select>
</div>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<div class="head-card-element">
<el-text class="mx-1">消费时间</el-text>
<el-date-picker
v-model="getTime"
type="datetimerange"
range-separator="至"
start-placeholder="起始时间"
end-placeholder="结束时间"
style="width: 400px"
@change="handleDatePickerChange"
value-format="YYYY-MM-DD HH:mm:ss"
/>
<el-button @click="getToday()" style="margin-left: 10px" :type="activeTimeRange === 'today' ? 'primary' : ''"></el-button>
<el-button @click="getYesterday()" style="margin-left: 10px" :type="activeTimeRange === 'yesterday' ? 'primary' : ''"></el-button>
<el-button @click="get7Days()" style="margin-left: 10px" :type="activeTimeRange === '7days' ? 'primary' : ''">近7天</el-button>
<el-button type="success" @click="reset()">重置</el-button>
<el-button type="primary" @click="search()">查询</el-button>
<el-button type="primary" @click="exportExcel()">导出Excel</el-button>
<el-button type="primary" @click="openExportList">查看导出列表</el-button>
</div>
</el-col>
</el-row>
</el-card>
</el-col>
</el-row>
<el-row>
<el-col>
<el-card>
<div>
金豆总数{{ Math.abs(permanentGolds + freeGolds + taskGolds) / 100 }}付费金豆数{{ Math.abs(permanentGolds) / 100 }}免费金豆数{{
Math.abs(freeGolds) / 100
}}
</div>
<!-- 设置表格容器的高度和滚动样式 -->
<div style="height: 576px; overflow-y: auto">
<el-table :data="tableData" style="width: 100%" height="576px" @sort-change="handleSortChange">
<el-table-column type="index" label="序号" width="80px" fixed="left">
<template #default="scope">
<span>{{
scope.$index + 1 + (getObj.value.pageNum - 1) * getObj.value.pageSize
}}</span>
</template>
</el-table-column>
<!-- 固定姓名列 -->
<el-table-column prop="name" label="姓名" width="150px" fixed="left" />
<!-- 固定精网号列 -->
<el-table-column prop="jwcode" label="精网号" width="110px" fixed="left" />
<el-table-column prop="dept" label="地区" width="110px" />
<el-table-column prop="sumGold" label="金豆数量" width="120px">
<template #default="scope">
{{
(scope.row.taskGold +
scope.row.freeGold +
scope.row.permanentGold) / 100
}}
</template>
</el-table-column>
<el-table-column prop="channel" label="频道" width="120px" />
<el-table-column prop="memberType" label="会员类型" width="120px" />
<el-table-column prop="joinMethod" label="加入方式" width="120px" />
<el-table-column prop="joinTime" label="加入时间" width="180px" />
<el-table-column prop="expireTime" label="到期时间" width="180px" />
</el-table>
</div>
<!-- 分页 -->
<div class="pagination">
<el-pagination background :page-size="getObj.pageSize" :page-sizes="[5, 10, 20, 50, 100]"
layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="handlePageSizeChange"
@current-change="handleCurrentChange"></el-pagination>
</div>
</el-card>
</el-col>
</el-row>
<!-- 导出弹窗 -->
<el-dialog v-model="exportListVisible" title="导出列表" width="80%">
<el-table :data="exportList" style="width: 100%" :loading="exportListLoading">
<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'">
{{ getTagText(scope.row.state) }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间">
<template #default="scope">
{{ moment(scope.row.createTime).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
<el-table-column label="操作">
<template #default="scope">
<el-button type="primary" size="small" @click="downloadExportFile(scope.row)"
:disabled="scope.row.state !== 2">
下载
</el-button>
</template>
</el-table-column>
</el-table>
<template #footer>
<div class="dialog-footer">
<el-button text @click="exportListVisible = false">关闭</el-button>
</div>
</template>
</el-dialog>
</template>
<style scoped>
.status {
display: flex;
}
.head-card {
display: flex;
}
.head-card-element {
margin-right: 20px;
}
.head-card-btn {
margin-left: auto;
}
</style>
.pagination {
display: flex;
margin-top: 20px;
}
</style>

720
src/views/consume/liveStream.vue

@ -1,11 +1,725 @@
<script setup lang="ts">
<script setup>
import { computed, onMounted, ref } from 'vue'
import { dayjs, ElMessage } from 'element-plus'
import request from '@/util/http'
import API from '@/util/http'
import moment from 'moment'
//
/*
====================工具方法==============================
*/
//
const formatTime = (val) => val ? dayjs(val).format('YYYY-MM-DD HH:mm:ss') : ''
/*
====================数据=================================
*/
//
const adminData = ref({})
//
const tableData = ref([])
// liveStream
const beanConsumeLive = ref({
jwcode: null,
dept: "",
type: "",
gift: "",
channel: "",
liveName: "",
startTime: '',
endTime: '',
sortField: '',
sortOrder: ''
})
//
const channels = ref([])
//
const consumeTypes = ref([
{ label: '发礼物', value: 1 },
{ label: '发红包', value: 2 },
{ label: '发福袋', value: 3 },
{ label: '付费直播', value: 4 },
{ label: '加入粉丝团', value: 5 },
{ label: '发弹幕', value: 6 }
])
//
const handleTypeChange = (value) => {
if (value !== 1) {
beanConsumeLive.value.gift = ''
}
}
//------------------------
//
const activeTimeRange = ref('')
//
const handleDatePickerChange = () => {
activeTimeRange.value = ''
}
//
const getObj = ref({
pageNum: 1,
pageSize: 50
})
//
const total = ref(100)
//
const getTime = ref({
startTime: '',
endTime: ''
})
//
// const activity = ref([])
//
const dept = ref([])
//
const sortField = ref('')
const sortOrder = ref('')
// //
// const consumePlatform = [
// {
// value: '',
// label: ''
// },
// {
// value: 'HomilyChart',
// label: 'HomilyChart'
// },
// {
// value: 'HomilyLink',
// label: 'HomilyLink'
// },
// {
// value: 'ERP',
// label: 'ERP'
// },
// {
// value: '',
// label: ''
// },
// {
// value: '',
// label: ''
// },
// ]
// //
// const tableDataTotal = ref({})
// const permanentGold = ref(0)
// const freeGold = ref(0)
// const taskGold = ref(0)
// const totalGold = ref(0)
// //
// const permanentGolds = ref(0)
// const freeGolds = ref(0)
// const taskGolds = ref(0)
// //
// const goods = ref([])
// const totalGoldSearch = ref({
// jwcode: null,
// payPlatform: "",
// dept: "",
// startTime: "",
// endTime: "",
// goodsName: ""
// })
/*
====================方法=================================
*/
//
const getAdminData = async function () {
try {
const result = await request({
url: '/admin/userinfo',
data: {}
})
adminData.value = result
console.log('请求成功', result)
console.log('用户信息', adminData.value)
} catch (error) {
console.log('请求失败', error)
}
}
const selectLiveBy = async function (val) {
try {
//
if (typeof val === 'number') {
getObj.value.pageNum = val
}
//
if (getTime.value != null) {
if (getTime.value.startTime != '' && getTime.value.endTime != '') {
beanConsumeLive.value.startTime = formatTime(getTime.value[0])
beanConsumeLive.value.endTime = formatTime(getTime.value[1])
}
} else {
beanConsumeLive.value.startTime = ''
beanConsumeLive.value.endTime = ''
}
beanConsumeLive.value.sortField = sortField.value
beanConsumeLive.value.sortOrder = sortOrder.value
console.log('搜索参数_时间', beanConsumeLive.value.startTime)
console.log('搜索参数1', getObj.value)
console.log('搜索参数2', beanConsumeLive.value)
// POST
const result = await request({
url: '/beanConsume/selectLiveBy',
data: {
pageNum: getObj.value.pageNum,
pageSize: getObj.value.pageSize,
beanConsumeLive: {
... beanConsumeLive.value,
sortField: sortField.value,
sortOrder: sortOrder.value
}
}
})
console.log('请求成功2', sortField)
// //
// // detail.value
// const detailWithoutSort = { ... beanConsumeLive.value }
// delete detailWithoutSort.sortField
// delete detailWithoutSort.sortOrder
// //
// totalGoldSearch.value.startTime = beanConsumeLive.value.startTime
// totalGoldSearch.value.endTime = beanConsumeLive.value.endTime
// totalGoldSearch.value.dept = beanConsumeLive.value.dept
// totalGoldSearch.value.goodsName = beanConsumeLive.value.goodsName
// totalGoldSearch.value.jwcode = beanConsumeLive.value.jwcode
// //
// const resultTotalGold = await request({
// // url: '/consume/statsGold',
// url: '/consume/statsGold',
// data: totalGoldSearch.value
// })
// console.log("", resultTotalGold)
// if (resultTotalGold.code === 200 && resultTotalGold.data) {
// const data = resultTotalGold.data
// console.log(':', data)
// permanentGolds.value = Number(data.permanentGolds) || 0
// freeGolds.value = Number(data.freeGolds) || 0
// taskGolds.value = Number(data.taskGolds) || 0
// }
// //
// tableData.value = result.data.list
// tableDataTotal.value = resultTotalGold.data
// if (resultTotalGold.data == null) {
// console.log('2', resultTotalGold)
// // 西
// tableDataTotal.value = resultTotalGold.data
// }
// const sumGoldList = tableData.value.map(item => item.sumGold);
// console.log("sumGold", sumGoldList); // sumGold
// console.log('@@@@@@@@@@tableDataT', tableDataTotal.value.list)
// console.log('tableData', tableData.value)
//
total.value = result.data.total
console.log('total', total.value)
} catch (error) {
console.log('请求失败', error)
//
}
}
//
const search = function () {
getObj.value.pageNum = 1
// selectLiveBy() todo
}
//
const reset = function () {
console.log('兄弟,你点了重置')
beanConsumeLive.value.jwcode = null
beanConsumeLive.value.type = ''
beanConsumeLive.value.gift = ''
beanConsumeLive.value.channel = ''
beanConsumeLive.value.liveName = ''
beanConsumeLive.value.dept = ''
beanConsumeLive.value.startTime = ''
beanConsumeLive.value.endTime = ''
sortField.value = ''
sortOrder.value = ''
getTime.value = {}
activeTimeRange.value = '' //
//
selectLiveBy()
console.log(' beanConsumeLive', beanConsumeLive.value)
}
//
const getToday = function () {
const today = new Date()
const startTime = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate()
)
const endTime = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate() + 1
)
getTime.value = [startTime, endTime]
console.log('getTime', getTime.value)
activeTimeRange.value = 'today' //
// selectLiveBy()
}
//
const getYesterday = function () {
const yesterday = new Date()
yesterday.setDate(yesterday.getDate() - 1)
const startTime = new Date(
yesterday.getFullYear(),
yesterday.getMonth(),
yesterday.getDate()
)
const endTime = new Date(
yesterday.getFullYear(),
yesterday.getMonth(),
yesterday.getDate() + 1
)
getTime.value = [startTime, endTime]
console.log('getTime', getTime.value)
activeTimeRange.value = 'yesterday' //
// selectLiveBy() //todo
}
// 7
const get7Days = function () {
const today = new Date()
const startTime = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate() - 6
)
const endTime = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate() + 1
)
getTime.value = [startTime, endTime]
console.log('getTime', getTime.value)
activeTimeRange.value = '7days' //
// selectLiveBy() todo
}
//
// const getGoods = async function () {
// try {
// // POST
// const result = await request({
// url: '/general/goods',
// data: {}
// })
// //
// console.log('product', result)
// //
// goods.value = result.data
// console.log('goods ', goods.value) //
// } catch (error) {
// console.log('', error)
// //
// }
// }
//
const getDept = async function () {
try {
//
const result = await request({
// url: '/general/dept',
url: '/beanConsume/getDept', // todo
data: {account:adminData.value.account}
})
console.log('请求地区列表成功', result)
//
dept.value = result.data
console.log('地区数据', dept.value)
} catch (error) {
console.log('请求地区列表失败', error)
ElMessage({
type: 'error',
message: '获取地区列表失败,请稍后重试'
})
}
}
// //
// const handleSortChange = (column) => {
// console.log('', column.prop)
// console.log('', column.order)
// if (column.prop === 'permanentGold') {
// sortField.value = 'permanentGold'
// } else if (column.prop === 'taskGold') {
// sortField.value = 'taskGold'
// } else if (column.prop === 'freeGold') {
// sortField.value = 'freeGold'
// } else if (column.prop === 'createTime') {
// sortField.value = 'createTime'
// }
// sortOrder.value = column.order === 'ascending' ? 'DESC' : 'ASC'
// selectLiveBy()
// }
// const handlePageSizeChange = function (val) {
// getObj.value.pageSize = val
// selectLiveBy()
// }
// const handleCurrentChange = function (val) {
// getObj.value.pageNum = val
// selectLiveBy()
// }
/*
====================计算属性=================================
*/
//
// const sumGold = computed(() => permanentGolds.value + freeGolds.value + taskGolds.value)
/*
====================监听=================================
*/
/*
====================挂载=================================
*/
onMounted(async function () {
await getAdminData()
// await selectLiveBy()
// // getActivity();
await getDept()
// await getGoods()
})
const exportExcel = async function () {
// const params = { //
// beanConsumeLive: {
// jwcode: beanConsumeLive.value.jwcode || '',
// payPlatform: beanConsumeLive.value.payPlatform || '',
// dept: beanConsumeLive.value.dept || '',
// startTime: beanConsumeLive.value.startTime || '',
// endTime: beanConsumeLive.value.endTime || '',
// goodsName: beanConsumeLive.value.goodsName || '',
// sortField: sortField.value || '',
// sortOrder: sortOrder.value || ''
// }
// }
const res = await API({ url: '/export/exportConsume', data: params })
if (res.code === 200) {
ElMessage.success('导出成功')
}
}
const exportListVisible = ref(false)
//
const openExportList = () => {
getExportList()
exportListVisible.value = true
}
//
const exportList = ref([])
//
const exportListLoading = ref(false)
//
const getExportList = async () => {
exportListLoading.value = true
try {
const result = await API({ url: '/export/export' })
if (result.code === 200) {
const filteredData = result.data.filter(item => {
return item.type === 4; //4 // todo type
});
exportList.value = filteredData
} else {
ElMessage.error(result.msg || '获取导出列表失败')
}
} catch (error) {
console.error('获取导出列表出错:', error)
ElMessage.error('获取导出列表失败,请稍后重试')
} finally {
exportListLoading.value = false
}
}
//
const downloadExportFile = (item) => {
if (item.state === 2) {
const link = document.createElement('a')
link.href = item.url
link.download = item.fileName
link.click()
} else {
ElMessage.warning('文件还在导出中,请稍后再试')
}
}
//
const getTagType = (state) => {
switch (state) {
case 0:
return 'info';
case 1:
return 'primary';
case 2:
return 'success';
case 3:
return 'danger';
default:
return 'info';
}
}
//
const getTagText = (state) => {
switch (state) {
case 0:
return '待执行';
case 1:
return '执行中';
case 2:
return '执行完成';
case 3:
return '执行出错';
default:
return '未知状态';
}
}
</script>
<template>
<div>live stream</div>
<el-row>
<el-col>
<el-card style="margin-bottom: 20px;margin-top:10px">
<el-row style="margin-bottom: 10px">
<el-col :span="4">
<div class="head-card-element">
<el-text class="mx-1">精网号</el-text>
<el-input v-model="beanConsumeLive.jwcode" placeholder="请输入精网号" style="width: 140px" clearable />
</div>
</el-col>
<el-col :span="4">
<div class="head-card-element">
<el-text class="mx-1">地区</el-text>
<el-select v-model="beanConsumeLive.dept" placeholder="请选择地区" style="width: 140px" clearable>
<el-option v-for="(item, index) in dept" :key="index" :label="item" :value="item" />
</el-select>
</div>
</el-col>
<el-col :span="4">
<div class="head-card-element">
<el-text class="mx-1">类型</el-text>
<el-select v-model="beanConsumeLive.type" placeholder="请选择类型" style="width: 140px" clearable @change="handleTypeChange">
<el-option v-for="(item, index) in consumeTypes" :key="index" :label="item.label" :value="item.value" />
</el-select>
</div>
</el-col>
<el-col :span="4" v-if="beanConsumeLive.type === 1">
<div class="head-card-element">
<el-text class="mx-1">礼物名称</el-text>
<el-select v-model="beanConsumeLive.gift" placeholder="请选择礼物名称" style="width: 140px" clearable>
<el-option v-for="(item, index) in goods" :key="index" :label="item" :value="item" />
</el-select>
</div>
</el-col>
<el-col :span="4">
<div class="head-card-element">
<el-text class="mx-1">频道</el-text>
<el-select
v-model="beanConsumeLive.channel"
placeholder="请选择频道"
style="width: 150px"
clearable
filterable
allow-create
default-first-option
>
<el-option v-for="(item, index) in channels" :key="index" :label="item" :value="item" />
</el-select>
</div>
</el-col>
<el-col :span="4">
<div class="head-card-element">
<el-text class="mx-1">直播间</el-text>
<el-input v-model="beanConsumeLive.liveName" placeholder="请输入直播间" style="width: 150px" clearable />
</div>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<div class="head-card-element">
<el-text class="mx-1" >充值时间</el-text>
<el-date-picker v-model="getTime" type="datetimerange" range-separator="" start-placeholder="起始时间"
end-placeholder="结束时间" style="width: 400px" @change="handleDatePickerChange" />
<el-button @click="getToday()" style="margin-left: 10px"
:type="activeTimeRange === 'today' ? 'primary' : ''"> </el-button>
<el-button @click="getYesterday()" style="margin-left: 10px"
:type="activeTimeRange === 'yesterday' ? 'primary' : ''"> </el-button>
<el-button @click="get7Days()" style="margin-left: 10px"
:type="activeTimeRange === '7days' ? 'primary' : ''"> 近7天</el-button>
<!-- </div>
</el-col>
<el-col :span="3">
<div class="head-card-btn"> -->
<el-button type="success" @click="reset()">重置</el-button>
<el-button type="primary" @click="search()">查询</el-button>
<el-button type="primary" @click="exportExcel()">导出excel</el-button>
<el-button type="primary" @click="openExportList">查看导出列表</el-button>
</div>
</el-col>
</el-row>
</el-card>
</el-col>
</el-row>
<el-row>
<el-col>
<el-card>
<div>
金豆总数{{ Math.abs(permanentGolds + freeGolds + taskGolds) / 100 }}付费金豆数{{ Math.abs(permanentGolds) / 100 }}免费金豆数{{
Math.abs(freeGolds) / 100
}}
</div>
<!-- 设置表格容器的高度和滚动样式 -->
<div style="height: 576px; overflow-y: auto">
<el-table :data="tableData" style="width: 100%" height="576px" @sort-change="handleSortChange">
<el-table-column type="index" label="序号" width="80px" fixed="left">
<template #default="scope">
<span>{{
scope.$index + 1 + (getObj.pageNum - 1) * getObj.pageSize
}}</span>
</template>
</el-table-column>
<!-- 固定姓名列 -->
<el-table-column prop="name" label="姓名" width="150px" fixed="left" />
<!-- 固定精网号列 -->
<el-table-column prop="jwcode" label="精网号" width="110px" fixed="left" />
<el-table-column prop="dept" label="地区" width="110px" />
<el-table-column prop="type" label="类型" width="120px" />
<el-table-column prop="sumGold" label="金豆数量" width="120px">
<template #default="scope">
{{
(scope.row.taskGold +
scope.row.freeGold +
scope.row.permanentGold) / 100
}}
</template>
</el-table-column>
<el-table-column prop="channel" label="频道" width="120px" />
<el-table-column prop="liveName" label="直播间名称" width="160px" show-overflow-tooltip />
<el-table-column prop="createTime" label="消费时间" sortable="custom" width="180px" />
</el-table>
</div>
<!-- 分页 -->
<div class="pagination">
<el-pagination background :page-size="getObj.pageSize" :page-sizes="[5, 10, 20, 50, 100]"
layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="handlePageSizeChange"
@current-change="handleCurrentChange"></el-pagination>
</div>
</el-card>
</el-col>
</el-row>
<!-- 导出弹窗 -->
<el-dialog v-model="exportListVisible" title="导出列表" width="80%">
<el-table :data="exportList" style="width: 100%" :loading="exportListLoading">
<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'">
{{ getTagText(scope.row.state) }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间">
<template #default="scope">
{{ moment(scope.row.createTime).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
<el-table-column label="操作">
<template #default="scope">
<el-button type="primary" size="small" @click="downloadExportFile(scope.row)"
:disabled="scope.row.state !== 2">
下载
</el-button>
</template>
</el-table-column>
</el-table>
<template #footer>
<div class="dialog-footer">
<el-button text @click="exportListVisible = false">关闭</el-button>
</div>
</template>
</el-dialog>
</template>
<style scoped>
.status {
display: flex;
}
.head-card {
display: flex;
}
.head-card-element {
margin-right: 20px;
}
.head-card-btn {
margin-left: auto;
}
</style>
.pagination {
display: flex;
margin-top: 20px;
}
</style>

292
src/views/recharge/addBeanRecharge.vue

@ -6,27 +6,28 @@ import axios from 'axios'
import { ElMessageBox } from 'element-plus'
import API from '@/util/http'
import { uploadFile } from '@/util/request';
import request from '@/util/http'
import moment from 'moment'
import { range, re } from 'mathjs'
import { e, range, re } from 'mathjs'
import { utils, read } from 'xlsx'
import throttle from 'lodash/throttle'
import { useAdminStore } from "@/store/index.js";
import { storeToRefs } from "pinia";
const user = ref({})
const getUser = async function (jwcode) {
if (addForm.value.jwcode) {
addForm.value.jwcode = addForm.value.jwcode.replace(/\s/g, '');
} else {
ElMessage.error('请先输入精网号')
return false
}
try {
const result = await API({
url: '/user/selectUser',
url: '/beanUser/userCard',
data: {
jwcode: addForm.value.jwcode
}
})
if (result.code === 0) {
ElMessage.error(result.msg);
} else if (result.data === null) {
@ -48,87 +49,70 @@ const addForm = ref({
remark: '',
adminId: ''
})
const Ref = ref(null)
// const rules = reactive({
// jwcode: [{ required: true, validator: validateJwCode, trigger: 'blur' }],
// gode: [
// { required: true, message: '', trigger: 'blur' },
// {
// validator: (rule, value, callback) => {
// //
// if (/[^0-9.]/.test(value)) {
// callback(new Error(''));
// return;
// }
const formRef = ref(null)
const adminStore = useAdminStore()
const { adminData } = storeToRefs(adminStore)
const rules = reactive({
jwcode: [
{ required: true, message: '请输入精网号', trigger: 'blur' },
{
validator: (rule, value, callback) => {
if (!value) {
callback(new Error('精网号不能为空'));
return;
}
if (/[^0-9]/.test(value)) {
callback(new Error('精网号只能包含数字'));
return;
}
callback();
}, trigger: 'blur'
}],
gode: [
{ required: true, message: '请输入永久金豆数', trigger: 'blur' },
{
validator: (rule, value, callback) => {
//
if (!/^\d+$/.test(value)) {
callback(new Error('请输入非负整数'));
return;
}
// //
// const integerPart = value.split('.')[0];
// if (integerPart.length > 6) {
// callback(new Error('6'));
// return;
// }
//
if (value.length > 6) {
callback(new Error('整数位数不能超过6位'));
return;
}
callback();
},
// //
// if (value.includes('.')) {
// const decimalPart = value.split('.')[1];
// if (decimalPart.length > 2) {
// callback(new Error(''));
// return;
// }
// }
// const numValue = Number(value);
// if (isNaN(numValue)) {
// callback(new Error(''));
// } else if (numValue < 0) {
// callback(new Error('0'));
// } else {
// callback();
// }
// },
// trigger: 'blur'
// }
// ],
// freeGode: [
// { required: true, message: '', trigger: 'blur' },
// {
// validator: (rule, value, callback) => {
// //
// if (/[^0-9.]/.test(value)) {
// callback(new Error(''));
// return;
// }
// //
// const integerPart = value.split('.')[0];
// if (integerPart.length > 6) {
// callback(new Error('6'));
// return;
// }
// //
// if (value.includes('.')) {
// const decimalPart = value.split('.')[1];
// if (decimalPart.length > 2) {
// callback(new Error(''));
// return;
// }
// }
trigger: 'blur'
}
],
freeGode: [
{ required: true, message: '请输入免费金豆数', trigger: 'blur' },
{
validator: (rule, value, callback) => {
//
if (!/^\d+$/.test(value)) {
callback(new Error('请输入非负整数'));
return;
}
// const numValue = Number(value);
// if (isNaN(numValue)) {
// callback(new Error(''));
// } else if (numValue < 0) {
// callback(new Error('0'));
// } else {
// callback();
// }
// },
// trigger: 'blur'
// }
// ],
// });
//
if (value.length > 6) {
callback(new Error('整数位数不能超过6位'));
return;
}
callback();
},
trigger: 'blur'
}
],
remark: [
{ required: true, message: '请输入备注', trigger: 'blur' }
]
});
//
const deleteAddForm = function () {
@ -141,118 +125,110 @@ const deleteAddForm = function () {
}
}
const handleAddForm = () => {
const handleAddForm = async () => {
try {
await new Promise((resolve, reject) => {
formRef.value.validate((valid) => {
if (valid) {
if (Number(addForm.value.gode) === 0 && Number(addForm.value.freeGode) === 0) {
reject(new Error('永久金豆和付费金豆不能同时为0'));
}
resolve(); //
} else {
reject(new Error('请检查并完善表单信息')); //
}
});
});
console.log('adminData', adminData.value);
const result = await request({
url: '/bean/add',
data: {
jwcode: addForm.value.jwcode,
gode: addForm.value.gode,
freeGode: addForm.value.freeGode,
remark: addForm.value.remark,
adminId: adminData.adminId
}
})
} catch (error) {
console.log('金豆新增充值失败');
ElMessage.error(error.message || '操作失败');
}
}
</script>
<template>
<div>
<el-form :model="addForm" ref="Ref" label-width="auto" style="max-width: 600px" class="add-form">
<el-form-item prop="jwcode" label="精网号">
<el-form :model="addForm" :rules="rules" ref="formRef" label-width="auto" style="max-width: 600px" class="add-form">
<el-form-item prop="jwcode" label="精网号" label-position="left">
<el-input v-model="addForm.jwcode" style="width: 220px" />
<el-button type="primary" @click="getUser(addForm.jwcode)" style="margin-left: 20px">查询</el-button>
</el-form-item>
<el-form-item prop="permanentGold" label="付费金豆">
<el-form-item prop="gode" label="付费金豆" label-position="left">
<el-input v-model="addForm.gode" style="width: 100px" />
<p></p>
</el-form-item>
<el-form-item prop="freeGold" label="免费金豆">
<el-form-item prop="freeGode" label="免费金豆" label-position="left">
<el-input v-model="addForm.freeGode" style="width: 100px" />
<p></p>
</el-form-item>
<el-form-item prop="remark" label="备注">
<el-input v-model="addForm.remark" style="width: 300px" :rows="2" maxlength="100" show-word-limit
<el-form-item prop="remark" label="备注" label-position="left">
<el-input v-model="addForm.remark" style="width: 300px" :rows="5" maxlength="100" show-word-limit
type="textarea" />
</el-form-item>
<el-form-item prop="adminId" label="提交人">
<!-- <el-form-item prop="adminId" label="提交人">
<el-input style="width: 300px" :value="adminData.adminName" disabled placeholder="提交人姓名" />
</el-form-item>
</el-form-item> -->
<el-button @click="deleteAddForm" style="margin-left: 280px" type="success">重置</el-button>
<el-button type="primary" @click="handleAddForm"> 提交 </el-button>
</el-form>
<!-- 客户信息栏 -->
<el-card v-if="user.jwcode" style="width: 800px; float: right" class="customer-info">
<el-card v-if="user.jwcode" style="width: 800px; float: right" class="customer-info">
<el-form :model="user" label-width="auto" style="max-width: 1000px" label-position="left">
<el-text size="large" style="margin-left: 20px">客户信息</el-text>
<!-- 第一行姓名 + 历史金币 -->
<!-- 第一行姓名 + 当前付费金豆 -->
<el-row style="margin-top: 20px">
<el-col :span="9">
<el-form-item label="姓名:">
<p>{{ user.name }}</p>
<p style="color: #2fa1ff; margin-right: 5px">{{ user.name }}</p>
</el-form-item>
</el-col>
<el-col :span="14">
<el-form-item label="历史金币总数">
<!-- 检查 user.historySumGold 是否为有效的数字 -->
<p style="color: #2fa1ff; margin-right: 5px" v-if="!isNaN(Number(user.historySumGold))">
{{ Number(user.historySumGold) / 100 }}
<el-form-item label="当前付费金豆:">
<p style="color: #2fa1ff; margin-right: 5px" v-if="!isNaN(Number(user.permanentBean))">
{{ Number(user.permanentBean) }}
</p>
<!-- 如果不是有效的数字显示默认值 -->
<p v-else></p>
</el-form-item>
<el-form-item style="margin-top: -23px">
<span style="display: inline; white-space: nowrap; color: #b1b1b1"
v-if="user.historyPermanentGold !== undefined">(永久金币:{{ user.historyPermanentGold / 100 }};免费金币:{{
(user.historyFreeGold) / 100
}};任务金币:{{ user.historyTaskGold / 100 }})</span>
</el-form-item>
</el-col>
</el-row>
<!-- 第二行精网号 + 当前金币独立行 -->
<el-row style="margin-top:-23px">
<!-- 第二行精网号 + 免费金豆 -->
<el-row >
<el-col :span="9">
<el-form-item label="精网号">
<p>{{ user.jwcode }}</p>
<p style="color: #2fa1ff; margin-right: 5px">{{ user.jwcode }}</p>
</el-form-item>
</el-col>
<el-col :span="14">
<el-form-item label="当前金币总数" style="width: 500px">
<span style="color: #2fa1ff; margin-right: 5px" v-if="user.nowSumGold !== undefined">{{ user.nowSumGold
/100}}</span>
</el-form-item>
<!-- 金币详情独立显示 -->
<el-form-item style="margin-top: -23px"> <!-- 负边距减少间距 -->
<span style="color: #b1b1b1; margin-left: 0px" v-if="user.nowPermanentGold !== undefined">(永久金币:{{
user.nowPermanentGold /100}};
免费金币:{{ user.nowFreeGold / 100 }};
任务金币:{{ user.nowTaskGold / 100 }})</span>
<el-form-item label="当前免费金豆:">
<span style="color: #2fa1ff; margin-right: 5px" v-if="user.freeBean !== undefined">{{ user.freeBean }}
</span>
</el-form-item>
</el-col>
</el-row>
<!-- 第三行首次充值日期 + 充值次数 -->
<el-row style="margin-top:-23px">
<el-col :span="9">
<el-form-item label="首次充值日期">
<p v-if="user.firstRecharge">
{{ moment(user.firstRecharge).format('YYYY-MM-DD HH:mm:ss') }}
</p>
</el-form-item>
</el-col>
<el-col :span="14">
<el-form-item label="充值次数">
<p style="color: #2fa1ff">{{ user.rechargeNum }}</p>
</el-form-item>
</el-col>
</el-row>
<!-- 第四行消费次数 + 所属门店 -->
<!-- 第三行消费次数 + 所属门店 -->
<el-row>
<el-col :span="9">
<el-form-item label="消费次数">
<p style="color: #2fa1ff">{{ user.consumeNum }}</p>
<el-form-item label="所属门店">
<p style="color: #2fa1ff">{{ user.market }}</p>
</el-form-item>
</el-col>
<el-col :span="9">
<el-form-item label="所属门店">
<p>{{ user.market }}</p>
<el-form-item label="消费次数">
<p style="color: #2fa1ff; margin-right: 5px" v-if="user.consumeNum!=null">{{ user.consumeNum }}</p>
<p style="color: #2fa1ff; margin-right: 5px" v-else>{{ 0 }}</p>
</el-form-item>
</el-col>
</el-row>
@ -262,4 +238,22 @@ const handleAddForm = () => {
</div>
</template>
<style></style>
<style scoped>
.add-form {
margin-top: 50px;
max-width: 50%;
float: left;
}
.customer-info {
max-width: 60%;
}
p {
margin: 0px;
}
.el-form-item {
margin-left: 50px;
}
</style>

442
src/views/recharge/addCoinRecharge.vue

@ -16,7 +16,7 @@ import throttle from 'lodash/throttle'
//
const trimJwCode = () => {
if (recharge.value.jwcode) {
recharge.value.jwcode = recharge.value.jwcode.replace(/\s/g, '');
recharge.value.jwcode = recharge.value.jwcode.replace(/\s/g, '');
}
}
//
@ -77,9 +77,9 @@ const recharge = ref({
const add = async function () {
try {
const formattedRecharge = { ...recharge.value}
const formattedRecharge = { ...recharge.value }
// 100
// 100
if (formattedRecharge.permanentGold) {
formattedRecharge.permanentGold = Number(formattedRecharge.permanentGold) * 100;
}
@ -154,7 +154,7 @@ const addBefore = () => {
})
return
}
if(recharge.value.money == null || recharge.value.money == '' || recharge.value.money == undefined){
if (recharge.value.money == null || recharge.value.money == '' || recharge.value.money == undefined) {
ElMessage({
type: 'error',
message: '请输入充值金额'
@ -187,21 +187,20 @@ const addBefore = () => {
//
//
const Ref = ref(null)
const validateJwCode = (rule, value, callback) => {
if (!value) {
callback(new Error('精网号不能为空'));
return;
}
if (/[^0-9]/.test(value)) {
callback(new Error('精网号只能包含数字'));
return;
}
callback();
};
const rules = reactive({
jwcode: [{ required: true, validator: validateJwCode, trigger: 'blur' }],
jwcode: [{
required: true, validator: (rule, value, callback) => {
if (!value) {
callback(new Error('精网号不能为空'));
return;
}
if (/[^0-9]/.test(value)) {
callback(new Error('精网号只能包含数字'));
return;
}
callback();
}, trigger: 'blur'
}],
activity: [{ required: true, message: '请选择活动名称', trigger: 'blur' }],
permanentGold: [
{ required: true, message: '请输入永久金币数', trigger: 'blur' },
@ -219,7 +218,7 @@ const rules = reactive({
callback(new Error('整数位数不能超过6位'));
return;
}
//
if (value.includes('.')) {
const decimalPart = value.split('.')[1];
@ -228,7 +227,7 @@ const rules = reactive({
return;
}
}
const numValue = Number(value);
if (isNaN(numValue)) {
callback(new Error('请输入有效的数字'));
@ -280,11 +279,11 @@ const rules = reactive({
}
],
rateName: [{
required: true,
message: '请选择货币名称',
required: true,
message: '请选择货币名称',
trigger: 'blur'
}],
money: [
{ required: true, message: '请输入充值金额', trigger: 'blur' },
{
@ -341,7 +340,7 @@ const getUser = async function (jwcode) {
}
})
if (result.code === 0) {
ElMessage.error(result.msg);
} else if (result.data === null) {
@ -365,7 +364,7 @@ const activity = ref([])
// const result = await API({
// url: '/general/activity',
// data: {
// }
// })
@ -387,7 +386,7 @@ const rateName = [
{
value: 'USD',
label: 'USD',
rateId: 1
rateId: 1
},
{
value: 'HKD',
@ -436,14 +435,14 @@ const customUpload = async (options) => {
try {
const formData = new FormData();
formData.append('file', options.file);
const response = await axios.post(import.meta.env.VITE_UPLOAD_URL, formData, {
headers: {
'Content-Type': 'multipart/form-data',
'Authorization': `Bearer ${localStorage.getItem('token')}`
}
});
if (response.data.code === 200 && response.data.data) {
//
handleAvatarSuccess(response.data, options.file);
@ -463,7 +462,7 @@ const customUpload = async (options) => {
const handleAvatarSuccess = (response, file) => {
// 使 file Object URL
imageUrl.value = URL.createObjectURL(file);
// 使
if (response && response.filePath) {
recharge.value.voucher = response.filePath;
@ -529,7 +528,7 @@ onMounted(async function () {
await getAdminData()
// await getCurrency()
// await getActivity()//
})
onMounted(() => {
console.log('上传URL:', import.meta.env.VITE_UPLOAD_URL);
@ -539,25 +538,12 @@ onMounted(() => {
<template>
<div>
<el-form
:model="recharge"
ref="Ref"
:rules="rules"
label-width="auto"
style="max-width: 600px"
class="add-form"
>
<el-form-item prop="jwcode" label="精网号">
<el-input v-model="recharge.jwcode" style="width: 220px" />
<el-button
type="primary"
@click="getUser(recharge.jwcode)"
style="margin-left: 20px"
>查询</el-button
>
</el-form-item>
<!-- <el-form-item prop="activity" label="活动名称">
<el-form :model="recharge" ref="Ref" :rules="rules" label-width="auto" style="max-width: 600px" class="add-form">
<el-form-item prop="jwcode" label="精网号">
<el-input v-model="recharge.jwcode" style="width: 220px" />
<el-button type="primary" @click="getUser(recharge.jwcode)" style="margin-left: 20px">查询</el-button>
</el-form-item>
<!-- <el-form-item prop="activity" label="活动名称">
<el-select
v-model="recharge.activity"
placeholder="请选择"
@ -572,24 +558,20 @@ onMounted(() => {
/>
</el-select>
</el-form-item> -->
<el-form-item prop="activity" label="活动名称">
<el-input
v-model="recharge.activity"
placeholder="请输入活动名称"
style="width: 300px"
/>
</el-form-item>
<el-form-item prop="permanentGold" label="永久金币">
<el-input v-model="recharge.permanentGold" style="width: 100px" />
<p></p>
</el-form-item>
<el-form-item prop="freeGold" label="免费金币">
<el-input v-model="recharge.freeGold" style="width: 100px" />
<p></p>
</el-form-item>
<!-- <el-form-item label="充值金额">
<el-form-item prop="activity" label="活动名称">
<el-input v-model="recharge.activity" placeholder="请输入活动名称" style="width: 300px" />
</el-form-item>
<el-form-item prop="permanentGold" label="永久金币">
<el-input v-model="recharge.permanentGold" style="width: 100px" />
<p></p>
</el-form-item>
<el-form-item prop="freeGold" label="免费金币">
<el-input v-model="recharge.freeGold" style="width: 100px" />
<p></p>
</el-form-item>
<!-- <el-form-item label="充值金额">
<el-select
prop="moneys"
v-model="rateName"
@ -607,203 +589,139 @@ onMounted(() => {
<el-input prop="money" v-model="recharge.money" style="width: 200px" aria-required="true"/>
</el-form-item> -->
<el-form-item label="充值金额" required>
<!-- 货币名称 -->
<el-form-item prop="rateName" style="display: inline-block; margin-left:0;">
<el-select
v-model="recharge.rateName"
placeholder="货币名称"
style="width: 100px"
>
<el-option
v-for="item in rateName"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<!-- 充值金额 -->
<el-form-item prop="money" style="display: inline-block; margin-left:10px;">
<el-input v-model="recharge.money" style="width: 190px"/>
</el-form-item>
</el-form-item>
<el-form-item prop="payModel" label="收款方式">
<el-select
v-model="recharge.payModel"
placeholder="请选择"
style="width: 300px"
>
<el-option
v-for="item in payModel"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item prop="payTime" label="交款时间">
<!-- 修改 type 属性为 datetime 以支持时分秒选择 -->
<el-date-picker
v-model="recharge.payTime"
type="datetime"
style="width: 300px"
/>
</el-form-item>
<el-form-item
prop="voucher"
label="交款凭证"
style="margin-bottom: 5px"
>
<el-upload
:http-request="customUpload"
class="avatar-uploader"
:show-file-list="false"
:before-upload="beforeAvatarUpload"
style="width: 100px; height: 115px"
>
<img
v-if="imageUrl"
:src="imageUrl"
class="avatar"
style="width: 100px; height: 115px"
/>
<el-icon
v-else
class="avatar-uploader-icon"
style="width: 100px; height: 100px"
>
<Plus />
</el-icon>
</el-upload>
<p style="margin-left: 10px; color: rgb(177, 176, 176)">
仅支持.jpg .png格式文件1MB
</p>
</el-form-item>
<el-form-item prop="remark" label="备注">
<el-input
v-model="recharge.remark"
style="width: 300px"
:rows="2"
maxlength="100"
show-word-limit
type="textarea"
/>
</el-form-item>
<el-form-item prop="adminName" label="提交人">
<el-input
style="width: 300px"
:value="adminData.adminName"
disabled
placeholder="提交人姓名"
/>
</el-form-item>
<el-button @click="deleteRecharge" style="margin-left: 280px" type="success"
>重置</el-button
>
<el-button type="primary" @click="addBefore"> 提交 </el-button>
</el-form>
<!-- 客户信息栏 -->
<el-card v-if="user.jwcode" style="width: 800px; float: right" class="customer-info">
<el-form
:model="user"
label-width="auto"
style="max-width: 1000px"
label-position="left"
>
<el-text size="large" style="margin-left: 20px">客户信息</el-text>
<!-- 第一行姓名 + 历史金币 -->
<el-row style="margin-top: 20px">
<el-col :span="9">
<el-form-item label="姓名:">
<p>{{ user.name }}</p>
</el-form-item>
</el-col>
<el-col :span="14">
<el-form-item label="历史金币总数">
<!-- 检查 user.historySumGold 是否为有效的数字 -->
<p style="color: #2fa1ff; margin-right: 5px" v-if="!isNaN(Number(user.historySumGold))">
{{ Number(user.historySumGold ) /100 }}
</p>
<!-- 如果不是有效的数字显示默认值 -->
<p v-else></p>
</el-form-item>
<el-form-item style="margin-top: -23px">
<span
style="display: inline; white-space: nowrap; color: #b1b1b1"
v-if="user.historyPermanentGold !== undefined"
>(永久金币:{{ user.historyPermanentGold /100 }};免费金币:{{
(user.historyFreeGold) /100
}};任务金币:{{ user.historyTaskGold /100}})</span>
</el-form-item>
</el-col>
</el-row>
<!-- 第二行精网号 + 当前金币独立行 -->
<el-row style="margin-top:-23px">
<el-col :span="9">
<el-form-item label="精网号">
<p>{{ user.jwcode }}</p>
</el-form-item>
</el-col>
<el-col :span="14">
<el-form-item label="当前金币总数" style="width: 500px">
<span
style="color: #2fa1ff; margin-right: 5px"
v-if="user.nowSumGold !== undefined"
>{{ user.nowSumGold /100}}</span>
</el-form-item>
<!-- 金币详情独立显示 -->
<el-form-item style="margin-top: -23px"> <!-- 负边距减少间距 -->
<span
style="color: #b1b1b1; margin-left: 0px"
v-if="user.nowPermanentGold !== undefined"
>(永久金币:{{ user.nowPermanentGold /100}};
免费金币:{{ user.nowFreeGold /100}};
任务金币:{{ user.nowTaskGold /100}})</span>
<el-form-item label="充值金额" required>
<!-- 货币名称 -->
<el-form-item prop="rateName" style="display: inline-block; margin-left:0;">
<el-select v-model="recharge.rateName" placeholder="货币名称" style="width: 100px">
<el-option v-for="item in rateName" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<!-- 第三行首次充值日期 + 充值次数 -->
<el-row style="margin-top:-23px">
<el-col :span="9">
<el-form-item label="首次充值日期">
<p v-if="user.firstRecharge">
{{ moment(user.firstRecharge).format('YYYY-MM-DD HH:mm:ss') }}
</p>
</el-form-item>
</el-col>
<el-col :span="14">
<el-form-item label="充值次数">
<p style="color: #2fa1ff">{{ user.rechargeNum }}</p>
</el-form-item>
</el-col>
</el-row>
<!-- 第四行消费次数 + 所属门店 -->
<el-row>
<el-col :span="9">
<el-form-item label="消费次数">
<p style="color: #2fa1ff">{{ user.consumeNum }}</p>
</el-form-item>
</el-col>
<el-col :span="9">
<el-form-item label="所属门店">
<p>{{ user.market }}</p>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
</div>
<!-- 充值金额 -->
<el-form-item prop="money" style="display: inline-block; margin-left:10px;">
<el-input v-model="recharge.money" style="width: 190px" />
</el-form-item>
</el-form-item>
<el-form-item prop="payModel" label="收款方式">
<el-select v-model="recharge.payModel" placeholder="请选择" style="width: 300px">
<el-option v-for="item in payModel" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item prop="payTime" label="交款时间">
<!-- 修改 type 属性为 datetime 以支持时分秒选择 -->
<el-date-picker v-model="recharge.payTime" type="datetime" style="width: 300px" />
</el-form-item>
<el-form-item prop="voucher" label="交款凭证" style="margin-bottom: 5px">
<el-upload :http-request="customUpload" class="avatar-uploader" :show-file-list="false"
:before-upload="beforeAvatarUpload" style="width: 100px; height: 115px">
<img v-if="imageUrl" :src="imageUrl" class="avatar" style="width: 100px; height: 115px" />
<el-icon v-else class="avatar-uploader-icon" style="width: 100px; height: 100px">
<Plus />
</el-icon>
</el-upload>
<p style="margin-left: 10px; color: rgb(177, 176, 176)">
仅支持.jpg .png格式文件1MB
</p>
</el-form-item>
<el-form-item prop="remark" label="备注">
<el-input v-model="recharge.remark" style="width: 300px" :rows="2" maxlength="100" show-word-limit
type="textarea" />
</el-form-item>
<el-form-item prop="adminName" label="提交人">
<el-input style="width: 300px" :value="adminData.adminName" disabled placeholder="提交人姓名" />
</el-form-item>
<el-button @click="deleteRecharge" style="margin-left: 280px" type="success">重置</el-button>
<el-button type="primary" @click="addBefore"> 提交 </el-button>
</el-form>
<!-- 客户信息栏 -->
<el-card v-if="user.jwcode" style="width: 800px; float: right" class="customer-info">
<el-form :model="user" label-width="auto" style="max-width: 1000px" label-position="left">
<el-text size="large" style="margin-left: 20px">客户信息</el-text>
<!-- 第一行姓名 + 历史金币 -->
<el-row style="margin-top: 20px">
<el-col :span="9">
<el-form-item label="姓名:">
<p>{{ user.name }}</p>
</el-form-item>
</el-col>
<el-col :span="14">
<el-form-item label="历史金币总数">
<!-- 检查 user.historySumGold 是否为有效的数字 -->
<p style="color: #2fa1ff; margin-right: 5px" v-if="!isNaN(Number(user.historySumGold))">
{{ Number(user.historySumGold) / 100 }}
</p>
<!-- 如果不是有效的数字显示默认值 -->
<p v-else></p>
</el-form-item>
<el-form-item style="margin-top: -23px">
<span style="display: inline; white-space: nowrap; color: #b1b1b1"
v-if="user.historyPermanentGold !== undefined">(永久金币:{{ user.historyPermanentGold / 100 }};免费金币:{{
(user.historyFreeGold) / 100
}};任务金币:{{ user.historyTaskGold / 100 }})</span>
</el-form-item>
</el-col>
</el-row>
<!-- 第二行精网号 + 当前金币独立行 -->
<el-row style="margin-top:-23px">
<el-col :span="9">
<el-form-item label="精网号">
<p>{{ user.jwcode }}</p>
</el-form-item>
</el-col>
<el-col :span="14">
<el-form-item label="当前金币总数" style="width: 500px">
<span style="color: #2fa1ff; margin-right: 5px" v-if="user.nowSumGold !== undefined">{{ user.nowSumGold
/100}}</span>
</el-form-item>
<!-- 金币详情独立显示 -->
<el-form-item style="margin-top: -23px"> <!-- 负边距减少间距 -->
<span style="color: #b1b1b1; margin-left: 0px" v-if="user.nowPermanentGold !== undefined">(永久金币:{{
user.nowPermanentGold /100}};
免费金币:{{ user.nowFreeGold / 100 }};
任务金币:{{ user.nowTaskGold / 100 }})</span>
</el-form-item>
</el-col>
</el-row>
<!-- 第三行首次充值日期 + 充值次数 -->
<el-row style="margin-top:-23px">
<el-col :span="9">
<el-form-item label="首次充值日期">
<p v-if="user.firstRecharge">
{{ moment(user.firstRecharge).format('YYYY-MM-DD HH:mm:ss') }}
</p>
</el-form-item>
</el-col>
<el-col :span="14">
<el-form-item label="充值次数">
<p style="color: #2fa1ff">{{ user.rechargeNum }}</p>
</el-form-item>
</el-col>
</el-row>
<!-- 第四行消费次数 + 所属门店 -->
<el-row>
<el-col :span="9">
<el-form-item label="消费次数">
<p style="color: #2fa1ff">{{ user.consumeNum }}</p>
</el-form-item>
</el-col>
<el-col :span="9">
<el-form-item label="所属门店">
<p>{{ user.market }}</p>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
</div>
</template>
<style scoped>

16
src/views/recharge/beanRecharge.vue

@ -7,9 +7,7 @@ import {useAdminStore} from "@/store/index.js";
const router = useRouter();//
const route = useRoute();//
// activeTab
const activeTab = ref(route.name === 'addBeanRecharge' ? 'detail' : 'add');
//coinConsumeDetaildetailadd
//coinConsumeadd
const activeTab = ref(route.name === 'beanSystemRecharge' ? 'system' : 'add');
const adminStore = useAdminStore();
const {menuTree} = storeToRefs(adminStore);
const goToAdd = () => {
@ -52,8 +50,8 @@ const hasMenuPermission = (tree, targetName) => {
//
const getDefaultRoute = () => {
if (!menuTree.value) return 'add';
const hasRecharge = hasMenuPermission(menuTree.value, '提交金充值');
return hasRecharge ? 'add' : 'detail';
const hasRecharge = hasMenuPermission(menuTree.value, '提交金充值');
return hasRecharge ? 'add' : 'system';
};
@ -61,7 +59,7 @@ const getDefaultRoute = () => {
watch(() => route.name, (newName) => {
if (newName === 'add' || newName === 'system' || newName =='online') {
activeTab.value = newName;
} else if (newName === 'coinRecharge') {
} else if (newName === 'beanRecharge') {
const defaultRoute = getDefaultRoute();
navigateTo(defaultRoute);
}
@ -69,12 +67,14 @@ watch(() => route.name, (newName) => {
//
onMounted(() => {
if (route.name === 'coinRecharge') {
if (route.name === 'beanRecharge') {
const defaultRoute = getDefaultRoute();
console.log('defaultRoute',defaultRoute);
navigateTo(defaultRoute);
} else {
//
if (route.name === 'add' || route.name === 'detail' || route.name =='online') {
if (route.name === 'add' || route.name === 'system' || route.name =='online') {
activeTab.value = route.name;
}
}

Loading…
Cancel
Save