gameapi-client/src/views/merchant/quota/index.vue

525 lines
20 KiB
Vue
Raw Normal View History

2025-08-14 10:33:48 +08:00
<template>
<div class="app-container">
<table-search-card :leftSpan="20" :model="queryParams" @getList="getList" @handleQuery="handleQuery" @resetQuery="resetQuery">
<template #left>
2025-08-27 20:51:27 +08:00
<table-search-date v-model:dateRange="dateRange" v-model:operateTimeType="operateTimeType"></table-search-date>
2025-08-14 10:33:48 +08:00
<el-form-item :label="t('商户账号')" prop="tenantKey">
<el-input
v-model="queryParams.tenantKey"
:placeholder="t('请输入商户账号')"
clearable
style="width: 200px"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item :label="t('玩家账号')" prop="memberAccount">
<el-input
v-model="queryParams.memberAccount"
:placeholder="t('请输入玩家账号')"
clearable
style="width: 200px"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item :label="t('游戏账号')" prop="gameAccount">
<el-input
v-model="queryParams.gameAccount"
:placeholder="t('请输入游戏账号')"
clearable
style="width: 200px"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item :label="t('币种')" prop="currencyCode">
2025-08-27 20:51:27 +08:00
<CustomSelect v-if="showLoding1" v-model="queryParams.currencyCode" filterable :options="sys_job_group" placeholder="请选择币种" style="width: 200px" />
2025-08-14 10:33:48 +08:00
</el-form-item>
<!-- <el-form-item :label="t('平台类型')" prop="platformCode">
<CustomSelect v-if="showLoding2" v-model="queryParams.platformCode" :options="sys_job_status" placeholder="请选择平台类型" style="width: 200px" />
</el-form-item> -->
<el-form-item :label="t('额度类型')" prop="quotaType">
<CustomSelect v-model="queryParams.quotaType" :options="quotaTypeArr" placeholder="请选择类型" style="width: 200px" />
</el-form-item>
<el-form-item :label="t('游戏平台')" prop="platformCode">
2025-08-27 20:51:27 +08:00
<CustomSelect v-if="showLoding3" v-model="queryParams.platformCode" :options="quotaplatformCodeArr" filterable placeholder="请选择平台" style="width: 200px" />
2025-08-14 10:33:48 +08:00
</el-form-item>
2025-09-04 09:21:45 +08:00
<el-form-item :label="t('操作类型')" prop="operationType">
<el-select v-if="operationTypeOption.length > 0" v-model="queryParams.operationType" clearable style="width:220px;" :placeholder="t('请选择')">
<el-option
v-for="dict in operationTypeOption"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
2025-08-27 20:51:27 +08:00
<!-- <el-form-item :label="t('开始时间')" prop="params.beginTime">
2025-08-14 10:33:48 +08:00
<el-date-picker
v-model="queryParams.params.beginTime"
type="date"
:placeholder="t('请选择开始时间')"
:default-value="new Date()"
/>
</el-form-item>
<el-form-item :label="t('结束时间')" prop="params.endTime">
<el-date-picker
v-model="queryParams.params.endTime"
type="date"
:placeholder="t('请选择结束时间')"
:default-value="new Date()"
/>
2025-08-27 20:51:27 +08:00
</el-form-item> -->
2025-08-14 10:33:48 +08:00
</template>
<!-- <template #right>
<el-button type="primary" @click="handleAdd">{{ t('') }}</el-button>
</template> -->
</table-search-card>
<el-table v-loading="loading" :data="agentList" class="c-table-main" stripe border>
<!-- <el-table-column type="selection" width="55" align="center" /> -->
<el-table-column :label="t('商户账号')" align="center" prop="tenantKey" :show-overflow-tooltip="true" min-width="175px">
<template #default="{row}">
{{ row.tenantKey }}
<CopyIcon :colors="'#409EFF'" :text="String(row.tenantKey)"></CopyIcon>
</template>
</el-table-column>
<!-- <el-table-column :label="t('前缀')" width="100" align="center" prop="tenantSn" /> -->
2025-08-27 20:51:27 +08:00
<el-table-column :label="t('玩家账号')" align="center" prop="memberAccount" min-width="120px" :show-overflow-tooltip="true" >
2025-08-14 10:33:48 +08:00
<template #default="{row}">
{{ row.memberAccount? row.memberAccount : '--' }}
</template>
</el-table-column>
2025-08-27 20:51:27 +08:00
<el-table-column :label="t('游戏账号')" align="center" prop="gameAccount" min-width="130px" :show-overflow-tooltip="true" >
2025-08-14 10:33:48 +08:00
<template #default="{row}">
{{ row.gameAccount? row.gameAccount : '--' }}
</template>
</el-table-column>
<el-table-column :label="t('币种')" width="100" align="center" prop="currencyCode" />
<el-table-column :label="t('游戏平台')" align="center" prop="platformName" min-width="130">
<template #default="{row}">
{{ row.platformName? row.platformName : '--' }}
</template>
</el-table-column>
2025-08-26 11:18:24 +08:00
2025-08-14 10:33:48 +08:00
<el-table-column align="center" prop="exchangeMoney" min-width="110px">
<template #header>
{{ t('转账金额') }}
<IconTips>{{ t('会员带入带出的游戏的金币') }}
</IconTips>
</template>
<template #default="{row}">
{{ row.exchangeMoney? row.exchangeMoney : '--' }}
</template>
</el-table-column>
<el-table-column align="center" prop="exchangeMoney" width="150px">
<template #header>
{{ t('商户通用比例(%)') }}
<IconTips>{{ t('商户通用比例备注商户成本9% 会员转入游戏金币100扣除额度90') }}
</IconTips>
</template>
<template #default="{row}">
{{ row.useCost? row.useCost+'%' : '--' }}
</template>
</el-table-column>
2025-08-26 11:18:24 +08:00
<el-table-column :label="t('转账类型')" align="center" prop="isOut" width="130">
2025-08-14 10:33:48 +08:00
<template #default="{row}">
2025-08-26 11:18:24 +08:00
<span v-if="row.isOut == 0">{{ t('') }}</span>
<span v-if="row.isOut == 1">{{ t('') }}</span>
2025-08-14 10:33:48 +08:00
</template>
</el-table-column>
2025-08-26 11:18:24 +08:00
2025-08-14 10:33:48 +08:00
<el-table-column align="center" prop="balance" min-width="80px">
<template #header>
{{ t('操作额度') }}
<!-- <IconTips>
</IconTips> -->
</template>
<template #default="{row}">
2025-08-26 11:18:24 +08:00
<span v-if="row.isOut == 0" style="color: red;">-{{ row.balance ==null ? '--' :row.balance}}</span>
<span v-if="row.isOut == 1" >{{ row.balance ==null ? '--' :row.balance}}</span>
2025-08-14 10:33:48 +08:00
</template>
</el-table-column>
<el-table-column align="center" prop="balanceAfter" width="130px">
<template #header>
{{ t('商户剩余额度') }}
<IconTips>{{ t('额度为会员可带入游戏的金币') }}
</IconTips>
</template>
<template #default="{row}">
2025-08-26 11:18:24 +08:00
{{ row.balanceAfter==null? '--' : row.balanceAfter }}
2025-08-14 10:33:48 +08:00
</template>
</el-table-column>
<el-table-column :label="t('额度类型')" align="center" prop="quotaType" width="85">
<template #default="{row}">
{{ row.quotaTypeName? row.quotaTypeName : '--' }}
</template>
</el-table-column>
2025-08-26 11:18:24 +08:00
<el-table-column :label="t('额度明细')" align="center" prop="platformName" min-width="130">
<template #default="{row}">
<el-popover :width="320" trigger="hover">
<ul class="al-list">
<li>
<span>{{ t('币种') }}</span>
<span>{{ t('可用额度') }}</span>
<span>{{ t('信誉额度') }}</span>
<span>{{ t('平台额度') }}</span>
</li>
<li >
<span>{{ row.currencyCode }}</span>
<span>{{ getQuota(row,'可用额度', 'available') }}</span>
<span>{{ getQuota(row,'信誉额度', 'credit') }}</span>
<span>{{ getQuota(row,'平台额度', 'platform') }}</span>
</li>
<!-- <li v-for="item in curAgentLevelInfo" :key="item.id">
<span>{{ item.currencyType }}</span>
<span>{{ item.levelName || '-' }}</span>
</li> -->
<!-- <li v-if="curAgentLevelInfo.length === 0">
{{ t('暂无信息...') }}
</li> -->
</ul>
<template #reference>
<el-button link type="primary">{{ t('查看') }}</el-button>
</template>
</el-popover>
</template>
</el-table-column>
2025-08-14 10:33:48 +08:00
<el-table-column :label="t('API订单号')" align="center" prop="transactionId" width="120">
<template #default="{row}">
{{ row.transactionId? row.transactionId : '--' }}
</template>
</el-table-column>
<el-table-column :label="t('商户订单号')" align="center" prop="orderId" width="120">
<template #default="{row}">
{{ row.orderId? row.orderId : '--' }}
</template>
</el-table-column>
2025-08-26 11:18:24 +08:00
<el-table-column :label="t('操作类型')" align="center" prop="isOut" width="120">
<template #default="{row}">
<span v-if="row.operationType == 1">{{ t('') }}</span>
<span v-if="row.operationType == 2">{{ t('') }}</span>
<span v-if="row.operationType == 3">{{ t('') }}</span>
<span v-if="row.operationType == 4">{{ t('') }}</span>
<span v-if="row.operationType == 5">{{ t('') }}</span>
<span v-if="row.operationType == 6">{{ t('') }}</span>
<span v-if="row.operationType == 7">{{ t('') }}</span>
</template>
</el-table-column>
2025-08-14 10:33:48 +08:00
<el-table-column :label="t('创建时间')" align="center" prop="createTime" width="200" :show-overflow-tooltip="true">
<template #default="scope">{{ parseTime(scope.row.createTime) }}</template>
</el-table-column>
2025-09-04 09:21:45 +08:00
<el-table-column :label="t('操作')" align="center" min-width="110px">
<template #default="{ row }">
<el-button
type="text"
v-if="row.auditStatus == 0"
v-hasPermi="['super:agent:flow:audit']"
icon="el-icon-edit"
@click="handleAudit(row)"
>{{ t('审计') }}</el-button>
</template>
</el-table-column>
2025-08-14 10:33:48 +08:00
<!-- <el-table-column :label="t('操作')" align="center" width="200" class-name="small-padding fixed-width">
<template #default="scope">
<el-button link type="primary" @click="handleView(scope.row)" v-hasPermi="['agent:tenant:view']">{{ t('') }}</el-button>
</template>
</el-table-column> -->
</el-table>
<pagination
v-show="total > 0"
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</div>
</template>
<script setup name="Agent">
2025-09-04 09:21:45 +08:00
import { superTenantQuotaflow,superCommonPlatSelect,superTenantQuotaAudit,getSuperCommonOperationType } from "@/api/super/tenant";
2025-08-14 10:33:48 +08:00
import Crontab from '@/components/Crontab'
import { getLocalStorage } from "@/utils/auth";
import CopyIcon from '@/components/CopyIcon'
import CustomSelect from '@/components/CustomSelect'
2025-08-27 20:51:27 +08:00
import TableSearchDate from '@/components/TableSearchDate'
2025-08-14 10:33:48 +08:00
import IconTips from '@/components/IconTips'
import { parseTime } from '@/utils/ruoyi'; // 时间格式化
2025-08-27 20:51:27 +08:00
import { nextTick, onMounted } from "vue";
2025-08-26 11:18:24 +08:00
import { get } from "@vueuse/core";
2025-08-14 10:33:48 +08:00
const router = useRouter();
const { proxy } = getCurrentInstance();
const { ff_tenant_type, ff_tenant_status } = proxy.useDict("ff_tenant_type", "ff_tenant_status");
2025-08-27 20:51:27 +08:00
const dateRange = ref([]),operateTimeType = ref("day");
2025-08-14 10:33:48 +08:00
const agentList = ref([]);
const open = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const title = ref("");
const openView = ref(false);
const openCron = ref(false);
const expression = ref("");
const tenantAgentPlatforms = ref([]);
const optionsType = ref([
{ label: proxy.t('请选择'), value: "" },
{ label: proxy.t('商户模式'), value: "tenantType" },
{ label: proxy.t('商户账号'), value: "account" },
{ label: proxy.t('商户状态'), value: "status" },
]);
2025-08-27 20:51:27 +08:00
const today = new Date();
const yyyy = today.getFullYear();
const mm = String(today.getMonth() + 1).padStart(2, '0');
const dd = String(today.getDate()).padStart(2, '0');
2025-08-14 10:33:48 +08:00
const data = reactive({
form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
orderByColumn:'createTime',
2025-08-27 20:51:27 +08:00
currencyCode: 'VND',
2025-08-14 10:33:48 +08:00
isAsc:'desc',
2025-08-27 20:51:27 +08:00
// params:{
// beginTime: `${yyyy}-${mm}-${dd} 00:00:00`,
// endTime: `${yyyy}-${mm}-${dd} 23:59:59`
// },
2025-08-14 10:33:48 +08:00
tenantKey: "",
memberAccount:''
},
rules: {
account: [{ required: true, message: proxy.t('商户账号不能为空'), trigger: "blur" }],
password: [{ required: true, message: proxy.t('密码不能为空'), trigger: "blur" }],
scoreRatio: [{ required: true, message: proxy.t('买分比例不能为空'), trigger: "blur" }],
tenantType: [{ required: true, message: proxy.t('商户模式不能为空'), trigger: "change" }],
}
});
const { queryParams, form, rules } = toRefs(data);
const quotaTypeArr = ref([
{ label: proxy.t('可用额度'), value: "BALANCE" },
{ label: proxy.t('平台额度'), value: "_FALSE" },
{ label: proxy.t('信誉额度'), value: "REPUTATION" },
]);
/** 查询列表 */
function getList() {
loading.value = true;
2025-08-27 20:51:27 +08:00
superTenantQuotaflow(proxy.addDateRange(queryParams.value, dateRange.value)).then(response => {
2025-08-14 10:33:48 +08:00
agentList.value = response.rows;
total.value = response.total;
loading.value = false;
});
}
const sys_job_group = ref([]);
const showLoding1 = ref(true);
const getsuperCommonCurrencySelect = async () => {
showLoding1.value = false;
let res = getLocalStorage('currencySelect');
sys_job_group.value = res.map(item => {
return { label:`${item.currencyName}(${item.currencyCode})`, value: item.currencyCode }
})
nextTick(() => {
showLoding1.value = true;
})
}
const sys_job_status = ref([]);
const showLoding2 = ref(true);
const getsuperCommonPlatformTypeSelect = async () => {
showLoding2.value = false;
let res = getLocalStorage('platformSelect');
sys_job_status.value = res.map(item => {
return { label: item.name, value: item.code }
});
nextTick(() => {
showLoding2.value = true;
})
}
const quotaplatformCodeArr = ref([]);
const showLoding3 = ref(true);
const superCommonPlatSelects = () => {
superCommonPlatSelect().then(res => {
quotaplatformCodeArr.value = res.data.map(item => {
return { label: item.info, value: item.code }
})
showLoding3.value = false;
nextTick(() => {
showLoding3.value = true;
})
})
}
superCommonPlatSelects();
/** 任务组名字典翻译 */
function jobGroupFormat(row, column) {
return proxy.selectDictLabel(sys_job_group.value, row.jobGroup);
}
/** 取消按钮 */
function cancel() {
open.value = false;
reset();
}
2025-08-26 11:18:24 +08:00
const getQuota = (row, type) => {
if (!row || !row.quotaTypeName || !row.balanceStr) return 0;
const names = row.quotaTypeName.split(','); // 拆成数组
const balances = row.balanceStr.split(','); // 拆成数组
const index = names.indexOf(type); // 找到对应下标
if (index === -1) return 0; // 没找到返回 0
return balances[index] || 0; // 对应值不存在也返回 0
}
2025-08-14 10:33:48 +08:00
/** 表单重置 */
function reset() {
form.value = {
account: "",
password: "",
scoreRatio: 1,
tenantType: 1,
tenantAgentPlatforms: [],
};
proxy.resetForm("agentRef");
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1;
getList();
}
/** 重置按钮操作 */
function resetQuery() {
// proxy.resetForm("queryRef");
handleQuery();
}
2025-09-04 09:21:45 +08:00
//审计
const handleAudit = (row) => {
proxy.$modal.confirm(proxy.t('是否审计?')).then(() => {
loading.value = true;
superTenantQuotaAudit({id:row.id}).then(res => {
loading.value = false;
proxy.$modal.msgSuccess(proxy.t('审计成功!'));
handleQuery();
}).catch(() => {
loading.value = false;
});
}).catch(() => { });
}
2025-08-14 10:33:48 +08:00
// 多选框选中数据
function handleSelectionChange(selection) {
ids.value = selection.map(item => item.jobId);
single.value = selection.length != 1;
multiple.value = !selection.length;
}
/** 详细信息 */
function handleView(row) {
form.value = {
account: row.tenantKey,
tenantType: 1,
scoreRatio: proxy.t('1万法定货币=1万通用额度'),
}
openView.value = true;
}
/** 获取平台利润 */
function getSelectPlatform() {
selectPlatform().then(response => {
form.value.tenantAgentPlatforms = response.data;
tenantAgentPlatforms.value = JSON.parse(JSON.stringify(response.data));
});
}
/** 新增按钮操作 */
function handleAdd() {
reset();
getSelectPlatform();
open.value = true;
title.value = proxy.t('添加商户');
}
function queryCode(type) {
form.value.tenantAgentPlatforms = form.value.tenantAgentPlatforms.map((item, index) => {
if (type === 'del' && item.cost > tenantAgentPlatforms.value[index].cost) {
item.cost -= 0.5;
item.useCost -= 0.5
} else if (type === 'add') {
item.cost += 0.5;
item.useCost += 0.5
}
return item
})
}
2025-09-04 09:21:45 +08:00
const operationTypeOption = ref([]);
const getSuperCommonOperationTypes = () => {
getSuperCommonOperationType({}).then(response => {
operationTypeOption.value = response.data.map(item => {
return { label: item.name, value: `${item.code}` }
});
2025-08-14 10:33:48 +08:00
});
2025-09-04 09:21:45 +08:00
};
2025-08-27 20:51:27 +08:00
//初始化
onMounted(() => {
getList();
getsuperCommonCurrencySelect();
2025-09-04 09:21:45 +08:00
getSuperCommonOperationTypes();
2025-08-27 20:51:27 +08:00
getsuperCommonPlatformTypeSelect();
})
2025-08-14 10:33:48 +08:00
</script>
<style scoped lang="scss">
.label-scoreRatio{
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
span{
width: 120px;
text-align: right;
font-weight: 700;
padding-right: 12px;
}
}
.scoreRatioTable{
width: calc(100% - 120px);
margin-left: 120px;
}
2025-08-26 11:18:24 +08:00
.al-list {
padding: 5px 0;
margin: 0;
width: 100%;
list-style: none;
li {
list-style: none;
width: 100%;
text-align: center;
padding: 10px 0;
border-bottom: #eeeeee solid 1px;
&:first-child {
span {
font-weight: bold;
}
}
span {
display: inline-block;
width: 25%;
}
&:last-child {
border: none
}
}
}
// .al-list li span {
// width: 50% !important;
// }
2025-08-14 10:33:48 +08:00
</style>