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

616 lines
22 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="app-container">
<table-search-card :leftSpan="20" :model="queryParams" @getList="getList" @handleQuery="handleQuery" @resetQuery="resetQuery">
<template #left>
<table-search-date v-model:dateRange="dateRange" v-model:operateTimeType="operateTimeType"></table-search-date>
<!-- <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('商户账号')" v-hasPermi="['super:tenant:list']" prop="tenantKey">
<el-select
v-model="queryParams.tenantKey"
filterable
clearable
reserve-keyword
placeholder="请输入商户账号搜索"
:remote-method="loadOptions"
:loading="loadingSelect"
style="width: 240px"
>
<!-- 正常列表 -->
<el-option
v-for="item in agentListSelect"
:key="item.tenantKey"
:label="item.tenantKey"
:value="item.tenantKey"
/>
<!-- 加载更多按钮 -->
<el-option
v-if="hasMore && agentListSelect.length > 0"
disabled
value=""
>
<div
style="color:#409EFF;cursor:pointer;width:100%;"
@click.stop="loadMore"
>
{{ loadingMore ? "加载中..." : "加载更多" }}
</div>
</el-option>
</el-select>
</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">
<CustomSelect v-if="showLoding1" v-model="queryParams.currencyCode" filterable :options="sys_job_group" placeholder="请选择币种" style="width: 200px" />
</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">
<CustomSelect v-if="showLoding3" v-model="queryParams.platformCode" :options="quotaplatformCodeArr" filterable placeholder="请选择平台" style="width: 200px" />
</el-form-item>
<el-form-item :label="t('操作类型')" prop="operationType">
<el-select v-model="queryParams.operationType" clearable style="width:220px;" :placeholder="t('请选择')">
<el-option
v-for="dict in operationTypes"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
<!-- <el-form-item :label="t('开始时间')" prop="params.beginTime">
<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()"
/>
</el-form-item> -->
</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" /> -->
<el-table-column :label="t('玩家账号')" align="center" prop="memberAccount" min-width="180px" >
<template #default="{row}">
{{ row.memberAccount? row.memberAccount : '--' }}
</template>
</el-table-column>
<el-table-column :label="t('游戏账号')" align="center" prop="gameAccount" min-width="180px" >
<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>
<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>
<el-table-column :label="t('转账类型')" align="center" prop="isOut" width="130">
<template #default="{row}">
<span v-if="row.isOut == 0">{{ t('转入第三方平台') }}</span>
<span v-if="row.isOut == 1">{{ t('转出第三方平台') }}</span>
</template>
</el-table-column>
<el-table-column align="center" prop="balance" min-width="80px">
<template #header>
{{ t('操作额度') }}
<!-- <IconTips>
</IconTips> -->
</template>
<template #default="{row}">
<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>
</template>
</el-table-column>
<el-table-column align="center" prop="balanceAfter" width="130px">
<template #header>
{{ t('商户剩余额度') }}
<IconTips>{{ t('额度为会员可带入游戏的金币') }}
</IconTips>
</template>
<template #default="{row}">
{{ row.balanceAfter==null? '--' : row.balanceAfter }}
</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>
<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>
<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>
<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>
<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>
<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>
<!-- <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">
import { superTenantQuotaflow,superCommonPlatSelect,superTenantQuotaAudit,getSuperCommonOperationType,superTenantList } from "@/api/super/tenant";
import Crontab from '@/components/Crontab'
import { getLocalStorage } from "@/utils/auth";
import CopyIcon from '@/components/CopyIcon'
import CustomSelect from '@/components/CustomSelect'
import TableSearchDate from '@/components/TableSearchDate'
import IconTips from '@/components/IconTips'
import { parseTime } from '@/utils/ruoyi'; // 时间格式化
import { nextTick, onMounted } from "vue";
import auth from '@/plugins/auth'
import { get } from "@vueuse/core";
const router = useRouter();
const { proxy } = getCurrentInstance();
const { ff_tenant_type, ff_tenant_status } = proxy.useDict("ff_tenant_type", "ff_tenant_status");
const dateRange = ref([]),operateTimeType = ref("day");
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" },
]);
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');
const data = reactive({
form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
orderByColumn:'createTime',
currencyCode: 'VND',
isAsc:'desc',
// params:{
// beginTime: `${yyyy}-${mm}-${dd} 00:00:00`,
// endTime: `${yyyy}-${mm}-${dd} 23:59:59`
// },
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 operationTypes = ref([
{ label: proxy.t('商户转入转出'), value: 1 },
{ label: proxy.t('日用额度结算'), value: 2 },
{ label: proxy.t('信誉额度充值'), value: 3 },
{ label: proxy.t('后台人工操作'), value: 4 },
{ label: proxy.t('商户订单充值'), value: 5 },
{ label: proxy.t('转入恢复'), value: 6 },
{ label: proxy.t('转出恢复'), value: 7 },
]);
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;
superTenantQuotaflow(proxy.addDateRange(queryParams.value, dateRange.value)).then(response => {
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();
}
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
}
/** 表单重置 */
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();
}
//审计
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(() => { });
}
// 多选框选中数据
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
})
}
const operationTypeOption = ref([]);
const getSuperCommonOperationTypes = () => {
getSuperCommonOperationType({}).then(response => {
operationTypeOption.value = response.data.map(item => {
return { label: item.name, value: `${item.code}` }
});
});
};
const agentListSelect = ref([])
const loadingSelect = ref(false)
const loadingMore = ref(false)
const hasMore = ref(true)
const queryParamSelect = ref({
pageNum: 1,
pageSize: 10,
tenantKey: ""
})
// 加载第一页(搜索)
const loadOptions = async (query) => {
queryParamSelect.value.pageNum = 1
queryParamSelect.value.tenantKey = query
loadingSelect.value = true
try {
const res = await superTenantList(queryParamSelect.value)
agentListSelect.value = res.rows || []
hasMore.value = agentListSelect.value.length < (res.total || 0)
} finally {
loadingSelect.value = false
}
}
// 加载更多(分页)
const loadMore = async () => {
if (!hasMore.value) return
queryParamSelect.value.pageNum++
loadingMore.value = true
try {
const res = await superTenantList(queryParamSelect.value)
agentListSelect.value = [...agentListSelect.value, ...(res.rows || [])]
hasMore.value = agentListSelect.value.length < (res.total || 0)
} finally {
loadingMore.value = false
}
}
//初始化
onMounted(() => {
getList();
if (auth.hasPermi('super:tenant:list') == true){
loadOptions('');
}
getsuperCommonCurrencySelect();
getSuperCommonOperationTypes();
getsuperCommonPlatformTypeSelect();
})
</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;
}
.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;
// }
</style>