feat:1,新增支付三方渠道 2,新增游戏配置超管Api配置 3,修改bug

main
YuanJian 2025-09-23 09:13:48 +08:00
parent 4c54307fc5
commit 98b5c3caaa
87 changed files with 4138 additions and 237 deletions

BIN
dist.rar

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -389,4 +389,55 @@ export function levelConfig(data) {
})
}
/* ------------------------------- 三方支付end ------------------------------- */
/* ------------------------------- 三方支付end ------------------------------- */
/**
* 查询三方支付通道
* @param data
* @returns
*/
export function getChannelExternalList(data) {
return request({
url: '/payment/channelExternal/list',
method: 'post',
data
})
}
/**
* 新增第三方渠道
* @param data
* @returns
*/
export function addChannelExternal(data) {
return request({
url: '/payment/channelExternal',
method: 'post',
data
})
}
/**
* 修改第三方渠道
* @param data
* @returns
*/
export function updateChannelExternal(data) {
return request({
url: '/payment/channelExternal',
method: 'put',
data
})
}
/**
* 获取第三方渠道详细信息
* @param {*} id
* @returns
*/
export function getChannelExternal(id) {
return request({
url: '/payment/channelExternal/' + id,
method: 'get'
})
}

View File

@ -42,3 +42,38 @@ export function deleteGameSecret(id) {
method: 'delete',
})
}
// 查询游戏配置表
export function getGameSuperSecretList(query) {
return request({
url: '/game/super/secret/list',
method: 'get',
params: query
})
}
//获取配置详情
export function getGameSuperSecretInfo(id) {
return request({
url: `/game/super/secret/${id}`,
method: 'get',
})
}
// 新增配置
export function postGameSuperSecret(data) {
return request({
url: '/game/super/secret',
method: 'post',
data: data
})
}
// 修改配置
export function updateGameSuperSecret(data) {
return request({
url: '/game/super/secret',
method: 'put',
data: data
})
}

View File

@ -172,4 +172,55 @@ export function getGamePlatformTenantSync(query) {
method: 'get',
params: query
})
}
//翻译列表
export function getGamePlatformNameList(query) {
return request({
url: '/game/platform/name/list',
method: 'get',
params: query
})
}
//更新翻译列表
export function updateGamePlatformName(data) {
return request({
url: '/game/platform/name',
method: 'put',
data: data
})
}
//新增翻译
export function postGamePlatformName(data) {
return request({
url: '/game/platform/name',
method: 'post',
data: data
})
}
//子游戏翻译列表
export function getGameNameList(query) {
return request({
url: '/game/name/list',
method: 'get',
params: query
})
}
//子游戏更新翻译列表
export function updateGameName(data) {
return request({
url: '/game/name',
method: 'put',
data: data
})
}
//子游戏新增翻译
export function postGameName(data) {
return request({
url: '/game/name',
method: 'post',
data: data
})
}

View File

@ -50,7 +50,7 @@ export function tenantSupplierALB(data) {
// 域名列表
export function getDomainList(query) {
return request({
url: '/domain/list',
url: '/domain//all/list',
method: 'get',
params: query
})

View File

@ -0,0 +1,53 @@
import request from '@/utils/request'
// 查询系统语种管理 列表
export function listLang(query) {
return request({
url: '/operation/lang/list',
method: 'get',
params: query
})
}
// 语种下拉框列表-全部语言 1.app 2.pc
export function selectListLang(query) {
return request({
url: '/operation/lang/select',
method: 'get',
params: query
})
}
// 新增系统语种管理
export function postLang(data) {
return request({
url: '/operation/lang',
method: 'post',
data: data
})
}
// 修改系统语种管理
export function updateLang(data) {
return request({
url: '/operation/lang',
method: 'put',
data: data
})
}
//语言详情
export function getOperationLangInfo(id) {
return request({
url: `/operation/lang/${id}`,
method: 'get',
})
}
// 删除语种
export function delOperationLang(ids) {
return request({
url: '/operation/lang/' + ids,
method: 'delete'
})
}

View File

@ -3,7 +3,7 @@ import request from '@/utils/request'
// 查询第三方支付渠道列表
export function listThirdChannel(query) {
return request({
url: '/payment/thirdChannel/list',
url: '/payment/channel/thirdChannellist',
method: 'get',
params: query
})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -24,7 +24,11 @@
}
}
//
.table-icon-image {
width: 50px;
height: 50px;
}
// tab
.tabs-main-box {
height: calc(100% - 55px);

View File

@ -187,3 +187,47 @@ aside {
margin-bottom: 10px;
}
}
//
.c-blue {
color: #409EFF !important;
cursor: pointer;
user-select: none;
}
.c-green {
color: #42b983 !important;
}
.c-orange {
color: #F56C6C !important;
}
.c-grey {
color: #999999 !important;
}
.c-red {
color: #db0537 !important;
}
//
.c-rotate {
animation: c-spin 2s linear infinite;
/* 应用动画 */
}
.el-form .el-form-item {
margin-right: 10px;
}
@keyframes c-spin {
0% {
transform: rotate(0deg);
/* 起始角度 */
}
100% {
transform: rotate(360deg);
/* 结束角度 */
}
}

View File

@ -0,0 +1,82 @@
<template>
<el-select v-model="selectedValue" :placeholder="isError ? t('获取失败,刷新重试') : t('请选择')" v-bind="$attrs"
:disabled="!isFinish">
<el-option v-for="item in options" :key="item[props.keys]" :disabled="disabledOptions.indexOf(item.value) !== -1" :label="item[props.label]" :value="item[props.keys]" />
</el-select>
</template>
<script setup>
import { getSelectData } from '@/api/common.js';
const props = defineProps({
keys: {
type: String,
default: 'value'
},
label: {
type: String,
default: 'label'
},
url: {
type: String,
default: ''
},
query: {
type: Object,
default: () => ({})
},
method: {
type: String,
default: 'get'
},
assignmentArray: {
type: String,
default: 'rows'
},
disabledOptions: {
type: Array,
default: []
},
hasDefault: { //
type: Boolean,
default: false
},
});
const selectedValue = defineModel(); //
const options = ref([]);
const isFinish = ref(false); //
const isError = ref(false); //
//
function getOptions() {
const { query, method, url, assignmentArray } = props;
const parmas = { pageNumber: 1, pageSize: 100, ...query };
getSelectData(url, parmas, method).then(res => {
options.value = res[assignmentArray];
//
if (props.hasDefault && selectedValue.value === '') {
selectedValue.value = options.value[0][props.keys];
}
isFinish.value = true;
}).catch(() => {
isError.value = true;
})
}
//
watch(() => props.query, (newVal, oldVal) => {
//
if (Object.keys(newVal).length && JSON.stringify(newVal) === JSON.stringify(oldVal)) {
return;
} else {
getOptions();
}
}, { deep: true, immediate: true });
//
defineExpose({
options
});
</script>

View File

@ -0,0 +1,32 @@
<template>
<el-input
v-model="code"
:maxlength="maxlength"
:placeholder="placeholder"
@input="onInput"
/>
</template>
<script setup>
import { ref, watch } from "vue"
const props = defineProps({
modelValue: String,
maxlength: { type: Number, default: 6 },
placeholder: { type: String, default: "请输入验证码" }
})
const emit = defineEmits(["update:modelValue"])
const code = ref(props.modelValue || "")
//
watch(() => props.modelValue, v => code.value = v || "")
//
const onInput = (val) => {
val = val.replace(/\D/g, "").slice(0, props.maxlength)
code.value = val
emit("update:modelValue", val)
}
</script>

View File

@ -8,8 +8,8 @@
<script>
import { defineComponent, nextTick, onMounted, reactive } from "vue";
import { getToken, getLocalStorage } from "@/utils/auth";
const uploadUrl1 = 'http://192.168.50.11:8081';
const uploadUrl = ref(uploadUrl1 + `/file/upload/localSysFile`); //
const uploadUrl1 = getLocalStorage('uploadUrl'); // ;
const uploadUrl = ref(uploadUrl1 + `/file/upload/localSysFile/3`); //
export default defineComponent({
props: {
modelValue: {

View File

@ -27,17 +27,19 @@
/>
</el-menu>
</el-scrollbar> -->
<div class="avatar-container">
<div class="avatar-container" style="margin-right: 10px;" >
<el-dropdown @command="handleCommand" class="right-menu-item hover-effect" trigger="click">
<div class="avatar-wrapper">
<img :src="userStore.avatar" class="user-avatar" />
<el-icon><caret-bottom /></el-icon>
<div class="avatar-wrapper" style="display: flex;align-items: center;justify-content: center;color: #fff;font-size: 14px;">
<!-- <img :src="userStore.avatar" class="user-avatar" />
<el-icon><caret-bottom /></el-icon> -->
{{ nickName }}
</div>
<template #dropdown>
<el-dropdown-menu>
<router-link to="/user/profile">
<!-- <router-link to="/user/profile">
<el-dropdown-item>个人中心</el-dropdown-item>
</router-link>
</router-link> -->
<el-dropdown-item @click="handleClick">{{ t("") }}</el-dropdown-item>
<el-dropdown-item command="setLayout" v-if="settingsStore.showSettings">
<span>布局设置</span>
</el-dropdown-item>
@ -48,6 +50,61 @@
</template>
</el-dropdown>
</div>
<el-dialog :title="t('账号设置')" align-center v-model="dialogVisible" width="700" append-to-body>
<el-scrollbar max-height="600px">
<el-form ref="userRef" :model="formData" :rules="rules" label-width="100px">
<el-form-item label="后台账号" prop="roleName">
{{ formData.userName }}
</el-form-item>
<el-form-item label="后台昵称" prop="nickName">
<el-input v-model="formData.nickName"
:placeholder="t('仅支持中英文和数字为1-20个字符')" maxlength="20" />
</el-form-item>
<el-form-item label="登录密码">
<el-row style="width: 100%;">
<el-col :span="12">
{{ t('已设置') }}
</el-col>
<el-col :span="12" style="display: flex;justify-content: right;">
<el-button type="primary" @click="updatePassword"></el-button>
</el-col>
</el-row>
</el-form-item>
</el-form>
</el-scrollbar>
<template #footer>
<div class="dialog-footer" style="display: flex;justify-content: center;">
<el-button @click="closeDialog"> </el-button>
<el-button type="primary" @click="submitForm"></el-button>
</div>
</template>
</el-dialog>
<!-- 修改密码 -->
<el-dialog :title="t('修改密码')" align-center v-model="passwordDialogVisible" width="630" append-to-body>
<el-scrollbar max-height="600px">
<el-form ref="passwordRef" :model="passwordFormData" :rules="rulesPassword" label-width="100px">
<el-form-item label="旧密码" prop="oldPassword">
<el-input v-model="passwordFormData.oldPassword" placeholder="请输入旧密码" type="password" show-password />
</el-form-item>
<el-form-item label="新密码" prop="newPassword">
<el-input v-model="passwordFormData.newPassword" placeholder="请输入新密码" type="password" show-password />
</el-form-item>
<el-form-item label="确认密码" prop="confirmPassword">
<el-input v-model="passwordFormData.confirmPassword" placeholder="请确认新密码" type="password" show-password/>
</el-form-item>
<el-form-item label="谷歌验证码" prop="codeGoogle">
<CodeInput v-model="passwordFormData.codeGoogle" maxlength="6" placeholder="请输入谷歌验证码"/>
</el-form-item>
</el-form>
</el-scrollbar>
<template #footer>
<div class="dialog-footer" style="display: flex;justify-content: center;">
<el-button @click="closePasswordDialog"> </el-button>
<el-button type="primary" @click="submitPasswordForm"></el-button>
</div>
</template>
</el-dialog>
</div>
</template>
@ -60,20 +117,53 @@ import useAppStore from '@/store/modules/app'
import useSettingsStore from '@/store/modules/settings'
import usePermissionStore from '@/store/modules/permission'
import useUserStore from '@/store/modules/user'
import CodeInput from "@/components/CodeInput";
import { getLocalStorage } from "@/utils/auth";
import { updateUserProfile,getUserProfile,updateUserPwd } from "@/api/system/user";
const route = useRoute();
const appStore = useAppStore()
const userStore = useUserStore()
const settingsStore = useSettingsStore()
const permissionStore = usePermissionStore()
const { proxy } = getCurrentInstance()
const sidebarRouters = computed(() => permissionStore.sidebarRouters);
const showLogo = computed(() => settingsStore.sidebarLogo);
const sideTheme = computed(() => settingsStore.sideTheme);
const theme = computed(() => settingsStore.theme);
const windowWidth = ref(window.innerWidth)
const windowWidth = ref(window.innerWidth);
const nickName = ref(getLocalStorage('userInfo')?.nickName);
const dialogVisible = ref(false);
const rules = ref({
nickName:[
{ required: true, message: '请输入昵称', trigger: 'change' },
]
});
const formData = ref({
});
const oldForm = shallowRef({ });
const passwordDialogVisible = ref(false);
const passwordFormData = ref({
oldPassword: undefined,
newPassword: undefined,
confirmPassword: undefined,
codeGoogle: undefined
});
const equalToPassword = (rule, value, callback) => {
if (passwordFormData.value.newPassword !== value) {
callback(new Error("两次输入的密码不一致"));
} else {
callback();
}
};
const rulesPassword = ref({
oldPassword: [{ required: true, message: "旧密码不能为空", trigger: "change" }],
newPassword: [{ required: true, message: "新密码不能为空", trigger: "change" }, { min: 6, max: 20, message: "长度在 6 到 20 个字符", trigger: "change" }, { pattern: /^[^<>"'|\\]+$/, message: "不能包含非法字符:< > \" ' \\\ |", trigger: "change" }],
confirmPassword: [{ required: true, message: "确认密码不能为空", trigger: "change" }, { required: true, validator: equalToPassword, trigger: "change" }],
codeGoogle: [{ required: true, message: "谷歌验证码不能为空", trigger: "change" }]
});
function updateWidth() {
windowWidth.value = window.innerWidth
}
@ -125,6 +215,51 @@ function logout() {
})
}).catch(() => { });
}
const handleClick = () => {
getUserProfile().then(response => {
formData.value = response.data;
dialogVisible.value = true;
nextTick(() => {
oldForm.value = JSON.stringify(formData.value);
})
});
}
const closeDialog = () => {
dialogVisible.value = false;
}
//
const updatePassword = () => {
passwordDialogVisible.value = true;
}
const submitForm = () => {
proxy.$refs.userRef.validate(valid => {
if (valid) {
if (JSON.stringify(formData.value) != oldForm.value) {
updateUserProfile(formData.value).then(response => {
proxy.$modal.msgSuccess("修改成功");
nickName.value = formData.value.nickName;
dialogVisible.value = false;
});
}else{
dialogVisible.value = false;
}
}
});
}
const closePasswordDialog = () => {
passwordDialogVisible.value = false;
}
const submitPasswordForm = () => {
proxy.$refs.passwordRef.validate(valid => {
if (valid) {
updateUserPwd(passwordFormData.value.oldPassword, passwordFormData.value.newPassword,passwordFormData.value.codeGoogle).then(response => {
proxy.$modal.msgSuccess("修改成功");
passwordDialogVisible.value = false;
});
}
});
}
</script>
<style lang="scss" scoped>

View File

@ -22,7 +22,10 @@ import { download } from '@/utils/request'
import 'virtual:svg-icons-register'
import SvgIcon from '@/components/SvgIcon'
import elementIcons from '@/components/SvgIcon/svgicon'
// 通用下拉列表
import BaseSelect from '@/components/BaseSelect';
// 字典下拉组件
import DictSelect from '@/components/DictSelect';
import './permission' // permission control
import { useDict } from '@/utils/dict'
@ -77,6 +80,8 @@ app.component('ImagePreview', ImagePreview)
app.component('RightToolbar', RightToolbar)
app.component('SelectInputForm', SelectInputForm);
app.component('TableOperation', TableOperation);
app.component('DictSelect', DictSelect);
app.component('BaseSelect', BaseSelect);
app.component('Editor', Editor)
app.use(router)
app.use(store)

View File

@ -1,5 +1,5 @@
import { parseTime } from './ruoyi'
import { getLocalStorage } from '@/utils/auth';
/**
* 表格时间格式化
*/

View File

@ -151,7 +151,7 @@
</el-table>
</div>
<div class="resclass">
<el-button type="primary" @click="handleTap()">... </el-button>
<!-- <el-button type="primary" @click="handleTap()">... </el-button> -->
</div>
</div>
</div>

View File

@ -3,7 +3,7 @@
<table-search-card :model="queryParams" @getList="getList" @handleQuery="handleQuery" @resetQuery="resetQuery">
<template #left>
<el-form-item prop="currencyType">
<currency-select v-model="queryParams.currencyType" style="width: 180px;" clearable @clear="handleQuery"
<currency-select v-model="queryParams.currencyType" filterable style="width: 180px;" clearable @clear="handleQuery"
@change="handleQuery"></currency-select>
</el-form-item>
<el-form-item prop="bankName">

View File

@ -5,7 +5,7 @@
@handleQuery="handleQuery">
</select-input-form>
<el-form-item prop="currency">
<checkbox-select style="width: 230px;" collapse-tags collapse-tags-tooltip v-model="queryParams.currency" :options="currencySelectArr" :placeholder="t('币种')"></checkbox-select>
<checkbox-select style="width: 230px;" collapse-tags collapse-tags-tooltip v-model="queryParams.currency" filterable :options="currencySelectArr" :placeholder="t('币种')"></checkbox-select>
</el-form-item>
<el-form-item prop="supportedFeatures">
<checkbox-select style="width: 230px;" collapse-tags collapse-tags-tooltip v-model="queryParams.supportedFeatures" :options="supportedFeaturesSelectArr" :placeholder="t('支持功能')"></checkbox-select>
@ -17,9 +17,9 @@
</table-search-card>
<el-table v-loading="loading" class="c-table-main" :data="agentList" border>
<el-table-column :label="t('接入时间')" min-width="100" sortable align="center" prop="createTime" >
<el-table-column :label="t('接入时间')" min-width="100" sortable align="center" prop="createTime" >
<template #default="{row}">
{{ parseTime(row.createTime) }}
{{ parseTime(row.createTime||row.updateTime) }}
</template>
</el-table-column>
<el-table-column :label="t('币种')" min-width="100" align="center" prop="currency" >
@ -43,12 +43,16 @@
<span v-if="row.supportedFeatures == 1">{{ t('') }}</span>
</template>
</el-table-column>
<el-table-column :label="t('缴纳保证金')" min-width="70" align="center" prop="depositAmount" >
<el-table-column :label="t('缴纳保证金')" min-width="70" align="center" prop="depositAmount" >
<template #default="{row}">
{{ row.depositAmount }}
{{ row.depositAmount == null ? '--' : row.depositAmount }}
</template>
</el-table-column>
<el-table-column :label="t('联系方式')" min-width="180" align="center" prop="contactInfo" />
<el-table-column :label="t('联系方式')" min-width="180" align="center" prop="contactInfo" >
<template #default="{row}">
{{ row.contactInfo == null ? '--' : row.contactInfo }}
</template>
</el-table-column>
<el-table-column :label="t('三方费率')" align="center" min-width="160" prop="thirdPartyFeeRate">
<template #default="scope">{{ scope.row.thirdPartyFeeRate||'--' }}</template>
</el-table-column>
@ -91,8 +95,8 @@
<el-table-column :label="t('昨日提现成功次数')" sortable align="center" min-width="160" prop="yesterdayWithdrawSucCount">
<template #default="scope">{{ scope.row.yesterdayWithdrawSucCount ==null?'--':scope.row.yesterdayWithdrawSucCount }}</template>
</el-table-column>
<el-table-column :label="t('昨日提现成功时间')" sortable align="center" min-width="160" prop="yesterdayWithdrawAmount">
<template #default="scope">{{ parseTime(scope.row.yesterdayWithdrawIncomeTimeSum) }}</template>
<el-table-column :label="t('昨日提现成功时间(秒)')" sortable align="center" min-width="180" prop="yesterdayWithdrawAmount">
<template #default="scope">{{scope.row.yesterdayWithdrawIncomeTimeSum }}</template>
</el-table-column>
<el-table-column :label="t('累计提现金额')" sortable align="center" min-width="160" prop="totalWithdrawAmount">
<template #default="scope">{{ scope.row.totalWithdrawAmount ==null?'--':scope.row.totalWithdrawAmount }}</template>
@ -127,7 +131,7 @@
</template>
<script setup name="Agent">
<script setup name="PaymentRanking">
import {getPayRankingList} from "@/api/finance";
import CheckboxSelect from "@/components/CheckboxSelect"; //
import { getLocalStorage } from "@/utils/auth";

View File

@ -5,7 +5,7 @@
@handleQuery="handleQuery">
</select-input-form>
<el-form-item prop="currency">
<checkbox-select style="width: 230px;" collapse-tags collapse-tags-tooltip v-model="queryParams.currency" :options="currencySelectArr" :placeholder="t('币种')"></checkbox-select>
<checkbox-select style="width: 230px;" collapse-tags collapse-tags-tooltip v-model="queryParams.currency" filterable :options="currencySelectArr" :placeholder="t('币种')"></checkbox-select>
</el-form-item>
<el-form-item prop="supportedFeatures">
<checkbox-select style="width: 230px;" collapse-tags collapse-tags-tooltip v-model="queryParams.supportedFeatures" :options="supportedFeaturesSelectArr" :placeholder="t('支持功能')"></checkbox-select>
@ -19,7 +19,7 @@
<el-table v-loading="loading" class="c-table-main" :data="agentList" border>
<el-table-column :label="t('接入时间')" min-width="100" sortable align="center" prop="createTime" >
<template #default="{row}">
{{ parseTime(row.createTime) }}
{{ parseTime(row.createTime||row.updateTime) }}
</template>
</el-table-column>
<el-table-column :label="t('币种')" min-width="100" align="center" prop="currency" >
@ -45,10 +45,14 @@
</el-table-column>
<el-table-column :label="t('缴纳保证金')" min-width="70" align="center" prop="depositAmount" >
<template #default="{row}">
{{ row.depositAmount }}
{{ row.depositAmount == null ? '--' : row.depositAmount }}
</template>
</el-table-column>
<el-table-column :label="t('联系方式')" min-width="180" align="center" prop="contactInfo" />
<el-table-column :label="t('联系方式')" min-width="180" align="center" prop="contactInfo" >
<template #default="{row}">
{{ row.contactInfo == null ? '--' : row.contactInfo }}
</template>
</el-table-column>
<el-table-column :label="t('三方费率')" align="center" min-width="160" prop="thirdPartyFeeRate">
<template #default="scope">{{ scope.row.thirdPartyFeeRate||'--' }}</template>
</el-table-column>
@ -91,8 +95,8 @@
<el-table-column :label="t('昨日提现成功次数')" sortable align="center" min-width="160" prop="yesterdayWithdrawSucCount">
<template #default="scope">{{ scope.row.yesterdayWithdrawSucCount ==null?'--':scope.row.yesterdayWithdrawSucCount }}</template>
</el-table-column>
<el-table-column :label="t('昨日提现成功时间')" sortable align="center" min-width="160" prop="yesterdayWithdrawAmount">
<template #default="scope">{{ parseTime(scope.row.yesterdayWithdrawIncomeTimeSum) }}</template>
<el-table-column :label="t('昨日提现成功时间(秒)')" sortable align="center" min-width="180" prop="yesterdayWithdrawAmount">
<template #default="scope">{{scope.row.yesterdayWithdrawIncomeTimeSum }}</template>
</el-table-column>
<el-table-column :label="t('累计提现金额')" sortable align="center" min-width="160" prop="totalWithdrawAmount">
<template #default="scope">{{ scope.row.totalWithdrawAmount ==null?'--':scope.row.totalWithdrawAmount }}</template>
@ -111,9 +115,7 @@
</el-table-column>
<el-table-column :label="t('更新日期')" sortable align="center" min-width="160" prop="balanceAfter">
<template #default="scope">{{ parseTime(scope.row.updateTime) }}</template>
</el-table-column>
</el-table>
<pagination
@ -123,11 +125,10 @@
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
<!-- 新增站点 -->
</template>
<script setup name="Agent">
<script setup name="PaymentRanking">
import {getPayRankingList} from "@/api/finance";
import CheckboxSelect from "@/components/CheckboxSelect"; //
import { getLocalStorage } from "@/utils/auth";

View File

@ -5,7 +5,7 @@
@handleQuery="handleQuery">
</select-input-form>
<el-form-item prop="currency">
<checkbox-select style="width: 230px;" collapse-tags collapse-tags-tooltip v-model="queryParams.currency" :options="currencySelectArr" :placeholder="t('币种')"></checkbox-select>
<checkbox-select style="width: 230px;" collapse-tags collapse-tags-tooltip v-model="queryParams.currency" filterable :options="currencySelectArr" :placeholder="t('币种')"></checkbox-select>
</el-form-item>
<el-form-item prop="supportedFeatures">
<checkbox-select style="width: 230px;" collapse-tags collapse-tags-tooltip v-model="queryParams.supportedFeatures" :options="supportedFeaturesSelectArr" :placeholder="t('支持功能')"></checkbox-select>
@ -17,9 +17,9 @@
</table-search-card>
<el-table v-loading="loading" class="c-table-main" :data="agentList" border>
<el-table-column :label="t('接入时间')" min-width="100" sortable align="center" prop="createTime" >
<el-table-column :label="t('接入时间')" min-width="100" sortable align="center" prop="createTime" >
<template #default="{row}">
{{ parseTime(row.createTime) }}
{{ parseTime(row.createTime||row.updateTime) }}
</template>
</el-table-column>
<el-table-column :label="t('币种')" min-width="100" align="center" prop="currency" >
@ -43,12 +43,16 @@
<span v-if="row.supportedFeatures == 1">{{ t('') }}</span>
</template>
</el-table-column>
<el-table-column :label="t('缴纳保证金')" min-width="70" align="center" prop="depositAmount" >
<el-table-column :label="t('缴纳保证金')" min-width="70" align="center" prop="depositAmount" >
<template #default="{row}">
{{ row.depositAmount }}
{{ row.depositAmount == null ? '--' : row.depositAmount }}
</template>
</el-table-column>
<el-table-column :label="t('联系方式')" min-width="180" align="center" prop="contactInfo" />
<el-table-column :label="t('联系方式')" min-width="180" align="center" prop="contactInfo" >
<template #default="{row}">
{{ row.contactInfo == null ? '--' : row.contactInfo }}
</template>
</el-table-column>
<el-table-column :label="t('三方费率')" align="center" min-width="160" prop="thirdPartyFeeRate">
<template #default="scope">{{ scope.row.thirdPartyFeeRate||'--' }}</template>
</el-table-column>
@ -91,8 +95,8 @@
<el-table-column :label="t('昨日提现成功次数')" sortable align="center" min-width="160" prop="yesterdayWithdrawSucCount">
<template #default="scope">{{ scope.row.yesterdayWithdrawSucCount ==null?'--':scope.row.yesterdayWithdrawSucCount }}</template>
</el-table-column>
<el-table-column :label="t('昨日提现成功时间')" sortable align="center" min-width="160" prop="yesterdayWithdrawAmount">
<template #default="scope">{{ parseTime(scope.row.yesterdayWithdrawIncomeTimeSum) }}</template>
<el-table-column :label="t('昨日提现成功时间(秒)')" sortable align="center" min-width="180" prop="yesterdayWithdrawAmount">
<template #default="scope">{{scope.row.yesterdayWithdrawIncomeTimeSum }}</template>
</el-table-column>
<el-table-column :label="t('累计提现金额')" sortable align="center" min-width="160" prop="totalWithdrawAmount">
<template #default="scope">{{ scope.row.totalWithdrawAmount ==null?'--':scope.row.totalWithdrawAmount }}</template>
@ -127,7 +131,7 @@
</template>
<script setup name="Agent">
<script setup name="PaymentRanking">
import {getPayRankingList} from "@/api/finance";
import CheckboxSelect from "@/components/CheckboxSelect"; //
import { getLocalStorage } from "@/utils/auth";

View File

@ -7,7 +7,7 @@
</el-tabs>
<!-- 列表组件 -->
<div class="tabs-main-box">
<available-third-party v-if="activeName == 'AvailableThirdParty'" v-hasPermi="['report:quotas:flow:list']"></available-third-party>
<available-third-party v-if="activeName == 'AvailableThirdParty'"></available-third-party>
<deactivated v-if="activeName == 'Deactivated'"></deactivated>
<all-three-parties v-if="activeName == 'AllThreeParties'"></all-three-parties>
</div>
@ -15,7 +15,7 @@
</template>
<!-- 稽核管理 -->
<script setup name="User">
<script setup name="PaymentRanking">
import AvailableThirdParty from "./availableThirdParty/list.vue";
import Deactivated from "./deactivated/list.vue";
import AllThreeParties from "./allThreeParties/list.vue";

View File

@ -0,0 +1,98 @@
<template>
<el-dialog :title="t('修改备注')" v-model="showDialog" width="800" append-to-body @close="closeDialog">
<el-form class="form-bg" ref="formRef" :model="form" :rules="rules" label-width="50">
<el-form-item :label="t('备注')" prop="remark">
<el-checkbox v-model="checkAll" :indeterminate="isIndeterminate" @change="handleCheckAllChange">
{{ t('全选') }}
</el-checkbox>
<el-checkbox-group v-model="form.levelIds" @change="handleCheckedCitiesChange">
<el-checkbox v-for="item in levelList" :key="item.id" :value="String(item.id)">
{{ item.levelName }}
</el-checkbox>
</el-checkbox-group>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeDialog">{{ t(' ') }}</el-button>
<el-button type="primary" @click="submitForm" :loading="loadingButton">{{ t('确 定') }}</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import { levelConfig } from '@/api/finance/recharge'
import { listLevel } from "@/api/member/level";
const { proxy } = getCurrentInstance()
const emits = defineEmits(['update:show', 'update:data'])
const props = defineProps({
data: {
type: Object,
default: {}
},
show: {
type: Boolean,
default: false
}
})
const form = computed({
get() {
return props.data
},
set(value) {
emits('update:data', value)
}
})
const showDialog = computed({
get() {
return props.show
},
set(value) {
emits('update:show', value)
}
})
const rules = ref([]);
const loadingButton = ref(false)
const closeDialog = () => {
showDialog.value = false
}
const submitForm = () => {
form.value.levelIds = form.value.levelIds.join(',');
loadingButton.value = true;
levelConfig(form.value).then(res => {
loadingButton.value = false;
closeDialog()
proxy.$modal.msgSuccess(proxy.t('修改会员层级成功!'))
emits('submit')
}).catch(() => {
loadingButton.value = false;
})
}
const checkAll = ref(false)
const isIndeterminate = ref(true)
const handleCheckAllChange = (val) => {
form.value.levelIds = val ? levelList.value.map(item => { return String(item.id) }) : []
isIndeterminate.value = false
}
const handleCheckedCitiesChange = (value) => {
const checkedCount = value.length
checkAll.value = checkedCount === levelList.value.length
isIndeterminate.value = checkedCount > 0 && checkedCount < levelList.value.length
}
/** 查询会员层级列表 */
const levelList = ref([])
const getLevelList = async () => {
await listLevel({ pageNum: 1, pageSize: 1000 }).then(response => {
levelList.value = response.rows
});
}
getLevelList()
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,67 @@
<template>
<el-dialog :title="t('修改备注')" v-model="showDialog" width="500" append-to-body @close="closeDialog">
<el-form class="form-bg" ref="formRef" :model="form" :rules="rules" label-width="50">
<el-form-item :label="t('备注')" prop="remark">
<el-input type="textarea" v-model="form.remark" :placeholder="t('请输入备注')" :rows="4" maxlength="250"
show-word-limit />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeDialog">{{ t(' ') }}</el-button>
<el-button type="primary" @click="submitForm" :loading="loadingButton">{{ t('确 定') }}</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import { editRemark } from '@/api/finance/recharge'
const { proxy } = getCurrentInstance()
const emits = defineEmits(['update:show', 'update:data'])
const props = defineProps({
data: {
type: Object,
default: {}
},
show: {
type: Boolean,
default: false
}
})
const form = computed({
get() {
return props.data
},
set(value) {
emits('update:data', value)
}
})
const showDialog = computed({
get() {
return props.show
},
set(value) {
emits('update:show', value)
}
})
const loadingButton = ref(false)
const rules = ref([])
const closeDialog = () => {
showDialog.value = false
}
const submitForm = () => {
form.value.remark = form.value.remark.trim();
loadingButton.value = true;
editRemark(form.value).then(res => {
loadingButton.value = false;
closeDialog()
proxy.$modal.msgSuccess(proxy.t('修改备注成功!'))
emits('submit')
}).catch(() => {
loadingButton.value = false;
})
}
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,84 @@
<template>
<el-dialog :title="t('配置手续费减免')" v-model="showDialog" width="700" append-to-body @close="closeDialog">
<el-form ref="formRef" :model="form" :rules="rules" label-width="140">
<el-form-item :label="t('限前多少次充值')" prop="payCount">
<number-input class="num-input" v-model="form.payCount" :placeholder="t('请输入限前多少次充值')">
<template #append>{{ t('次') }}</template>
</number-input>
<div class="mt10 tips">{{ t('可限定前多少次充值,才减免手续费') }}</div>
</el-form-item>
<el-form-item :label="t('单笔充值金额限定')" prop="payAmount">
<number-input class="num-input" v-model="form.payAmount" :placeholder="t('请输入单笔充值金额限定')">
<template #prepend>{{ currencySign }}</template>
</number-input>
<div class="mt10 tips">{{ t('单笔金额小于此金额,才减免手续费,按充值金额填写(非游戏分数)') }}</div>
</el-form-item>
<el-form-item :label="t('减免百分比')" prop="reduceRate">
<number-input class="num-input" v-model="form.reduceRate" :digit="2" :placeholder="t('请输入减免百分比')" :min="0"
:max="100">
<template #append>%</template>
</number-input>
<div class="mt10 tips">{{ t('例如填入60%表示减免总手续费的60%') }}</div>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeDialog">{{ t(' ') }}</el-button>
<el-button type="primary" @click="submitForm" >{{ t('确 定') }}</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import NumberInput from "@/components/NumberInput/index.vue"; //
const { proxy } = getCurrentInstance();
const emits = defineEmits(['submit', 'update:data', 'update:show'])
const props = defineProps({
data: {
type: Object,
default: {}
},
show: Boolean,
currencySign: {
type: String,
default: ''
}
})
const form = computed({
get() {
return props.data
},
set(value) {
emits('update:data', value)
}
})
const showDialog = computed({
get() {
return props.show
},
set(value) {
emits('update:show', value)
}
})
const rules = reactive({})
const closeDialog = () => {
showDialog.value = false
}
const submitForm = async () => {
closeDialog()
emits('submit')
}
</script>
<style scoped lang="scss">
.tips {
width: 100%;
color: #999999;
}
.num-input {
width:50%;
}
</style>

View File

@ -0,0 +1,301 @@
<template>
<el-form v-if="lodingForm" :ref="(el) =>formRefs[index] = el " :model="item" :rules="rules" label-width="120"
v-for="(item, index) in fieldConfigList" :key="new Date()" style="margin-bottom: 15px;">
<el-row :span="24">
<el-col :span="9" class="position-top">
<el-form-item prop="fieldName" :label="t('字段名称')">
<template #label>
<div class="label-center">
<span>{{ t('字段名称') }}</span>
</div>
</template>
<el-input v-model="item.fieldName" :maxlength="50" :placeholder="t('请输入字段名称')" />
</el-form-item>
</el-col>
<el-col :span="9" class="position-top">
<el-form-item prop="fieldCode" :label="t('字段编码')">
<template #label>
<div class="label-center">
<span>{{ t('字段编码') }}</span>
</div>
</template>
<el-input v-model="item.fieldCode" :maxlength="50" :placeholder="t('请输入字段编码')" />
</el-form-item>
</el-col>
<el-col :span="6" class="position-bottm">
<el-form-item>
<el-button icon="Delete" v-if="fieldConfigList.length > 1" @click="handleDelete(index,item)">{{ t('')
}}</el-button>
<el-button type="primary" icon="Plus" @click="handleAdd" v-if="index === fieldConfigList.length - 1">{{
t('渠道配置') }}</el-button>
</el-form-item>
</el-col>
<el-col :span="12" class="position-top">
<el-form-item prop="pcId" :label="t('第三方渠道ID')">
<template #label>
<div class="label-center">
<span>{{ t('第三方渠道ID') }}</span>
</div>
</template>
<el-input v-model="item.pcId" :maxlength="50" :placeholder="t('请输入第三方渠道ID')" />
</el-form-item>
</el-col>
<el-col :span="12" class="position-top">
<el-form-item prop="defaultValue" :label="t('默认值')">
<template #label>
<div class="label-center">
<span>{{ t('默认值') }}</span>
</div>
</template>
<el-input v-model="item.defaultValue" :maxlength="50" :placeholder="t('请输入默认值')" />
</el-form-item>
</el-col>
<el-col :span="24" class="position-top">
<el-form-item prop="remark" :label="t('描述')">
<template #label>
<div class="label-center">
<span>{{ t('描述') }}</span>
</div>
</template>
<el-input v-model="item.remark" :maxlength="50" :placeholder="t('请输入描述')" />
</el-form-item>
</el-col>
<el-col :span="12" class="position-top">
<el-form-item prop="mustFlag" :label="t('是否必填')">
<template #label>
<div class="label-center">
<span>{{ t('是否必填') }}</span>
</div>
</template>
<el-radio-group v-model="item.mustFlag">
<el-radio :value="1">{{ t('必填') }}</el-radio>
<el-radio :value="0">{{ t('非必填') }}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12" class="position-top">
<el-form-item prop="merchantFlag" :label="t('是否是商户号')">
<template #label>
<div class="label-center">
<span>{{ t('是否是商户号') }}</span>
</div>
</template>
<el-radio-group v-model="item.merchantFlag">
<el-radio :value="1">{{ t('是商户号') }}</el-radio>
<el-radio :value="0">{{ t('非商户号') }}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
</el-form>
<fee-reduction v-if="dialogShowData.showFeeReduction" v-model:show="dialogShowData.showFeeReduction" v-model:data="addQuery" @submit="settingSubmit"
:currencySign="currencySign"></fee-reduction>
<recharge-config v-if="dialogShowData.showRechargeConfig" v-model:show="dialogShowData.showRechargeConfig" v-model:data="addQuery" @submit="settingSubmit"
:currencySign="currencySign"></recharge-config>
<recommended-amount v-if="dialogShowData.showRecommendedAmount" v-model:show="dialogShowData.showRecommendedAmount" v-model:data="addQuery" @submit="settingSubmit"
:currencySign="currencySign"></recommended-amount>
</template>
<script setup>
import CheckboxSelect from "@/components/CheckboxSelect";
import IconTips from "@/components/IconTips"; //
import SetLangContent from "@/components/SetLangContent"; //
import NumberInput from "@/components/NumberInput/index.vue"; //
import FeeReduction from "./FeeReduction.vue";
import RecommendedAmount from "./RecommendedAmount.vue";
import RechargeConfig from "./RechargeConfig.vue";
import { listLevel } from "@/api/member/level";
import { listChannelProduct } from "@/api/payment/channelProduct";
import { el } from "element-plus/es/locales.mjs";
import { nextTick, ref } from "vue";
const { proxy } = getCurrentInstance()
const props = defineProps({
data: {
type: Object,
default: {}
},
currencySign: {
type: String,
default: ''
},
formData: {
type: Object,
default: {}
}
})
const emits = defineEmits(['update:data'])
const fieldConfigList = computed({
get() {
return props.data
},
set(value) {
emits('update:data', value)
}
})
const validateUniqueCombo = (rule, value, callback, index) => {
const currentItem = fieldConfigList.value[index];
const duplicate = fieldConfigList.value.some((item, i) => {
return (
i !== index &&
item.parentId === currentItem.parentId &&
item.channelProductCode === currentItem.channelProductCode
);
});
if (duplicate) {
callback(new Error('所属大类与编码组合重复'));
} else {
callback();
}
const field = `parentId`;
formRefs.value[index]?.clearValidate(field);
const field1 = `channelProductCode`;
formRefs.value[index]?.clearValidate(field1);
};
const rules = ref({
})
const formRefs = ref([])
//
const validateForms = async () => {
let isValid = true;
for (let i = 0; i < formRefs.value.length; i++) {
try {
await formRefs.value[i].validate();
} catch (error) {
isValid = false;
break;
}
}
return isValid;
};
//
const handleAdd = () => {
fieldConfigList.value.push({
pcId:null,
fieldName:null,
fieldCode:null,
defaultValue:null,
mustFlag:1,
merchantFlag:1,
remark:null,
})
}
const IdArr = ref([]);
const lodingForm = ref(true);
//
const handleDelete = (index,item) => {
IdArr.value.push(item.id);
props.formData.deleteIdList = IdArr.value;
fieldConfigList.value.splice(index, 1)
// vuenextTick()formRefs.value[index]null
lodingForm.value = false;
nextTick(() => {
formRefs.value.splice(index, 1);
lodingForm.value = true;
})
}
//
const dialogShowData = ref({
showFeeReduction: false,
showRechargeConfig: false,
showRecommendedAmount: false,
})
const addQuery = ref({})
//
const channelProductList = ref([])
const getListChannelProduct = async (rows) => {
// const params = { pageNum: 1, pageSize: 1000, thirdChannelId: id, productType: 0 }
// await listChannelProduct(params).then(response => {
// channelProductList.value = response.rows
// });
channelProductList.value = rows
}
//
const resetChannelProductList = () => {
channelProductList.value = []
}
const settingSubmit = () => {
// console.log(fieldConfigList.value, '------')
}
defineExpose({
getListChannelProduct,
resetChannelProductList,
validateForms
})
</script>
<style scoped lang="scss">
.el-form {
width: 100%;
}
.channel-form {
--el-collapse-header-bg-color: #f5f7fa;
--el-collapse-content-bg-color: #f5f7fa;
:deep(.el-collapse-item__header) {
border-bottom: 1px solid #ddd !important;
}
}
.position-top .el-form-item {
display: block;
:deep(.el-form-item__label) {
justify-content: start;
}
}
.position-bottm {
display: flex;
.el-form-item {
align-items: end;
}
}
.input-group {
width: 100%;
display: flex;
align-items: center;
}
.channel-title {
width: 100%;
display: flex;
align-items: center;
padding: 0 10px;
}
.collapse-icon {
width: 60px;
display: flex;
align-items: center;
justify-content: space-between;
padding-right: 10px;
.collapse-active {
color: #409eff;
cursor: pointer;
}
}
.label-center {
display: flex;
align-items: center;
}
</style>

View File

@ -0,0 +1,298 @@
<template>
<el-form v-if="lodingForm" :ref="(el) =>formRefs[index] = el " :model="item" :rules="rules" label-width="120"
v-for="(item, index) in paymentList" :key="new Date()" style="margin-bottom: 15px;">
<el-row :span="24">
<el-col :span="4" class="position-top">
<el-form-item prop="productCode" :key="index" :label="t('产品编号')">
<template #label>
<div class="label-center">
<span>{{ t('产品编号') }}</span>
<icon-tips trigger="hover">{{ t('与三方支付确认支付的产品编号') }}</icon-tips>
</div>
</template>
<el-input v-model="item.productCode" :maxlength="50" :placeholder="t('请输入产品编号')" />
</el-form-item>
</el-col>
<el-col :span="5" class="position-top">
<el-form-item prop="productName" :label="t('产品名称')">
<template #label>
<div class="label-center">
<span>{{ t('产品名称') }}</span>
<icon-tips trigger="hover">{{ t('大厅充值界面的通道显示名称') }}</icon-tips>
</div>
</template>
<el-input v-model="item.productName" :maxlength="50" :placeholder="t('请输入产品名称')" />
</el-form-item>
</el-col>
<el-col :span="5" class="position-top">
<el-form-item prop="productType" :label="t('产品类型')">
<template #label>
<div class="label-center">
<span>{{ t('产品类型') }}</span>
<icon-tips trigger="hover">{{
t('与三方支付对接确认的该通道所属的类型默认为普通类型USDT及支付宝SDK为对应选择') }}</icon-tips>
</div>
</template>
<dict-select style="width: 100%;" v-model="item.productType"
dictKey="ff_channel_product_type" :placeholder="t('请选择产品类型')" ></dict-select>
</el-form-item>
</el-col>
<el-col :span="6" class="position-bottm">
<el-form-item>
<el-button icon="Delete" v-if="paymentList.length > 1" @click="handleDelete(index,item)">{{ t('')
}}</el-button>
<el-button type="primary" icon="Plus" @click="handleAdd" v-if="index === paymentList.length - 1">{{
t('新增渠道产品') }}</el-button>
</el-form-item>
</el-col>
<el-col :span="24" class="mb20" style="margin-top: 10px;">
<el-form-item :label="t('通道单笔限额')" required>
<div class="input-group">
<el-form-item prop="limitMin" :rules="[{
required: true,
message: '请输入最大通道单笔限额'
}, {
validator: (rule, value, callback) => {
if (value >= item.limitMax) {
return callback(new Error('最小金额应小于最大金额'))
} else {
return callback()
}
}
}]">
<number-input v-model="item.limitMin" :maxlength="16"
:placeholder="t('请输入最小通道单笔限额')" />
</el-form-item>
<span class="ml20 mr20">~</span>
<el-form-item prop="limitMax" :rules="[{
required: true,
message: '请输入最大通道单笔限额'
}, {
validator: (rule, value, callback) => {
if (value <= item.limitMin) {
return callback(new Error('最大金额应大于最小金额'))
} else {
return callback()
}
}
}]">
<number-input v-model="item.limitMax" :maxlength="16"
:placeholder="t('请输入最大通道单笔限额')" />
</el-form-item>
</div>
</el-form-item>
</el-col>
</el-row>
</el-form>
<fee-reduction v-if="dialogShowData.showFeeReduction" v-model:show="dialogShowData.showFeeReduction" v-model:data="addQuery" @submit="settingSubmit"
:currencySign="currencySign"></fee-reduction>
<recharge-config v-if="dialogShowData.showRechargeConfig" v-model:show="dialogShowData.showRechargeConfig" v-model:data="addQuery" @submit="settingSubmit"
:currencySign="currencySign"></recharge-config>
<recommended-amount v-if="dialogShowData.showRecommendedAmount" v-model:show="dialogShowData.showRecommendedAmount" v-model:data="addQuery" @submit="settingSubmit"
:currencySign="currencySign"></recommended-amount>
</template>
<script setup>
import CheckboxSelect from "@/components/CheckboxSelect";
import IconTips from "@/components/IconTips"; //
import SetLangContent from "@/components/SetLangContent"; //
import NumberInput from "@/components/NumberInput/index.vue"; //
import FeeReduction from "./FeeReduction.vue";
import RecommendedAmount from "./RecommendedAmount.vue";
import RechargeConfig from "./RechargeConfig.vue";
import { listLevel } from "@/api/member/level";
import { listChannelProduct } from "@/api/payment/channelProduct";
import { el } from "element-plus/es/locales.mjs";
import { nextTick, ref } from "vue";
const { proxy } = getCurrentInstance()
const props = defineProps({
data: {
type: Object,
default: {}
},
currencySign: {
type: String,
default: ''
},
formData: {
type: Object,
default: {}
}
})
const emits = defineEmits(['update:data'])
const paymentList = computed({
get() {
return props.data
},
set(value) {
emits('update:data', value)
}
})
const rules = ref({
parentId: [
{ required: true, message: proxy.t('请选择通道所属大类') }
],
channelProductCode: [
{ required: true, message: proxy.t('请选择通道编码') },
],
channelProductName: [
{ required: true, message: proxy.t('请输入通道名称') }
],
channelProductType: [
{ required: true, message: proxy.t('请选择通道类型') }
],
levelIds: [
{ required: true, message: proxy.t('请选择会员层级') }
],
terminals: [
{ required: true, message: proxy.t('请选择终端') }
],
moneyMin: [
{ required: true, message: proxy.t('请输入最小通道单笔限额') }
],
moneyMax: [
{ required: true, message: proxy.t('请输入最大通道单笔限额') }
],
})
const formRefs = ref([])
//
const validateForms = async () => {
let isValid = true;
for (let i = 0; i < formRefs.value.length; i++) {
try {
await formRefs.value[i].validate();
} catch (error) {
isValid = false;
break;
}
}
return isValid;
};
//
const handleAdd = () => {
paymentList.value.push({
productCode:'',
productCode:'',
productType:'',
limitMin:'',
limitMax:'',
status:0,
})
}
const IdArr = ref([]);
const lodingForm = ref(true);
//
const handleDelete = (index,item) => {
IdArr.value.push(item.id);
props.formData.deleteIdList = IdArr.value;
paymentList.value.splice(index, 1)
// vuenextTick()formRefs.value[index]null
lodingForm.value = false;
nextTick(() => {
formRefs.value.splice(index, 1);
lodingForm.value = true;
})
}
//
const dialogShowData = ref({
showFeeReduction: false,
showRechargeConfig: false,
showRecommendedAmount: false,
})
const addQuery = ref({})
//
const channelProductList = ref([])
const getListChannelProduct = async (rows) => {
// const params = { pageNum: 1, pageSize: 1000, thirdChannelId: id, productType: 0 }
// await listChannelProduct(params).then(response => {
// channelProductList.value = response.rows
// });
channelProductList.value = rows
}
//
const resetChannelProductList = () => {
channelProductList.value = []
}
const settingSubmit = () => {
// console.log(paymentList.value, '------')
}
defineExpose({
getListChannelProduct,
resetChannelProductList,
validateForms
})
</script>
<style scoped lang="scss">
.el-form {
width: 100%;
}
.channel-form {
--el-collapse-header-bg-color: #f5f7fa;
--el-collapse-content-bg-color: #f5f7fa;
:deep(.el-collapse-item__header) {
border-bottom: 1px solid #ddd !important;
}
}
.position-top .el-form-item {
display: block;
:deep(.el-form-item__label) {
justify-content: start;
}
}
.position-bottm {
display: flex;
.el-form-item {
align-items: end;
}
}
.input-group {
width: 100%;
display: flex;
align-items: center;
}
.channel-title {
width: 100%;
display: flex;
align-items: center;
padding: 0 10px;
}
.collapse-icon {
width: 60px;
display: flex;
align-items: center;
justify-content: space-between;
padding-right: 10px;
.collapse-active {
color: #409eff;
cursor: pointer;
}
}
.label-center {
display: flex;
align-items: center;
}
</style>

View File

@ -0,0 +1,117 @@
<template>
<el-dialog :title="t('配置充值赠送')" v-model="showDialog" width="1000" append-to-body @close="closeDialog">
<el-form class="form-bg" ref="rechargeConfigForm" :model="form" :rules="rules" label-width="180">
<el-form-item :label="t('会员层级')" prop="deduceRateType">
<el-radio-group v-model="form.deduceRateType" @change="deduceRateTypeChange">
<el-radio :value="0" :label="t('不区分层级')"></el-radio>
<el-radio :value="1" :label="t('按层级分别配置充值赠送')"></el-radio>
</el-radio-group>
<div class="tips">{{ t('可所有会员统一配置赠送,也可按不同会员层级分别配置充值赠送;') }}</div>
<div class="tips">{{ t('未配置充值赠送的会员层级,无充值赠送。') }}</div>
</el-form-item>
<el-tabs v-model="activeTab" type="card" v-if="form.deduceRateType === 1" class="tab-bg">
<el-tab-pane v-for="item in form.chargeRateLevelList" :key="item.leavelId" :label="item.leavelName" />
</el-tabs>
<recharge-config-item v-model:data="addQuery" :currencySign="currencySign"></recharge-config-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeDialog">{{ t(' ') }}</el-button>
<el-button type="primary" @click="submitForm" :loading="loadingButton">{{ t('确 定') }}</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import RechargeConfigItem from './RechargeConfigItem.vue'
import * as recharge from "@/api/finance/recharge"
const { proxy } = getCurrentInstance();
const emits = defineEmits(['submit', 'update:data', 'update:show'])
const props = defineProps({
data: {
type: Object,
default: {}
},
show: Boolean,
currencySign: {
type: String,
default: ''
}
})
const form = computed({
get() {
return props.data
},
set(value) {
emits('update:data', value)
}
})
const showDialog = computed({
get() {
return props.show
},
set(value) {
emits('update:show', value)
}
})
const activeTab = ref('0')
const addQuery = ref({})
const loadingButton = ref(false)
const rules = reactive({
deduceRateType: [
{ required: true, message: proxy.t('请选择会员层级') },
],
})
const closeDialog = () => {
showDialog.value = false
}
const submitForm = async () => {
closeDialog()
emits('submit')
}
const deduceRateTypeChange = (val) => {
if (val === 1 && form.value.chargeRateLevelList.length === 0) {
form.value.deduceRateType = 0
return proxy.$modal.msgError('请先添加会员层级')
}
}
watch(() => form.value.deduceRateType, (val) => {
if (val === 0) {
addQuery.value = form.value
} else if (val === 1) {
addQuery.value = form.value.chargeRateLevelList[activeTab.value || 0]
}
}, { immediate: true })
watch(() => activeTab.value, (val) => {
addQuery.value = form.value.chargeRateLevelList[activeTab.value || 0]
})
onMounted(() => {
})
</script>
<style scoped lang="scss">
.form-bg {
padding: 20px 0;
background: #f5f7fa;
}
.tips {
width: 100%;
color: #999999;
}
.num-input {
width: 50%;
}
.tab-bg {
background: #f5f7fa;
}
</style>

View File

@ -0,0 +1,125 @@
<template>
<el-form-item :class="{ 'form-item-center': index === 0 }"
:label="`${item.minAmount ?? 0} ${t('到')} ${item.maxAmount ?? ''}`" v-for="(item, index) in form.chargeRateList"
:key="index">
<el-row :span="24" style="width: 100%;">
<el-col :span="10">
<el-form-item :label="index === 0 ? t('充值金额区间(含)') : ''" label-position="top">
<number-input v-model="item.maxAmount" :placeholder="t('请输入金额')" :digit="2" :maxlength="12">
<template #prepend>{{ currencySign }}</template>
</number-input>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item :label="index === 0 ? t('赠送比例') : ''" label-position="top">
<number-input v-model="item.chargeRate" :placeholder="t('请输入赠送比例')" :digit="2" :max="100">
<template #append>%</template>
</number-input>
</el-form-item>
</el-col>
<el-col :span="4" v-if="form.chargeRateList">
<el-form-item label-position="top">
<template #label v-if="index === 0">
<div style="height: 22px;"></div>
</template>
<el-button v-if="form.chargeRateList.length > 1" icon="Delete" circle
@click="handleDelete(index)" />
<el-button v-if="index === form.chargeRateList.length - 1" type="primary" icon="Plus" circle
@click="handleAdd(item)" />
</el-form-item>
</el-col>
</el-row>
<div class="tips">
{{ t('预计赠送金额') }}
<span>{{ ((item.minAmount * item.chargeRate) / 100).toFixed(2) ?? '--' }}</span> ~
<span>{{ ((item.maxAmount * item.chargeRate) / 100).toFixed(2) ?? '--' }}</span>
</div>
</el-form-item>
<el-form-item :label="t('赠送金额上限')" prop="deduceLimit">
<number-input v-model="form.deduceLimit" :placeholder="t('请输入赠送金额上限')" :maxlength="12"></number-input>
</el-form-item>
<el-form-item :label="t('赠送次数上限')" prop="deduceCountType">
<el-radio-group style="width: 100%;" v-model="form.deduceCountType">
<el-radio :value="0" :label="t('每日赠送上限次数')"></el-radio>
<el-radio :value="1" :label="t('总共赠送上限次数')"></el-radio>
</el-radio-group>
<number-input class="num-input" v-model="form.deduceCount" :maxlength="12"
:placeholder="t('请输入赠送上限次数,不填表示不限次数')"></number-input>
<div class="tips">{{ t('可选择每日、总共其中一种,设置会员充值赠送次数上限') }}</div>
</el-form-item>
</template>
<script setup>
import NumberInput from "@/components/NumberInput/index.vue"; //
const { proxy } = getCurrentInstance();
const emits = defineEmits(['update:data', 'update:show'])
const props = defineProps({
data: {
type: Object,
default: {}
},
currencySign: {
type: String,
default: ''
}
})
const form = computed({
get() {
return props.data
},
set(value) {
emits('update:data', value)
}
})
//
const handleAdd = (item) => {
if (!item.maxAmount) {
return proxy.$message.error(proxy.t('请输入金额'))
} else if (!item.chargeRate) {
return proxy.$message.error(proxy.t('请输入赠送比例'))
} else if (item.maxAmount <= item.minAmount) {
return proxy.$message.error(proxy.t('最大金额必须大于最小金额'))
}
form.value.chargeRateList.push({
minAmount: '',
maxAmount: '',
chargeRate: ''
})
}
// chargeRateList
watch(
() => form.value.chargeRateList,
(newVal) => {
if (newVal && newVal.length > 0) {
newVal[0].minAmount = 0; // minAmount 0
for (let i = 1; i < newVal.length; i++) {
newVal[i].minAmount = Number(newVal[i - 1].maxAmount) + 0.01;
}
}
},
{ deep: true, immediate: true }
)
//
const handleDelete = (index) => {
form.value.chargeRateList.splice(index, 1)
}
</script>
<style scoped lang="scss">
.form-item-center {
align-items: center;
}
.tips {
width: 100%;
color: #999999;
}
.num-input {
width: 50%;
}
</style>

View File

@ -0,0 +1,174 @@
<template>
<el-dialog :title="t('推荐金额')" v-model="showDialog" width="1000" append-to-body @close="closeDialog">
<el-form ref="formRef" :model="form" :rules="rules" label-width="140">
<el-form-item :label="t('充值限制')" prop="rechargeLimit">
<el-radio-group v-model="form.rechargeLimit">
<el-radio :value="1">{{ t('可输入任意金额') }}</el-radio>
<el-radio :value="2">{{ t('仅限固定金额') }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item :label="t('推荐金额设置')" prop="referrerAmountList">
<div style="background-color:transparent;border-left:1px solid rgb(235,238,245);border-bottom:1px solid rgb(235,238,245)">
<div class="row-view" style="background-color:rgb(245,247,250)">
<div class="row-item-1">推荐金额()</div>
<div class="row-item-2 border-right">此推荐金额叠加赠送(选填)</div>
<div class="row-item-1 border-right">推荐金额()</div>
<div class="row-item-2">此推荐金额叠加赠送(选填)</div>
</div>
<div class="row-view-push">
<div class="row-view-push--items" style="align-items: center;" v-for="(row,index) in form.referrerAmountList">
<div class="row-item-a">
<el-form-item label-width="0">
<el-input style="width: 100%;" v-model="row.referrerAmount" class="num-input" :placeholder="t('通道推荐金额')"/>
</el-form-item>
</div>
<div class="row-item-b">
<el-form-item label-width="0" :prop="`referrerAmountList.${index}.giveAmount`">
<div style="display: flex;">
<el-select
v-model="row.type"
style="width: 45%;"
clearable>
<el-option
:label="t('按比例')"
:key="1"
:value="1"
/>
<el-option
:label="t('按金额')"
:key="2"
:value="2"
/>
</el-select>
<el-input v-model="row.giveAmount" style="width: 65%;" class="num-input" :placeholder="t('请输入加赠比例')"/>
</div>
</el-form-item>
</div>
</div>
</div>
</div>
<div class="label-tip border-right" style="line-height:42px;padding-left:10px">
{{ t('说明:会员按推荐金额充值才可获对应加赠,加赠金额与充值赠送金额叠加送出。') }}
</div>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeDialog">{{ t(' ') }}</el-button>
<el-button type="primary" @click="submitForm">{{ t(' ') }}</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import NumberInput from "@/components/NumberInput/index.vue"; //
const { proxy } = getCurrentInstance();
const emits = defineEmits(['submit', 'update:data', 'update:show'])
const props = defineProps({
data: {
type: Object,
default: {}
},
show: Boolean,
currencySign: {
type: String,
default: ''
}
})
const form = computed({
get() {
return props.data
},
set(value) {
emits('update:data', value)
}
})
const showDialog = computed({
get() {
return props.show
},
set(value) {
emits('update:show', value)
}
})
const rules = reactive({
referrerAmountList: [
{ required: true, message: proxy.t('请输入推荐金额'), trigger: 'change' },
]
})
const closeDialog = () => {
showDialog.value = false
}
const submitForm = async () => {
closeDialog()
emits('submit')
}
</script>
<style scoped lang="scss">
.tips {
width: 100%;
color: #999999;
}
.num-input {
width:50%;
}
.border-right{
border-bottom: 1px solid #ebeef5;
border-right: 1px solid #ebeef5;
border-left: 1px solid #ebeef5;
box-sizing: border-box;
width: 100%;
}
.label-tip {
color: #979797;
font-size: 12px;
}
.row-view {
display: flex;
text-align: center;
}
.row-item-1 {
flex: 4;
}
.border-right {
border-bottom: 1px solid #ebeef5;
border-right: 1px solid #ebeef5;
box-sizing: border-box;
}
.row-item-2 {
flex: 6;
}
.row-view-push {
border-right: 1px solid #ebeef5;
box-sizing: border-box;
}
.row-view-push .row-view-push--items:nth-child(odd) {
border-left: 1px solid #ebeef5;
}
.row-view-push .row-view-push--items{
border-bottom: 1px solid #ebeef5;
border-left: 1px solid #ebeef5;
box-sizing: border-box;
display: inline-flex;
min-height: 60px;
vertical-align: top;
width: 50%;
}
.row-view-push--items .row-item-a {
border-right: 1px solid #ebeef5;
flex: 2;
margin-right: 10px;
text-align: center;
}
.row-view-push .row-view-push--items .row-item-b{
display: flex;
flex: 3;
justify-content: space-evenly;
text-align: center;
}
</style>

View File

@ -0,0 +1,250 @@
<template>
<el-dialog :title="!isEdit ? t('新增三方渠道') : t('修改三方渠道')" align-center v-model="isShowDialog" width="1300" append-to-body
@close="closeDialog">
<el-scrollbar max-height="700px" >
<el-form ref="formRef" v-if="isShow" :model="formData" :rules="rules" label-width="150">
<el-row :span="24">
<el-col :span="10">
<el-form-item :label="t('通道币种')" prop="currencyCode">
<currency-select style="width: 100%;" v-model="formData.currencyCode" :placeholder="t('请选择通道币种')"></currency-select>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item :label="t('渠道名称')" prop="name">
<el-input v-model="formData.name" :maxlength="50" :placeholder="t('请输入渠道名称,最多50个字')" />
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item :label="t('渠道编码')" prop="code">
<el-input v-model="formData.code" :maxlength="50" :placeholder="t('请输入渠道编码')" />
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item :label="t('联系方式')" prop="contact">
<el-input v-model="formData.contact" :maxlength="50" :placeholder="t('请输入联系方式')" />
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item :label="t('三方费率')" prop="tripartiteRate">
<NumberInput v-model="formData.tripartiteRate" :digit="2" :maxlength="50" :placeholder="t('请输入三方费率')" />
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item :label="t('缴纳保证金')" prop="deposit">
<NumberInput v-model="formData.deposit" :digit="2" :maxlength="50" :placeholder="t('请输入缴纳保证金')" />
</el-form-item>
</el-col>
<el-divider />
<el-col :span="20">
<el-form-item :label="t('下单地址')" prop="payUrl">
<el-input v-model="formData.payUrl" :maxlength="255" show-word-limit
:placeholder="t('请输入下单地址')" />
</el-form-item>
</el-col>
<el-col :span="20">
<el-form-item :label="t('查询地址')" prop="payQueryUrl">
<el-input v-model="formData.payQueryUrl" :maxlength="255" show-word-limit
:placeholder="t('请输入查询地址')" />
</el-form-item>
</el-col>
<el-col :span="20">
<el-form-item :label="t('回调地址')" prop="notifyUrl">
<el-input v-model="formData.notifyUrl" :maxlength="255" show-word-limit
:placeholder="t('请输入回调地址')" />
</el-form-item>
</el-col>
<el-col :span="20">
<el-form-item :label="t('查询余额地址')" prop="balanceUrl">
<el-input v-model="formData.balanceUrl" :maxlength="255" show-word-limit
:placeholder="t('请输入查询余额地址')" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item :label="t('渠道产品')" prop="productList">
<recharge-channel ref="rechargeChannelRef" v-if="isShow" :formData="formData" v-model:data="formData.productList"
:currencySign="currencySign"></recharge-channel> <!-- -->
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item :label="t('渠道配置')" prop="productList">
<field-configList ref="fieldConfigListRef" v-if="isShow" :formData="formData" v-model:data="formData.fieldConfigList"
:currencySign="currencySign"></field-configList> <!-- -->
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-scrollbar>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeDialog">{{ t(' ') }}</el-button>
<el-button type="primary" @click="submitForm" :loading="loadingButton">{{ t('确 定') }}</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import RechargeChannel from './RechargeChannel' //
import FieldConfigList from './FieldConfigList'
import * as recharge from "@/api/finance/recharge"
import { listThirdChannel } from "@/api/payment/thirdChannel";
import useInitDataStore from "@/store/modules/initData";
import CurrencySelect from "@/components/CurrencySelect";
import NumberInput from "@/components/NumberInput";
import { getCurrencyDisplay } from "@/utils/index";
import { getLocalStorage } from "@/utils/auth";
import { nextTick } from 'vue';
const useInitData = useInitDataStore();
const { proxy } = getCurrentInstance();
const emits = defineEmits(['submit'])
const isShowDialog = ref(false);
const loadingButton = ref(false);
const formData = ref({
currencyCode: 'VND',
code: null,
name: null,
type: null,
status:null,
contact: null,
tripartiteRate: null,
deposit: null,
payUrl: null,
ipWhitelist:null,
payQueryUrl: null,
notifyUrl:null,
balanceUrl:null,
productList: [
{
productCode:'',
productCode:'',
productType:'',
limitMin:'',
limitMax:'',
status:0,
}
],
fieldConfigList:[
{
pcId:null,
fieldName:null,
fieldCode:null,
defaultValue:null,
mustFlag:1,
merchantFlag:1,
remark:null,
}
]
})
const rules = reactive({
currencyCode: [
{ required: true, message: proxy.t('请选择通道币种'), trigger: 'change' }
],
name: [
{ required: true, message: proxy.t('请输入渠道名称'), trigger: 'change' }
],
code: [
{ required: true, message: proxy.t('请输入渠道编码'), trigger: 'change' }
],
payUrl: [
{ required: true, message: proxy.t('请输入下单地址'), trigger: 'change' }
],
payQueryUrl: [
{ required: true, message: proxy.t('请输入查询地址'), trigger: 'change' }
],
})
const isEdit = ref(false)
const reset = () => {
nextTick(() => {
proxy.$refs['rechargeChannelRef'].resetChannelProductList()
})
isEdit.value = false
proxy.resetForm("formRef");
}
const closeDialog = () => {
isShowDialog.value = false
}
const isShow = ref(true)
const openDialog = (id = null) => {
isShowDialog.value = true
isShow.value = false
nextTick(() => {
isShow.value = true
reset();
if (id) {
isEdit.value = true
getThirdChannelQuery(id)
}
})
}
// merchName
const getThirdChannelQuery = async (id) => {
await recharge.getChannelExternal(id).then(res => {
formData.value = {
...res.data,
productList:res.data.productList.map((item)=>{
return {
...item,
productType:`${item.productType}`
}
})
}
})
}
const submitForm = async () => {
//
const isChannelValid = await proxy.$refs['rechargeChannelRef'].validateForms();
const isConfigListValid = await proxy.$refs['fieldConfigListRef'].validateForms();
const isFormValid = await proxy.$refs.formRef.validate();
// RechargeChannel
if (isFormValid && isChannelValid && isConfigListValid) {
let _data = '';
_data = {
...formData.value,
}
loadingButton.value = true;
if (isEdit.value) {
recharge.updateChannelExternal(_data).then(res => {
loadingButton.value = false;
proxy.$modal.msgSuccess(proxy.t("修改成功"));
closeDialog()
emits('submit')
}).catch(() => {
loadingButton.value = false;
})
} else {
recharge.addChannelExternal(_data).then(res => {
loadingButton.value = false;
proxy.$modal.msgSuccess(proxy.t("新增成功"));
closeDialog()
emits('submit')
}).catch(() => {
loadingButton.value = false;
})
}
} else {
// RechargeChannel
console.log('RechargeChannel 组件中的表单校验未通过');
}
}
const currencySign = ref(null)
onMounted(() => {
})
defineExpose({ openDialog })
</script>
<style scoped lang="scss">
.input-group {
width: 100%;
display: flex;
align-items: center;
gap: 10px;
}
</style>

View File

@ -0,0 +1,284 @@
<template>
<table-search-card :model="queryParams" @getList="getList" @handleQuery="handleQuery" @resetQuery="handleQuery"
:leftSpan="22" :rightSpan="2">
<template #left>
<!-- <el-form-item prop="queryType">
<el-select style="width: 200px;" v-model="queryParams.queryType">
<el-option v-for="item in queryTypeOptions" :key="item.value" :label="item.label"
:value="item.value"> </el-option>
</el-select>
</el-form-item>
<el-form-item prop="queryValue">
<el-input v-model="queryParams.queryValue"
:placeholder="`${t('请输入')}${queryTypeOptions[queryParams.queryType - 1].label}`"></el-input>
</el-form-item> -->
<el-form-item prop="name">
<el-input v-model="queryParams.name"
:placeholder="`${t('请输入渠道名称')}`"></el-input>
</el-form-item>
<el-form-item prop="status">
<CustomSelect v-model="queryParams.status" style="width: 200px;" :options="switchStatusOptions" :placeholder="t('状态')" :empty-values="[null, undefined]"
:value-on-clear="null" clearable></CustomSelect>
</el-form-item>
<el-form-item prop="currencyCode">
<CustomSelect v-if="currencyTypeOptions.length > 0" v-model="queryParams.currencyCode" style="width: 200px;" :placeholder="t('币种')"
:options="currencyTypeOptions"></CustomSelect>
</el-form-item>
<!-- <el-form-item prop="levelIdList">
<checkbox-select v-model="queryParams.levelIdList" style="width: 200px;" collapse-tags :placeholder="t('会员层级')"
:options="levelOptions"></checkbox-select>
</el-form-item> -->
</template>
<template #right>
<el-button v-hasPermi="['payment:thirdChannel:add']" type="primary" icon="Plus" @click="handleAdd"
payment:channel:add>{{ t('新增第三方')
}}</el-button>
</template>
</table-search-card>
<el-table v-loading="loading" :data="listData" class="c-table-main" stripe border >
<el-table-column :label="t('渠道名称')" align="center" prop="name" min-width="150" fixed="left" >
<template v-slot="{row}">
<span v-if="row.name">{{ row.name }}</span>
</template>
</el-table-column>
<el-table-column :label="t('联系方式')" align="center" prop="contact" min-width="130" >
<template v-slot="{row}">
<span >{{ row.contact||'--' }}</span>
</template>
</el-table-column>
<el-table-column :label="t('三方费率')" align="center" prop="tripartiteRate" min-width="130">
<template v-slot="{row}">
<span >{{ row.tripartiteRate ==null ? '--' : row.tripartiteRate}}</span>
</template>
</el-table-column>
<el-table-column :label="t('类型')" align="center" prop="type" width="130" >
<template v-slot="{row}">
<span v-if="row.type == 0">{{ t('') }}</span>
<span v-if="row.type == 1">{{ t('') }}</span>
</template>
</el-table-column>
<el-table-column :label="t('缴纳保证金')" align="center" prop="deposit" min-width="130" >
<template v-slot="{row}">
<span >{{ row.deposit == null ? '--' : row.deposit }}</span>
</template>
</el-table-column>
<el-table-column :label="t('渠道编码')" align="center" prop="code" min-width="130" >
<template v-slot="{row}">
<span >{{ row.code }}</span>
</template>
</el-table-column>
<el-table-column :label="t('币种编号')" align="center" prop="currencyCode" min-width="130">
<template v-slot="{row}">
<span >{{ row.currencyCode }}</span>
</template>
</el-table-column>
<el-table-column :label="t('下单地址')" align="center" prop="payUrl" min-width="200" >
<template v-slot="{row}">
<span >{{ row.payUrl|| '--' }}</span>
</template>
</el-table-column>
<el-table-column :label="t('查询地址')" align="center" prop="payQueryUrl" min-width="200" >
<template v-slot="{row}">
<span >{{ row.payQueryUrl || '--' }}</span>
</template>
</el-table-column>
<el-table-column :label="t('回调地址')" align="center" prop="notifyUrl" min-width="200" >
<template v-slot="{row}">
<span >{{ row.notifyUrl || '--' }}</span>
</template>
</el-table-column>
<el-table-column :label="t('查询余额地址')" align="center" prop="balanceUrl" min-width="200" >
<template v-slot="{row}">
<span >{{ row.balanceUrl || '--' }}</span>
</template>
</el-table-column>
<el-table-column :label="t('操作')" align="center" prop="operate"
width="170" fixed="right">
<template #default="{ row }">
<el-button link type="primary" @click="handleAdd(row)" >
{{ t('修改') }}</el-button>
</template>
</el-table-column>
</el-table>
<third-channel-add v-if="showLodings" ref="thirdChannelAddRef" @submit="handleQuery"></third-channel-add> <!-- 添加第三方渠道 -->
<edit-remark v-if="editRemarkDialog" v-model:show="editRemarkDialog" v-model:data="addQuery" @submit="handleQuery"></edit-remark> <!-- 编辑备注 -->
<recharge-config v-if="configDialog" v-model:show="configDialog" v-model:data="addQuery" @submit="handleConfigSubmit"
:currencySign="currencySign"></recharge-config> <!-- -->
<edit-level v-if="levelDialog" v-model:show="levelDialog" v-model:data="addQuery" @submit="handleQuery"></edit-level> <!-- 充值等级 -->
</template>
<script setup>
import CheckboxSelect from "@/components/CheckboxSelect"; //
import baseSwitch from "@/components/BaseSwitch"; //
import ThirdChannelAdd from "./components/ThirdChannelAdd" //
import EditRemark from "./components/EditRemark.vue"; //
import EditLevel from "./components/EditLevel.vue"; //
import RechargeConfig from "./components/RechargeConfig.vue";//
import CustomSelect from "@/components/CustomSelect"; //
import TableDragSort from '@/components/TableDragSort'; //
import TextDragSort from "@/components/TextDragSort"; //
import * as recharge from '@/api/finance/recharge';
import { getChannelExternalList } from '@/api/finance/recharge'
import { listLevel } from '@/api/member/level'
import { getCurrencyDisplay } from "@/utils/index";
import { nextTick } from "vue";
const { proxy } = getCurrentInstance()
const { ff_device_type } = proxy.useDict('ff_device_type')
const data = reactive({
loading: false,
queryParams: {
queryType: '',
parentId: '',
terminalsList: [],
currencyCode: '',
levelIdList: [],
switchStatus: ''
},
listData: [],
})
const props = defineProps({
typeName: String,
typeOS: String,
})
const switchStatusOptions = [
{ value: '', label: proxy.t('全部状态') },
{ label: proxy.t('停用'), value: '0' },
{ label: proxy.t('启用'), value: '1' },
]
const { loading, queryParams, listData } = toRefs(data)
const queryTypeOptions = [
{
value: 1,
label: '商户名称'
},
{
value: 2,
label: '第三方支付名称'
},
{
value: 3,
label: '商户号'
},
{
value: 4,
label: '通道编码'
},
{
value: 5,
label: '通道名称'
}
]
//
data.queryParams.queryType = Number(props.typeOS)
data.queryParams.queryValue = props.typeName
const showLodings = ref(true) //
/**
* 打开新增修改第三方弹窗
* @param row
*/
const handleAdd = (row) => {
showLodings.value = false;
nextTick(() => {
showLodings.value = true;
setTimeout(() => {
proxy.$refs['thirdChannelAddRef'].openDialog(row.id)
}, 300);
})
}
/** 搜索按钮操作 */
const handleQuery = () => {
getList();
}
//
const getList = () => {
loading.value = true;
const { parentId, terminalsList, currencyCode, levelIdList, ...other } = queryParams.value
const _data = {
...other,
terminalsList: terminalsList.join(','),
currencyCode: currencyCode,
levelIdList: levelIdList.join(','),
parentId: parentId
}
getChannelExternalList(_data).then(response => {
listData.value = response.rows.map(item => {
return item
})
loading.value = false;
});
}
/**
* 所有下拉框的数据
*/
//
const channelOptions = ref([]);
const lodingShow = ref(true);
const getListChannel = async () => {
lodingShow.value = false;
const { data } = await recharge.listChannel({ parentId: 0 })
channelOptions.value = data.map(item => {
return {
label: item.channelName,
value: item.id
}
})
nextTick(() => {
lodingShow.value = true;
})
}
//
const currencyTypeOptions = ref([]);
const getListCurrencyType = () => {
const list = JSON.parse(localStorage.getItem('currencyList'))
currencyTypeOptions.value = list.map(item => {
return {
label: item.currencyCode,
value: item.currencyCode
}
})
}
//
const editRemarkDialog = ref(false)
const addQuery = ref({})
//
const configDialog = ref(false)
const currencySign = ref(null)
//
const handleConfigSubmit = () => {
let { deduceRateType } = addQuery.value
if (deduceRateType === 1) {
addQuery.value.chargeRateList = []
addQuery.value.chargeRateLevelList.map(item => {
item.chargeRateList = item.chargeRateList.filter(rateItem => rateItem.maxAmount && rateItem.minAmount >= 0 && rateItem.chargeRate)
})
} else if (deduceRateType === 0) {
addQuery.value.chargeRateList = addQuery.value.chargeRateList.filter(rateItem => rateItem.maxAmount && rateItem.minAmount >= 0 && rateItem.chargeRate)
}
recharge.chargeRateConfig(addQuery.value).then(res => {
proxy.$modal.msgSuccess(proxy.t("修改成功"))
getList()
})
}
//
const levelDialog = ref(false)
const initOptions = () => {
getListCurrencyType()
getListChannel()
// getListLabel()
}
onMounted(() => {
initOptions()
getList()
})
</script>
<style lang="scss" scoped></style>

View File

@ -1,11 +1,14 @@
<template>
<div class="app-container">
<el-tabs v-model="activeName">
<el-tab-pane name="ThirdPartyPayment" :label="t('共用三方支付')"></el-tab-pane>
<el-tab-pane name="ThirdOthersPayment" :label="t('共用三方代付')"></el-tab-pane>
<el-tab-pane name="AddThirdPartyList" :label="t('共用三方支付')"></el-tab-pane>
<!-- <el-tab-pane name="ThirdPartyPayment" :label="t('共用三方支付')"></el-tab-pane> -->
<!-- <el-tab-pane name="ThirdOthersPayment" :label="t('共用三方代付')"></el-tab-pane> -->
</el-tabs>
<!-- 列表组件 -->
<div class="tabs-main-box">
<add-third-party-list :typeOS="typeOS" :typeName="typeName" v-if="activeName == 'AddThirdPartyList'"></add-third-party-list>
<third-payment v-if="activeName == 'ThirdOthersPayment'"></third-payment>
<third-channel-list :typeOS="typeOS" :typeName="typeName" v-if="activeName === 'ThirdPartyPayment'"></third-channel-list>
</div>
@ -13,13 +16,14 @@
</template>
<!-- 稽核管理 -->
<script setup name="User">
<script setup name="PaymentRanking">
import BillingRecords from "./billingRecords/list.vue";
import AccountChanges from "./accountChanges/list.vue";
import DepositOrder from "./depositOrder/list.vue";
import ThirdChannelList from "./thirdChannelList/list"
import AddThirdPartyList from "./addThirdPartyList/list"
import ThirdPayment from "./thirdPayment"
const activeName = ref('ThirdPartyPayment'); //
const activeName = ref('AddThirdPartyList'); //
const memberAccount = ref(''); //
const typeOS = ref('1');
const typeName = ref('');
@ -28,7 +32,7 @@ onActivated(() => {
const routeParams = useRoute().query;
//
if (Object.keys(routeParams).length) {
activeName.value = routeParams.activeName || 'ThirdPartyPayment';
activeName.value = routeParams.activeName || 'AddThirdPartyList';
memberAccount.value = routeParams.memberAccount || '';
}

View File

@ -98,14 +98,14 @@
</div>
</template>
<el-row :span="24">
<el-col :span="12" class="mt20 mb20">
<!-- <el-col :span="12" class="mt20 mb20">
<el-form-item prop="levelIds" :label="t('会员层级')">
<checkbox-select v-model="item.levelIds" :placeholder="t('请选择会员层级')"
:options="levelList" collapse-tags
@change="levelIdsChange(item)"></checkbox-select>
</el-form-item>
</el-col>
<el-col :span="12" class="mt20 mb20">
</el-col> -->
<el-col :span="24" class="mt20 mb20">
<el-form-item prop="terminals" :label="t('终端')">
<checkbox-select v-model="item.terminals" :placeholder="t('请选择终端')"
dictKey="ff_device_type" collapse-tags></checkbox-select>
@ -508,15 +508,15 @@ const openDialog = (dialog = null, row) => {
}
/** 查询会员层级列表 */
const levelList = ref([])
const getLevelList = async () => {
await listLevel({ pageNum: 1, pageSize: 1000 }).then(response => {
levelList.value = response.rows.map(itme => {
return { label: itme.levelName, value: itme.id }
});
});
}
getLevelList()
// const levelList = ref([])
// const getLevelList = async () => {
// await listLevel({ pageNum: 1, pageSize: 1000 }).then(response => {
// levelList.value = response.rows.map(itme => {
// return { label: itme.levelName, value: itme.id }
// });
// });
// }
// getLevelList()
//
const levelIdsChange = (row) => {
row.chargeRateLevelList = row.levelIds.map(item => {

View File

@ -1,5 +1,5 @@
<template>
<el-dialog :title="!isEdit ? t('新增三方充值') : t('修改三方充值')" v-model="isShowDialog" width="1300" append-to-body
<el-dialog :title="!isEdit ? t('新增三方充值') : t('修改三方充值')" align-center v-model="isShowDialog" width="1300" append-to-body
@close="closeDialog">
<el-form ref="formRef" v-if="isShow" :model="formData" :rules="rules" label-width="150">
<el-row :span="24">
@ -84,6 +84,7 @@ import RechargeChannel from './RechargeChannel' // 充值通道
import * as recharge from "@/api/finance/recharge"
import { listThirdChannel } from "@/api/payment/thirdChannel";
import useInitDataStore from "@/store/modules/initData";
import CurrencySelect from "@/components/CurrencySelect";
import { getCurrencyDisplay } from "@/utils/index";
import { getLocalStorage } from "@/utils/auth";
import { nextTick } from 'vue';
@ -95,7 +96,7 @@ const emits = defineEmits(['submit'])
const isShowDialog = ref(false);
const loadingButton = ref(false);
const formData = ref({
currencyType: useInitData.currencyCode,
currencyType: 'VND',
merchCode: null,
merchName: null,
merchNameOld: null,
@ -465,6 +466,7 @@ const currencyTypeChange = () => {
const currencySign = ref(null)
watch( () => formData.value.currencyType, async(val) => {
getListThirdChannel(val)
console.log('currencySign', val)
currencySign.value = getCurrencyDisplay(val, 'currencySign')
}, { immediate: true })

View File

@ -3,7 +3,7 @@
:leftSpan="22" :rightSpan="2">
<template #left>
<el-form-item prop="queryType">
<el-select v-model="queryParams.queryType">
<el-select style="width: 200px;" v-model="queryParams.queryType">
<el-option v-for="item in queryTypeOptions" :key="item.value" :label="item.label"
:value="item.value"> </el-option>
</el-select>
@ -13,29 +13,31 @@
:placeholder="`${t('请输入')}${queryTypeOptions[queryParams.queryType - 1].label}`"></el-input>
</el-form-item>
<el-form-item prop="parentId">
<custom-select v-if="lodingShow" v-model="queryParams.parentId" :placeholder="t('通道所属大类')"
<custom-select v-if="lodingShow" style="width: 200px;" v-model="queryParams.parentId" :placeholder="t('通道所属大类')"
:options="channelOptions"></custom-select>
</el-form-item>
<el-form-item prop="switchStatus">
<dict-select dictKey="ff_common_status" v-model="queryParams.switchStatus" :placeholder="t('通道状态')"
<!-- <dict-select dictKey="ff_common_status" style="width: 200px;" v-model="queryParams.switchStatus" :placeholder="t('通道状态')"
:addOptions="{ value: '', label: t('全部状态') }" :empty-values="[null, undefined]"
:value-on-clear="null" clearable></dict-select>
:value-on-clear="null" clearable></dict-select> -->
<CustomSelect v-model="queryParams.switchStatus" style="width: 200px;" :options="switchStatusOptions" :placeholder="t('通道状态')" :empty-values="[null, undefined]"
:value-on-clear="null" clearable>></CustomSelect>
</el-form-item>
<el-form-item prop="terminalsList">
<checkbox-select v-model="queryParams.terminalsList" collapse-tags :placeholder="t('支持终端')"
<checkbox-select v-model="queryParams.terminalsList" style="width: 200px;" collapse-tags :placeholder="t('支持终端')"
:options="ff_device_type"></checkbox-select>
</el-form-item>
<el-form-item prop="currencyTypeList">
<checkbox-select v-model="queryParams.currencyTypeList" collapse-tags :placeholder="t('通道币种')"
<checkbox-select v-model="queryParams.currencyTypeList" style="width: 200px;" collapse-tags :placeholder="t('通道币种')"
:options="currencyTypeOptions"></checkbox-select>
</el-form-item>
<el-form-item prop="levelIdList">
<checkbox-select v-model="queryParams.levelIdList" collapse-tags :placeholder="t('会员层级')"
<!-- <el-form-item prop="levelIdList">
<checkbox-select v-model="queryParams.levelIdList" style="width: 200px;" collapse-tags :placeholder="t('会员层级')"
:options="levelOptions"></checkbox-select>
</el-form-item>
</el-form-item> -->
</template>
<template #right>
<el-button v-hasPermi="['payment:thirdChannel:add']" type="primary" icon="Plus" @click="handleAdd"
<el-button v-hasPermi="['payment:thirdChannel:add']" type="primary" icon="Plus" @click="handleAdd"
payment:channel:add>{{ t('新增第三方')
}}</el-button>
</template>
@ -187,6 +189,12 @@ const props = defineProps({
typeName: String,
typeOS: String,
})
const switchStatusOptions = [
{ value: '', label: proxy.t('全部状态') },
{ label: proxy.t('停用'), value: '0' },
{ label: proxy.t('启用'), value: '1' },
]
const { loading, queryParams, listData } = toRefs(data)
const queryTypeOptions = [
@ -367,15 +375,15 @@ const getListCurrencyType = () => {
}
//
const levelOptions = ref([])
const getListLabel = async () => {
const { rows } = await listLevel()
levelOptions.value = rows.map(item => {
return {
label: item.levelName,
value: item.id
}
})
}
// const getListLabel = async () => {
// const { rows } = await listLevel()
// levelOptions.value = rows.map(item => {
// return {
// label: item.levelName,
// value: item.id
// }
// })
// }
//
const editRemarkDialog = ref(false)
@ -392,7 +400,7 @@ const currencySign = ref(null)
const handleConfig = (row) => {
let { id, deduceRateType, deduceLimit, deduceCountType, deduceCount, chargeRateList, chargeRateLevelList, currencyType, levelIds, levelNames } = row
deduceCountType = deduceCountType ?? 0
currencySign.value = getCurrencyDisplay(currencyType, 'currencySign')
currencySign.value = getCurrencyDisplay(currencyType, 'currencySign');
//
if (!chargeRateList || chargeRateList.length === 0) {
chargeRateList = [
@ -470,7 +478,7 @@ const handleLevel = (row) => {
const initOptions = () => {
getListCurrencyType()
getListChannel()
getListLabel()
// getListLabel()
}
onMounted(() => {
initOptions()

View File

@ -2,9 +2,9 @@
<div class="app-container home" style="padding: 0px;">
<div class="main_box">
<div style="margin-bottom: 15px;">
<custom-select v-model="currencyType" :options="currencySelectArr" style="width: 220px;"
<custom-select v-model="currencyType" filterable :options="currencySelectArr" style="width: 220px;"
@change="getHomeIndexs"></custom-select>
<custom-select style="width: 130px;" v-if="siteSelect.length > 0" @change="getHomeIndexs" collapse-tags collapse-tags-tooltip v-model="tenantId" clearable :options="siteSelect" :placeholder="t('请选择')"></custom-select>
<custom-select style="width: 130px;" filterable v-if="siteSelect.length > 0" @change="getHomeIndexs" collapse-tags collapse-tags-tooltip v-model="tenantId" clearable :options="siteSelect" :placeholder="t('请选择')"></custom-select>
</div>
<el-row>
<el-col :span="24" style="background:rgb(255,255,255);padding:16px 16px 0px;margin-bottom:32px">
@ -53,7 +53,7 @@ const getSiteSelects = () => {
getSiteSelect().then(response => {
siteSelect.value = [
{
label: '全部',
label: '全部站点',
value: '0', // ID 'all'
},
...response.data.map((item, index) => {

View File

@ -70,7 +70,7 @@
<el-dialog v-model="goodDialogVisible" align-center :title="t('温馨提示')" width="418" :before-close="handleClose">
<div style="width: 90%;margin-bottom: 20px;">{{ t('请用手机打开客服端Google身份验证器,输入验证码') }}</div>
<div class="">
<number-input v-model="gooleCode" style="width: 90%" :maxlength="6" :placeholder="t('验证码只能为数字')" ></number-input>
<CodeInput v-model="gooleCode" style="width: 90%" :maxlength="6" :placeholder="t('验证码只能为数字')" ></CodeInput>
</div>
<template #footer>
<div class="dialog-footer">
@ -90,7 +90,7 @@
</div>
<el-form ref="authenticatorRef" :model="authenticatorForm" :rules="authenticatorRules">
<el-form-item label="谷歌验证码" prop="authenticatorCode">
<number-input v-model="authenticatorForm.authenticatorCode" :maxlength="6" style="width: 100%;height: 36px;" :placeholder="t('验证码只能为数字')" ></number-input>
<CodeInput v-model="authenticatorForm.authenticatorCode" :maxlength="6" style="width: 100%;height: 36px;" :placeholder="t('验证码只能为数字')" ></CodeInput>
</el-form-item>
</el-form>
<div class="" style="margin-top: 20px;margin-bottom: 20px;">
@ -118,7 +118,7 @@ import { getCodeImg,googleBinding,getTwoStepVerificationQRCode,bindingTwoFactorV
import Cookies from "js-cookie";
import { encrypt, decrypt } from "@/utils/jsencrypt";
import useUserStore from '@/store/modules/user'
import NumberInput from "@/components/NumberInput";
import CodeInput from "@/components/CodeInput";
import { i18nScope } from "@/languages"
import { setToken } from '@/utils/auth'
import Vcode from "vue3-puzzle-vcode";

View File

@ -159,14 +159,26 @@
>{{ form.operName }} / {{ form.operIp }} / {{ form.operLocation }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="请求地址:">{{ form.operUrl }}</el-form-item>
<el-form-item label="请求地址:">
<div style="width: 100%;">
{{ form.operUrl }}
</div>
</el-form-item>
<el-form-item label="请求方式:">{{ form.requestMethod }}</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="操作方法:">{{ form.method }}</el-form-item>
<el-form-item label="操作方法:">
<div style="width: 100%;">
{{ form.method }}
</div>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="请求参数:">{{ form.operParam }}</el-form-item>
<el-form-item label="请求参数:">
<div style="width: 100%;">
{{ form.operParam }}
</div>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="返回参数:" >

View File

@ -16,7 +16,7 @@
@handleQuery="handleQuery">
</select-input-form>
<el-form-item prop="currencyType">
<custom-select style="width: 130px;" collapse-tags collapse-tags-tooltip v-model="queryParams.currencyType" :options="currencySelectArr" :placeholder="t('币种')"></custom-select>
<custom-select style="width: 130px;" collapse-tags collapse-tags-tooltip v-model="queryParams.currencyType" filterable :options="currencySelectArr" :placeholder="t('币种')"></custom-select>
</el-form-item>
</template>
<template #right>

View File

@ -17,7 +17,7 @@
@handleQuery="handleQuery">
</select-input-form>
<el-form-item prop="currencyType">
<custom-select style="width: 130px;" collapse-tags collapse-tags-tooltip v-model="queryParams.currencyType" :options="currencySelectArr" :placeholder="t('币种')"></custom-select>
<custom-select style="width: 130px;" collapse-tags collapse-tags-tooltip filterable v-model="queryParams.currencyType" :options="currencySelectArr" :placeholder="t('币种')"></custom-select>
</el-form-item>
<select-input-form ref="selectInputFormRef" :queryParamsList="queryParamsList2" keyName="accountType" :queryParams="queryParams"
@handleQuery="handleQuery">

View File

@ -21,7 +21,7 @@
<el-button @click="changeStatus(item, 1)" v-if="item.stopStatus === 0 && item.systemType"
type="success">{{
t('启用') }}</el-button>
<el-button v-if="!item.systemType" type="info" @click="deleteAvatar(item)">{{ t('') }}</el-button>
<el-button type="info" @click="deleteAvatar(item)">{{ t('') }}</el-button>
</div>
</li>
<li style="border: #dddddd dashed 1px;">

View File

@ -3,7 +3,7 @@
<table-search-card :model="queryParams" @getList="getList" align-center @handleQuery="handleQuery" @resetQuery="handleQuery">
<template #left>
<el-form-item :label="t('币种类型')" prop="currencyType">
<dict-select dictKey="ff_currency" v-model="queryParams.currencyType" :placeholder="t('请选择币种类型')"
<dict-select dictKey="ff_currency" filterable style="width: 200px;" v-model="queryParams.currencyType" :placeholder="t('请选择币种类型')"
clearable></dict-select>
</el-form-item>
<el-form-item :label="t('币种名称')" prop="currencyName">
@ -135,7 +135,7 @@ import * as currency from "@/api/currency";
import { getLocalStorage, setLocalStorage } from "@/utils/auth";
import TableDragSort from '@/components/TableDragSort'; //
import ImageUpload from "@/components/ImageUpload";
import DictSelect from "@/components/DictSelect";
const { proxy } = getCurrentInstance();
const { ff_currency } = proxy.useDict('ff_currency');
@ -157,6 +157,8 @@ const data = reactive({
queryParams: {
pageNum: 1,
pageSize: 20,
orderByColumn:'sortNo',
isAsc:'asc',
currencyType: null,
currencyName: null
},

View File

@ -60,7 +60,7 @@
<!-- 子域名展示 -->
<el-popover placement="right" :width="524" trigger="click">
<template #reference>
<span class="c-blue"> ({{ row.operationDomainSons?.length }})</span>
<span > (<span class="c-blue" style="border-bottom: 1px solid #409EFF;">{{ row.operationDomainSons?.length }}</span>)</span>
</template>
<el-table :data="row.operationDomainSons">
<el-table-column width="200" align="center" property="name" :label="t('子域名')" />
@ -87,7 +87,7 @@
<p class="c-clear" v-if="row.domainStatus == 2">
<!-- 当前DNS为 -->
<span class="c-green">{{ t('验证已生效') }}</span>
<el-button link type="primary" @click="row.isShowDns = !row.isShowDns">{{ row.isShowDns ? t('收起') :
<el-button link type="primary" v-if="row.dnsList.length != 0" @click="row.isShowDns = !row.isShowDns">{{ row.isShowDns ? t('') :
t('展开')
}}</el-button>
</p>

View File

@ -34,6 +34,7 @@
import { formatTime,finalTimestamp } from '@/utils/ruoyi'; //
import ImageUpload from "@/components/ImageUpload";
import { updateGame } from "@/api/game/game";
import {postGameSecret,updateGameSecret} from "@/api/game/configuration";
import { nextTick, onMounted, ref } from "vue"; //
import { getLocalStorage } from "@/utils/auth";
@ -120,24 +121,41 @@ const submitForm = () => {
//
formRef.value.validate(valid => {
if (valid) {
loadingButton.value = true;
//
let formData = {
...formAll
};
if (JSON.stringify(formAll) != oldForm.value) {
updateGame(formData).then(res => {
loadingButton.value = false;
proxy.$modal.msgSuccess(proxy.t('修改成功!'));
emits('submit');
closeDialog();
}).catch(() => {
loadingButton.value = false;
});
}else{
loadingButton.value = false;
closeDialog();
}
if (props.addEditStatus == 'add'){
loadingButton.value = true;
//
let formData = {
...formAll
};
postGameSecret(formData).then(res => {
loadingButton.value = false;
proxy.$modal.msgSuccess(proxy.t('修改成功!'));
emits('submit');
closeDialog();
}).catch(() => {
loadingButton.value = false;
});
}else{
loadingButton.value = true;
//
let formData = {
...formAll
};
if (JSON.stringify(formAll) != oldForm.value) {
updateGameSecret(formData).then(res => {
loadingButton.value = false;
proxy.$modal.msgSuccess(proxy.t('修改成功!'));
emits('submit');
closeDialog();
}).catch(() => {
loadingButton.value = false;
});
}else{
loadingButton.value = false;
closeDialog();
}
}
}
});
};

View File

@ -0,0 +1,349 @@
<template>
<!-- 详情 -->
<el-dialog :title="t('超管Api配置')" :close-on-click-modal="false" align-center v-model="showDialog" width="900px" append-to-body>
<el-scrollbar height="600px" >
<div style="display: flex;justify-content: space-between;margin-bottom: 10px;">
<div></div>
<div>
<el-button type="primary" @click="handleAdd">{{t('')}}</el-button>
</div>
</div>
<el-table class="c-table-main" style="height: 460px;" :data="tenantList" border>
<el-table-column :label="t('租户KEY')" align="center" min-width="120" prop="tenantKey">
<template #default="{ row }">
{{ row.tenantKey }}
</template>
</el-table-column>
<el-table-column :label="t('租户密钥')" align="center" min-width="120" prop="secretKey">
<template #default="{ row }">
{{ row.secretKey}}
</template>
</el-table-column>
<el-table-column :label="t('币种')" align="center" min-width="120" prop="currencyCode">
<template #default="{ row }">
{{ row.currencyCode}}
</template>
</el-table-column>
<el-table-column :label="t('状态')" align="center" min-width="120" prop="quota">
<template #default="{ row }">
<el-switch v-model="row.status" :active-value="1" :inactive-value="0"
:active-text="t('启用')"
:inactive-text="t('停用')"
:before-change="switchBeforeChange"
@click="handleDisable(row, 'status')"
inline-prompt/>
<!-- <el-button v-if="row.status == 1" @click="handleEnable(row)" type="primary">{{t('')}}</el-button>
<el-button v-if="row.status == 0" @click="handleDisable(row)" type="primary">{{t('')}}</el-button> -->
</template>
</el-table-column>
<el-table-column :label="t('操作时间')" align="center" min-width="120" prop="currencyCode">
<template #default="{ row }">
{{ row.updateTime ? formatTime(row.updateTime): formatTime(row.createTime) }}
</template>
</el-table-column>
<el-table-column :label="t('操作')" align="center" min-width="120" prop="quota">
<template #default="{ row }">
<el-button @click="handleEdit(row)" type="primary">{{t('修改')}}</el-button>
<!-- <el-button @click="handleDelect(row)" type="primary">{{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="getSiteBindApiGameInfos" />
</el-scrollbar>
<template #footer style="margin-top: 20px;">
<div class="dialog-footer" style="display: flex;justify-content: center;">
<!-- <el-button type="primary" @click="submitForm" :loading="loadingButton">{{ t('确 定') }}</el-button> -->
<el-button @click="closeDialog">{{ t(' ') }}</el-button>
</div>
</template>
<el-dialog v-if="showDialogTenant" :title="addStatus == 'add'?t('新增租户'):t('修改租户')" align-center v-model="showDialogTenant" width="700px" append-to-body>
<el-form ref="formRef" :model="formAll" :rules="rules" label-width="150px" class="site-form">
<el-form-item label="租户KEY" prop="tenantKey">
<el-input v-model="formAll.tenantKey" placeholder="请输入租户KEY" />
</el-form-item>
<el-form-item label="租户密钥" prop="secretKey">
<el-input v-model="formAll.secretKey" placeholder="请输入密钥" />
</el-form-item>
<el-form-item label="币种" prop="currencyCode">
<custom-select v-model="formAll.currencyCode" :options="currencySelectArr" style="width: 100%;"></custom-select>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer" style="display: flex;justify-content: center;">
<el-button type="primary" @click="submitForm" :loading="loadingButton">{{ t('确 定') }}</el-button>
<el-button @click="closeDialog1">{{ t(' ') }}</el-button>
</div>
</template>
</el-dialog>
</el-dialog>
</template>
<script setup>
import { formatTime,finalTimestamp } from '@/utils/ruoyi'; //
// import SkinSelector from "@/components/SkinSelector";
import CustomSelect from "@/components/CustomSelect"; //
import { nextTick, onMounted, ref } from "vue"; //
import { getLocalStorage } from "@/utils/auth";
import { postSiteBindApiGame,getSiteBindApiGameInfo,postSiteUpdateApiGame,postSiteDeleteApiGame,postSiteOpenApiGameInfo,postSiteStopApiGameInfo } from "@/api/siteManagement";
import {getGameSuperSecretList,getGameSuperSecretInfo,postGameSuperSecret,updateGameSuperSecret} from "@/api/game/configuration";
import { id } from 'element-plus/es/locales.mjs';
const currencySelectArr = getLocalStorage('currencySelect')?.map(item => {
return {
label: `${item.currencyName}(${item.currencyCode})`,
value: item.currencyCode
};
});
const { proxy } = getCurrentInstance() //
const emits = defineEmits(['submit', 'update:show']) //
const props = defineProps({ //
data: {
type: Object, //
default: {}
},
show: {
type: Boolean, //
default: false
},
addEditStatus:{ // /
type: String,
default: 'add'
},
modifyDate: { //
type: Object,
default: {}
}
})
const showDialog = computed({ //
get() {
return props.show
},
set(value) {
emits('update:show', value)
}
})
const formAll = reactive({
})
const oldForm = shallowRef({ });
const showDialogTenant = ref(false);
const queryParams = ref({
pageNum: 1,
pageSize: 20,
currencyCode:'',
orderByColumn:'createTime',
isAsc:'desc',
})
const rules = reactive({
tenantKey: [
{ required: true, message: proxy.t('请输入租户id'), trigger: 'change' }
],
secretKey: [
{ required: true, message: proxy.t('请输入密钥'), trigger: 'change' }
],
ShowStartTime: [
{ required: true, message: proxy.t('请选择时间'), trigger: 'change' }
]
})
const tenantList = ref([]);
const total = ref(0);
const switchBeforeChange = () => {
return false
}
const getSiteBindApiGameInfos = () => {
getGameSuperSecretList(queryParams.value).then(res => {
tenantList.value = res.rows;
total.value = res.total;
})
}
//
nextTick(() => {
// Object.assign(formAll, props.modifyDate);
formAll.siteId = props.modifyDate.id;
getSiteBindApiGameInfos();
});
const addStatus = ref('add')
//
const handleAdd = () => {
addStatus.value = 'add';
showDialogTenant.value = true;
formAll.siteId = props.modifyDate.id;
formAll.tenantKey = '';
formAll.secretKey = '';
formAll.currencyCode = '';
}
const handleEdit = (row) => {
addStatus.value = 'edit';
showDialogTenant.value = true;
Object.assign(formAll, row);
setTimeout(() => {
oldForm.value = JSON.stringify(formAll);
}, 500);
}
const handleDelect = (row) => {
proxy.$modal.confirm(proxy.t('确认是否删除?')).then(() => {
postSiteDeleteApiGame({siteId:formAll.siteId,id:row.id}).then(() => {
proxy.$modal.msgSuccess(proxy.t('删除成功'));
getSiteBindApiGameInfos();
})
}).catch(() => {})
}
//
const handleDisable = (row,type) => {
proxy.$modal.confirm(proxy.t('确认是否停用?')).then(() => {
updateGameSuperSecret({id:row.id,status:row.status == 1 ? 0 : 1}).then(() => {
proxy.$modal.msgSuccess(proxy.t(`${row.status == 1 ? '停用' : '启用'}成功`));
getSiteBindApiGameInfos();
})
}).catch(() => {})
}
//
const closeDialog = () => {
showDialog.value = false
}
const closeDialog1 = () => {
showDialogTenant.value = false
}
const formRef = ref(null);
const loadingButton = ref(false);
//
const submitForm = () => {
//
formRef.value.validate(valid => {
if (valid) {
loadingButton.value = true;
//
if (addStatus.value == 'add'){
let formData = {
tenantKey:formAll.tenantKey,
secretKey:formAll.secretKey,
currencyCode:formAll.currencyCode
};
postGameSuperSecret(formData).then(res => {
loadingButton.value = false;
proxy.$modal.msgSuccess(proxy.t('新增成功!'));
getSiteBindApiGameInfos();
closeDialog1();
}).catch(error => {
loadingButton.value = false;
});
}else{
let formData = {
id: formAll.id,
tenantKey:formAll.tenantKey,
secretKey:formAll.secretKey,
currencyCode:formAll.currencyCode
};
if (JSON.stringify(formAll) != oldForm.value) {
updateGameSuperSecret(formData).then(res => {
loadingButton.value = false;
proxy.$modal.msgSuccess(proxy.t('修改成功!'));
getSiteBindApiGameInfos();
closeDialog1();
}).catch(error => {
loadingButton.value = false;
});
}else{
loadingButton.value = false;
closeDialog1();
}
}
}
});
};
</script>
<style scope lang="scss">
.w100 {
width: 100%;
}
.upload-box-vioce{
height: 90px !important;
overflow: hidden;
.upload-tips {
color: #999;
font-size: 12px;
line-height: 1.5;
padding-left: 10px;
}
.component-upload-image .el-upload--picture-card {
width: 180px !important;
height: 90px !important;
}
.el-upload-list--picture-card .el-upload-list__item {
width: 180px!important;
height: 90px!important;
}
:deep(.el-upload-list) {
width:180px!important;
height: 90px!important;
.el-upload,
.el-upload-list--picture-card .el-upload-list__item {
width: 180px!important;
height: 90px!important;
}
.el-upload-list__item {
margin: 0;
border: none;
width: 180px!important;
height: 90px!important;
}
}
}
.upload-box-vioce11{
height: 400px !important;
overflow: hidden;
.upload-tips {
color: #999;
font-size: 12px;
line-height: 1.5;
padding-left: 10px;
}
.component-upload-image .el-upload--picture-card {
width: 300px !important;
height: 400px !important;
}
.el-upload-list--picture-card .el-upload-list__item {
width: 300px!important;
height: 400px!important;
}
:deep(.el-upload-list) {
width:300px!important;
height: 400px!important;
.el-upload,
.el-upload-list--picture-card .el-upload-list__item {
width: 300px!important;
height: 400px!important;
}
.el-upload-list__item {
margin: 0;
border: none;
width: 300px!important;
height: 400px!important;
}
}
}
</style>
<style >
.el-form-ge .el-form-item__content{
align-items: flex-start!important;
}
</style>

View File

@ -2,22 +2,43 @@
<table-search-card :model="queryParams" @getList="getList" @handleQuery="handleQuery" @resetQuery="resetQuery">
<template #left>
<el-form-item prop="platformShowCode">
<el-input v-model="queryParams.platformShowCode" :placeholder="t('请输入平台')" />
<el-input v-model="queryParams.platformShowCode" :placeholder="t('请输入平台展示代码')" />
</el-form-item>
</template>
<template #right>
<el-button type="primary" @click="superApiConfiguration" >{{ t('超管Api配置') }}</el-button>
<el-button type="primary" plain icon="Plus" @click="handleAdd" >{{ t('新增配置') }}</el-button>
</template>
</table-search-card>
<el-table v-loading="loading" :data="gameList" class="c-table-main" stripe
ref="dragTable" row-key="id" border>
<el-table-column :label="t('平台名称')" align="center" prop="platformCode" />
<el-table-column :label="t('api平台代码')" align="center" prop="apiPlatformCode" />
<el-table-column :label="t('货币信息')" align="center" prop="currencyInfo" />
<el-table-column :label="t('语言信息')" align="center" prop="langInfo" />
<el-table-column :label="t('平台展示代码')" align="center" min-width="120px" prop="platformShowCode" />
<el-table-column :label="t('平台名称')" align="center" min-width="120px" prop="platformCode" />
<el-table-column :label="t('api平台代码')" align="center" min-width="120px" prop="apiPlatformCode" />
<el-table-column :label="t('货币信息')" align="center" min-width="260px" prop="currencyInfo" >
<template #default="{row}">
<el-popover :width="260" trigger="hover">
{{ row.currencyInfo }}
<template #reference>
<div class="two-line-clamp">{{ row.currencyInfo }}</div>
</template>
</el-popover>
</template>
</el-table-column>
<el-table-column :label="t('语言信息')" align="center" min-width="260px" prop="langInfo" >
<template #default="{row}">
<el-popover :width="260" trigger="hover">
{{ row.langInfo }}
<template #reference>
<div class="two-line-clamp">{{ row.langInfo }}</div>
</template>
</el-popover>
</template>
</el-table-column>
<table-operation></table-operation>
<el-table-column :label="t('操作')" align="center" class-name="small-padding fixed-width">
<el-table-column :label="t('操作')" align="center" min-width="120px" class-name="small-padding fixed-width">
<template #default="scope">
<el-button link type="primary" @click="handleUpdate(scope.row)"
v-hasPermi="['game:game:edit']">{{ t('修改') }}</el-button>
@ -32,14 +53,19 @@
<add-dialog v-if="isShowDialog"
:addEditStatus="addEditStatus" :modifyDate="modifyDate" @submit="getList"
v-model:show="isShowDialog"></add-dialog>
<SuperApiConfigurationdialog v-if="isShowApiConfiguration"
:addEditStatus="addEditStatus" :modifyDate="modifyDate" @submit="getList"
v-model:show="isShowApiConfiguration"></SuperApiConfigurationdialog>
</template>
<script setup name="Game">
import AddDialog from "./AddDialog"///
import SuperApiConfigurationdialog from "./SuperApiConfigurationdialog"
import * as game from "@/api/game/game";
import { platformSelect,getGamePlatformApiSync,getGamePlatformTenantSync } from "@/api/game/platform";
import {getGameSecretList,getGameSecretInfo} from "@/api/game/configuration";
import {getGameSecretList,getGameSecretInfo,deleteGameSecret} from "@/api/game/configuration";
import useInitDataStore from "@/store/modules/initData";
import { ref } from "vue";
const emits = defineEmits(["reset"])
@ -116,11 +142,11 @@ const addEditStatus = ref('add'), isShowDialog = ref(false), editDataId = ref(''
function handleUpdate(row) {
reset();
const _id = row.id || ids.value
game.getGame(_id).then(response => {
getGameSecretInfo(_id).then(response => {
modifyDate.value = response.data;
isShowDialog.value = true;
addEditStatus.value = 'edit'
title.value = proxy.t('修改平台管理');
title.value = proxy.t('修改配置');
});
// proxy.$modal.msgError("")
}
@ -130,13 +156,17 @@ const handleAdd = () => {
addEditStatus.value = 'add'
title.value = proxy.t('新增配置');
}
const isShowApiConfiguration =ref(false)
const superApiConfiguration = () =>{
isShowApiConfiguration.value = true
}
const handleSynchronous = (row) => {
proxy.$modal.confirm(proxy.t('当前设置宣传图同步到所有币种下生效')).then(() => {
game.gameGameSync({id:row.id}).then(() => {
proxy.$modal.msgSuccess(proxy.t('同步成功'));
proxy.$modal.confirm(proxy.t('确认是否删除?')).then(() => {
deleteGameSecret(row.id).then(() => {
proxy.$modal.msgSuccess(proxy.t('删除成功'));
getList();
})
}).catch(() => {})
}).catch(() => {})
}
// api
const handleApiGame = () => {
@ -164,4 +194,18 @@ onMounted(() => {
})
</script>
<style scoped lang="scss"></style>
<style scoped lang="scss">
.two-line-clamp {
width: 100%;
height: auto;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
flex-wrap: nowrap;
line-height: 23px;
}
</style>

View File

@ -22,20 +22,19 @@
<el-form-item :label="t('icon图样式')" prop="iconStyle">
<el-radio-group v-model="formAll.iconStyle">
<el-radio :value="1">{{ t('默认') }}</el-radio>
<el-radio :value="2">{{ t('自定义') }}</el-radio>
<!-- <el-radio :value="2">{{ t('自定义') }}</el-radio> -->
</el-radio-group>
</el-form-item>
<div v-if="formAll.iconStyle == 1">
<el-form-item :label="t('品牌LOGO')" prop="gameLogo">
<div class="upload-box-vioce">
<image-upload :disabled="formAll.iconStyle == 1" :typeUpImg="3" v-model="formAll.gameLogo" :limit="1"
<image-upload :typeUpImg="3" v-model="formAll.gameLogo" :limit="1"
:isShowTip="false" :isdrag="true"></image-upload>
</div>
</el-form-item>
<el-form-item :label="t('icon图预览')" prop="gameIcon">
<div class="upload-box-vioce11">
<image-upload :disabled="formAll.iconStyle == 1" :typeUpImg="3" v-model="formAll.gameIcon" :limit="1"
<image-upload :typeUpImg="3" v-model="formAll.gameIcon" :limit="1"
:isShowTip="false" :isdrag="true"></image-upload>
</div>
</el-form-item>
@ -43,13 +42,13 @@
<div v-if="formAll.iconStyle == 2">
<el-form-item :label="t('品牌LOGO')" prop="customGameLogo">
<div class="upload-box-vioce">
<image-upload :disabled="formAll.iconStyle == 1" :typeUpImg="3" v-model="formAll.customGameLogo" :limit="1"
<image-upload :typeUpImg="3" v-model="formAll.customGameLogo" :limit="1"
:isShowTip="false" :isdrag="true"></image-upload>
</div>
</el-form-item>
<el-form-item :label="t('icon图预览')" prop="customGameIcon">
<div class="upload-box-vioce11">
<image-upload :disabled="formAll.iconStyle == 1" :typeUpImg="3" v-model="formAll.customGameIcon" :limit="1"
<image-upload :typeUpImg="3" v-model="formAll.customGameIcon" :limit="1"
:isShowTip="false" :isdrag="true"></image-upload>
</div>
</el-form-item>

View File

@ -0,0 +1,301 @@
<template>
<!-- 新增 -->
<el-dialog :title="t('语言翻译')" align-center :close-on-click-modal="false" width="1000" v-model="showDialog" append-to-body>
<el-scrollbar height="600px" >
<div style="display: flex;justify-content: space-between;margin-bottom: 10px;">
<div></div>
<div>
<el-button type="primary" @click="addTranslate">{{t('')}}</el-button>
</div>
</div>
<el-table v-loading="loading" :data="translateList" class="c-table-main" stripe
ref="dragTable" row-key="id" border>
<el-table-column :label="t('游戏代码')" align="center" min-width="120px" prop="gameCode" />
<el-table-column :label="t('游戏名称')" align="center" min-width="120px" prop="gameName" />
<el-table-column :label="t('语言')" align="center" min-width="120px" prop="langCode" />
<table-operation></table-operation>
<el-table-column :label="t('操作')" align="center" min-width="120px" class-name="small-padding fixed-width">
<template #default="scope">
<el-button link type="primary" @click="handleUpdate(scope.row)"
v-hasPermi="['game:game:edit']">{{ t('修改') }}</el-button>
</template>
</el-table-column>
</el-table>
</el-scrollbar>
<template #footer>
<div class="dialog-footer" style="display: flex;justify-content: center;">
<!-- <el-button type="primary" @click="submitForm" :loading="loadingButton">{{ t('确 定') }}</el-button> -->
<el-button @click="closeDialog">{{ t(' ') }}</el-button>
</div>
</template>
<el-dialog v-if="showPreview" :title="addEditType == 'add'?t('新增'):t('修改')" align-center v-model="showPreview" width="700px" append-to-body>
<el-scrollbar>
<el-form ref="formRef" :model="formAll" :rules="rules" label-width="130px" class="add-form">
<el-form-item :label="t('游戏代码')" prop="gameCode">
<el-input v-model="formAll.gameCode" :placeholder="t('请输入游戏代码')" />
</el-form-item>
<el-form-item :label="t('游戏名称')" prop="gameName">
<el-input v-model="formAll.gameName" :placeholder="t('请输入游戏名称')" />
</el-form-item>
<el-form-item :label="t('语言')" prop="langCode">
<CustomSelect v-model="formAll.langCode" :options="langCodeSelect" :placeholder="t('请选择语言')" ></CustomSelect>
</el-form-item>
</el-form>
</el-scrollbar>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitFormPreview" :loading="loadingButton">{{ t('确 定') }}</el-button>
<el-button @click="closeDialogPreview">{{ t(' ') }}</el-button>
</div>
</template>
</el-dialog>
</el-dialog>
</template>
<script setup>
import { formatTime,finalTimestamp } from '@/utils/ruoyi'; //
import ImageUpload from "@/components/ImageUpload";
import NumberInput from "@/components/NumberInput";
import { getGameNameList,updateGameName,postGameName } from "@/api/game/platform";
import BannerColour from "@/components/BannerColour"; // Banner
import BannerIcon from "@/components/BannerIcon"; // Banner
import CustomSelect from "@/components/CustomSelect";
import { getToken } from '@/utils/auth'
import { nextTick, onMounted, ref } from "vue"; //
import { getLocalStorage } from "@/utils/auth";
const fileHost = getLocalStorage('fileUrl') || ''; // host
const uploadUrl = getLocalStorage('uploadUrl');
const uploadImgUrl = ref(uploadUrl + "/file/upload/localSysFile/3"); //
const loadingButton = ref(false);
const oldForm = shallowRef({ });
const { proxy } = getCurrentInstance() //
const emits = defineEmits(['submit', 'update:show']) //
const props = defineProps({ //
data: {
type: Object, //
default: {}
},
show: {
type: Boolean, //
default: false
},
addEditStatus:{ // /
type: String,
default: 'add'
},
modifyDate: { //
type: Object,
default: {}
}
})
const showDialog = computed({ //
get() {
return props.show
},
set(value) {
emits('update:show', value)
}
})
const translateList = ref([]),loading = ref(false);
const langCodeSelect = ref(getLocalStorage('langSelect')?.filter(v => v.langType == 1 && v.langStatus).map((item)=>{
return {label: `${item.name}(${item.langDisplay})`, value: item.countryLang};
}))
const formAll = reactive({
})
const getGameNameLists = () => {
getGameNameList({gameCode: props.modifyDate.gameCode}).then(res => {
if (res.code === 200) {
translateList.value = res.data
}
})
}
//
nextTick(async () => {
getGameNameLists();
});
//
const rules = reactive({
gameCode: [
{ required: true, message: '请输入游戏名称', trigger: 'blur' }
],
gameName: [
{ required: true, message: '请输入游戏名称', trigger: 'blur' }
],
langCode: [
{ required: true, message: '请选择语言', trigger: 'change' }
],
})
const showPreview = ref(false);
const addEditType = ref('add');
const addTranslate = () => {
addEditType.value = 'add';
formAll.langCode = '';
formAll.gameCode = props.modifyDate.gameCode;
formAll.gameName = props.modifyDate.gameName;
showPreview.value = false;
nextTick(() => {
showPreview.value = true;
});
}
const handleUpdate = (row) => {
showPreview.value = true;
Object.assign(formAll, row);
addEditType.value = 'edit';
showPreview.value = false;
nextTick(() => {
showPreview.value = true;
});
}
const closeDialogPreview = () => {
showPreview.value = false
}
//
const formRef = ref(null)
const submitFormPreview = () => {
formRef.value.validate(async(valid) => {
if (valid) {
let formData = {
...formAll,
gamePlatformId:props.modifyDate.id
}
if(addEditType.value == 'add'){
postGameName(formData).then(res => {
proxy.$modal.msgSuccess(proxy.t('添加成功!'));
getGameNameLists();
closeDialogPreview();
})
}else if(addEditType.value == 'edit'){
updateGameName(formData).then(res => {
proxy.$modal.msgSuccess(proxy.t('修改成功!'));
getGameNameLists();
closeDialogPreview();
})
}
}
})
}
//
const closeDialog = () => {
showDialog.value = false
}
</script>
<style scope lang="scss">
.w100 {
width: 100%;
}
.upload-box-vioce{
height: 90px !important;
overflow: hidden;
.upload-tips {
color: #999;
font-size: 12px;
line-height: 1.5;
padding-left: 10px;
}
.component-upload-image .el-upload--picture-card {
width: 180px !important;
height: 90px !important;
}
.el-upload-list--picture-card .el-upload-list__item {
width: 180px!important;
height: 90px!important;
}
:deep(.el-upload-list) {
width:180px!important;
height: 90px!important;
.el-upload,
.el-upload-list--picture-card .el-upload-list__item {
width: 180px!important;
height: 90px!important;
}
.el-upload-list__item {
margin: 0;
border: none;
width: 180px!important;
height: 90px!important;
}
}
}
.upload-box-vioce11{
height: 400px !important;
overflow: hidden;
.upload-tips {
color: #999;
font-size: 12px;
line-height: 1.5;
padding-left: 10px;
}
.component-upload-image .el-upload--picture-card {
width: 300px !important;
height: 400px !important;
}
.el-upload-list--picture-card .el-upload-list__item {
width: 300px!important;
height: 400px!important;
}
:deep(.el-upload-list) {
width:300px!important;
height: 400px!important;
.el-upload,
.el-upload-list--picture-card .el-upload-list__item {
width: 300px!important;
height: 400px!important;
}
.el-upload-list__item {
margin: 0;
border: none;
width: 300px!important;
height: 400px!important;
}
}
}
.upload-box-vioce22{
height: 200px !important;
overflow: hidden;
.upload-tips {
color: #999;
font-size: 12px;
line-height: 1.5;
padding-left: 10px;
}
.component-upload-image .el-upload--picture-card {
width: 400px !important;
height: 200px !important;
}
.el-upload-list--picture-card .el-upload-list__item {
width: 400px!important;
height: 200px!important;
}
:deep(.el-upload-list) {
width:400px!important;
height: 200px!important;
.el-upload,
.el-upload-list--picture-card .el-upload-list__item {
width: 400px!important;
height: 200px!important;
}
.el-upload-list__item {
margin: 0;
border: none;
width: 400px!important;
height: 200px!important;
}
}
}
.disable-click {
pointer-events: none;
}
</style>

View File

@ -2,17 +2,17 @@
<table-search-card :model="queryParams" @getList="getList" @handleQuery="handleQuery" @resetQuery="resetQuery">
<template #left>
<el-form-item prop="currencyCode">
<currency-select style="width: 200px;" v-model="queryParams.currencyCode" @change="platformListInit()"></currency-select>
<currency-select style="width: 200px;" filterable v-model="queryParams.currencyCode" @change="platformListInit()"></currency-select>
</el-form-item>
<el-form-item prop="gameType">
<custom-select v-model="queryParams.gameType" style="width: 200px;" :options="gameTypeOptions" @change="gameTypeChange" :clearable="false"></custom-select>
<custom-select v-model="queryParams.gameType" style="width: 200px;" filterable :options="gameTypeOptions" @change="gameTypeChange" :clearable="false"></custom-select>
</el-form-item>
<!-- <el-form-item prop="gameType">
<dict-select v-model="queryParams.gameType" :config="{hasCheckAll:true,filterValue:['8','7','6','3','9']}" dictKey="ff_game_type" @change="gameTypeChange"
:clearable="false" :isDefault="useInitData.dictInitData.platformType ? false : true" ></dict-select>
</el-form-item> -->
<el-form-item prop="platformId">
<el-select v-model="queryParams.platformId" style="width: 200px;">
<el-select v-model="queryParams.platformId" filterable style="width: 200px;">
<el-option v-for="item in platformList" :key="item.id" :label="item.platformName" :value="item.id" />
</el-select>
</el-form-item>
@ -38,7 +38,7 @@
<el-table-column :label="t('币种')" align="center" prop="currencyDisplay" />
<el-table-column :label="t('维护开关')" align="center" prop="stopStatus" label-class-name="text-warning">
<template #default="{ row }">
<el-switch v-model="row.stopStatus" :active-value="1" :inactive-value="2"
<el-switch v-model="row.stopStatus" :disabled="row.gameStatus == 2" :active-value="1" :inactive-value="2"
:before-change="switchBeforeChange"
@click="beforeSwitchChange(row, 'stopStatus')" />
</template>
@ -58,12 +58,14 @@
</template>
</el-table-column>
<el-table-column :label="t('操作')" align="center" class-name="small-padding fixed-width">
<el-table-column :label="t('操作')" align="center" min-width="130px" class-name="small-padding fixed-width">
<template #default="scope">
<el-button link type="primary" @click="handleUpdate(scope.row)"
v-hasPermi="['game:game:edit']">{{ t('修改') }}</el-button>
<el-button link type="primary" @click="handleSynchronous(scope.row)"
v-hasPermi="['game:game:sync']">{{ t('同步') }}</el-button>
<el-button link type="primary" @click="fhandleTranslate(scope.row)"
v-hasPermi="['game:platform:name:list']">{{ t('翻译') }}</el-button>
</template>
</el-table-column>
<table-operation></table-operation>
@ -74,10 +76,15 @@
<add-dialog v-if="isShowDialog"
:addEditStatus="addEditStatus" :modifyDate="modifyDate" @submit="getList"
v-model:show="isShowDialog"></add-dialog>
<translate-dialog v-if="translateShowDialog"
:addEditStatus="addEditStatus" :modifyDate="modifyDate" @submit="getList"
v-model:show="translateShowDialog"></translate-dialog>
</template>
<script setup name="Game">
import AddDialog from "./AddDialog"///
import TranslateDialog from "./TranslateDialog"
import * as game from "@/api/game/game";
import { platformSelect,getGamePlatformApiSync,getGamePlatformTenantSync } from "@/api/game/platform";
import useInitDataStore from "@/store/modules/initData";
@ -103,6 +110,7 @@ const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const title = ref("");
const translateShowDialog = ref(false);
const gameTypeOptions = ref([
{ label: '电子', value: '1' },
{ label: '棋牌', value: '2' },
@ -141,7 +149,10 @@ function getList() {
loading.value = false;
});
}
const fhandleTranslate = (row) => {
translateShowDialog.value = true;
modifyDate.value = row;
}
//
function reset() {
form.value = {

View File

@ -24,7 +24,7 @@
<el-form-item :label="t('是否同步')" prop="syncStatus">
<el-checkbox v-model="formAll.syncStatus" />
</el-form-item>
<el-form-item :label="t('平台跳转方式')" prop="iosJump">
<!-- <el-form-item :label="t('平台跳转方式')" prop="iosJump">
<div style="width: 100%;display: flex;">
<div style="width: 80px;text-align: right;margin-right: 10px;">IOS:</div>
<el-radio-group v-model="formAll.iosJump" style="margin-bottom: 0px">
@ -46,11 +46,11 @@
<el-radio :value="2">{{ t('外链') }}</el-radio>
</el-radio-group>
</div>
</el-form-item>
</el-form-item> -->
<el-form-item :label="t('宣传图样式')" prop="promotionalStyle">
<el-radio-group v-model="formAll.promotionalStyle">
<el-radio :value="1">{{ t('默认') }}</el-radio>
<el-radio :value="2">{{ t('自定义') }}</el-radio>
<!-- <el-radio :value="2">{{ t('自定义') }}</el-radio> -->
</el-radio-group>
</el-form-item>

View File

@ -0,0 +1,327 @@
<template>
<!-- 新增 -->
<el-dialog :title="t('语言翻译')" align-center :close-on-click-modal="false" width="1000" v-model="showDialog" append-to-body>
<el-scrollbar height="600px" >
<div style="display: flex;justify-content: space-between;margin-bottom: 10px;">
<div></div>
<div>
<el-button type="primary" @click="addTranslate">{{t('')}}</el-button>
</div>
</div>
<el-table v-loading="loading" :data="translateList" class="c-table-main" stripe
ref="dragTable" row-key="id" border>
<el-table-column :label="t('游戏平台id')" align="center" min-width="120px" prop="gamePlatformId" />
<el-table-column :label="t('游戏平台名称')" align="center" min-width="120px" prop="gamePlatformName" />
<el-table-column :label="t('语言')" align="center" min-width="120px" prop="langCode" />
<table-operation></table-operation>
<el-table-column :label="t('操作')" align="center" min-width="120px" class-name="small-padding fixed-width">
<template #default="scope">
<el-button link type="primary" @click="handleUpdate(scope.row)"
v-hasPermi="['game:game:edit']">{{ t('修改') }}</el-button>
</template>
</el-table-column>
</el-table>
</el-scrollbar>
<template #footer>
<div class="dialog-footer" style="display: flex;justify-content: center;">
<!-- <el-button type="primary" @click="submitForm" :loading="loadingButton">{{ t('确 定') }}</el-button> -->
<el-button @click="closeDialog">{{ t(' ') }}</el-button>
</div>
</template>
<el-dialog v-if="showPreview" :title="addEditType == 'add'?t('新增'):t('修改')" align-center v-model="showPreview" width="700px" append-to-body>
<el-scrollbar>
<el-form ref="formRef" :model="formAll" :rules="rules" label-width="130px" class="add-form">
<el-form-item :label="t('游戏平台名称')" prop="gamePlatformName">
<el-input v-model="formAll.gamePlatformName" :placeholder="t('请输入游戏平台名称')" />
</el-form-item>
<el-form-item :label="t('语言')" prop="langCode">
<CustomSelect v-model="formAll.langCode" :options="langCodeSelect" :placeholder="t('请选择语言')" ></CustomSelect>
</el-form-item>
</el-form>
</el-scrollbar>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitFormPreview" :loading="loadingButton">{{ t('确 定') }}</el-button>
<el-button @click="closeDialogPreview">{{ t(' ') }}</el-button>
</div>
</template>
</el-dialog>
</el-dialog>
</template>
<script setup>
import { formatTime,finalTimestamp } from '@/utils/ruoyi'; //
import ImageUpload from "@/components/ImageUpload";
import NumberInput from "@/components/NumberInput";
import { updatePlatform,getGamePlatformNameList,updateGamePlatformName,postGamePlatformName } from "@/api/game/platform";
import BannerColour from "@/components/BannerColour"; // Banner
import BannerIcon from "@/components/BannerIcon"; // Banner
import CustomSelect from "@/components/CustomSelect";
import { getToken } from '@/utils/auth'
import { nextTick, onMounted, ref } from "vue"; //
import { getLocalStorage } from "@/utils/auth";
const fileHost = getLocalStorage('fileUrl') || ''; // host
const uploadUrl = getLocalStorage('uploadUrl');
const uploadImgUrl = ref(uploadUrl + "/file/upload/localSysFile/3"); //
const loadingButton = ref(false);
const oldForm = shallowRef({ });
const { proxy } = getCurrentInstance() //
const emits = defineEmits(['submit', 'update:show']) //
const props = defineProps({ //
data: {
type: Object, //
default: {}
},
show: {
type: Boolean, //
default: false
},
addEditStatus:{ // /
type: String,
default: 'add'
},
modifyDate: { //
type: Object,
default: {}
}
})
const showDialog = computed({ //
get() {
return props.show
},
set(value) {
emits('update:show', value)
}
})
const translateList = ref([]),loading = ref(false);
const langCodeSelect = ref(getLocalStorage('langSelect')?.filter(v => v.langType == 1 && v.langStatus).map((item)=>{
return {label: `${item.name}(${item.langDisplay})`, value: item.countryLang};
}))
const formAll = reactive({
})
const getGamePlatformNameLists = () => {
getGamePlatformNameList({gamePlatformId: props.modifyDate.id}).then(res => {
if (res.code === 200) {
translateList.value = res.data
}
})
}
//
nextTick(async () => {
getGamePlatformNameLists();
});
//
const rules = reactive({
gamePlatformName: [
{ required: true, message: '请输入游戏名称', trigger: 'blur' }
],
langCode: [
{ required: true, message: '请选择语言', trigger: 'change' }
]
})
const showPreview = ref(false);
const addEditType = ref('add');
const addTranslate = () => {
addEditType.value = 'add';
formAll.langCode = '';
formAll.gamePlatformName = props.modifyDate.platformName;
showPreview.value = false;
nextTick(() => {
showPreview.value = true;
});
}
const handleUpdate = (row) => {
showPreview.value = true;
Object.assign(formAll, row);
addEditType.value = 'edit';
showPreview.value = false;
nextTick(() => {
showPreview.value = true;
});
}
const closeDialogPreview = () => {
showPreview.value = false
}
//
const formRef = ref(null)
const submitFormPreview = () => {
formRef.value.validate(async(valid) => {
if (valid) {
let formData = {
...formAll,
gamePlatformId:props.modifyDate.id
}
if(addEditType.value == 'add'){
postGamePlatformName(formData).then(res => {
proxy.$modal.msgSuccess(proxy.t('添加成功!'));
getGamePlatformNameLists();
closeDialogPreview();
})
}else if(addEditType.value == 'edit'){
updateGamePlatformName(formData).then(res => {
proxy.$modal.msgSuccess(proxy.t('修改成功!'));
getGamePlatformNameLists();
closeDialogPreview();
})
}
}
})
}
//
const closeDialog = () => {
showDialog.value = false
}
//
const submitForm = async() => {
//
formRef.value.validate(async(valid) => {
if (valid) {
//
let formData = {
...formAll,
};
if (JSON.stringify(formAll) != oldForm.value) {
updatePlatform(formData).then(res => {
loadingButton.value = false;
proxy.$modal.msgSuccess(proxy.t('修改成功!'));
emits('submit');
closeDialog();
}).catch(error => {
loadingButton.value = false;
});
}else{
loadingButton.value = false;
closeDialog();
}
}
});
};
</script>
<style scope lang="scss">
.w100 {
width: 100%;
}
.upload-box-vioce{
height: 90px !important;
overflow: hidden;
.upload-tips {
color: #999;
font-size: 12px;
line-height: 1.5;
padding-left: 10px;
}
.component-upload-image .el-upload--picture-card {
width: 180px !important;
height: 90px !important;
}
.el-upload-list--picture-card .el-upload-list__item {
width: 180px!important;
height: 90px!important;
}
:deep(.el-upload-list) {
width:180px!important;
height: 90px!important;
.el-upload,
.el-upload-list--picture-card .el-upload-list__item {
width: 180px!important;
height: 90px!important;
}
.el-upload-list__item {
margin: 0;
border: none;
width: 180px!important;
height: 90px!important;
}
}
}
.upload-box-vioce11{
height: 400px !important;
overflow: hidden;
.upload-tips {
color: #999;
font-size: 12px;
line-height: 1.5;
padding-left: 10px;
}
.component-upload-image .el-upload--picture-card {
width: 300px !important;
height: 400px !important;
}
.el-upload-list--picture-card .el-upload-list__item {
width: 300px!important;
height: 400px!important;
}
:deep(.el-upload-list) {
width:300px!important;
height: 400px!important;
.el-upload,
.el-upload-list--picture-card .el-upload-list__item {
width: 300px!important;
height: 400px!important;
}
.el-upload-list__item {
margin: 0;
border: none;
width: 300px!important;
height: 400px!important;
}
}
}
.upload-box-vioce22{
height: 200px !important;
overflow: hidden;
.upload-tips {
color: #999;
font-size: 12px;
line-height: 1.5;
padding-left: 10px;
}
.component-upload-image .el-upload--picture-card {
width: 400px !important;
height: 200px !important;
}
.el-upload-list--picture-card .el-upload-list__item {
width: 400px!important;
height: 200px!important;
}
:deep(.el-upload-list) {
width:400px!important;
height: 200px!important;
.el-upload,
.el-upload-list--picture-card .el-upload-list__item {
width: 400px!important;
height: 200px!important;
}
.el-upload-list__item {
margin: 0;
border: none;
width: 400px!important;
height: 200px!important;
}
}
}
.disable-click {
pointer-events: none;
}
</style>

View File

@ -2,10 +2,10 @@
<table-search-card :model="queryParams" @getList="getList" @handleQuery="handleQuery" @resetQuery="resetQuery">
<template #left>
<el-form-item prop="currencyCode">
<currency-select style="width: 200px;" v-model="queryParams.currencyCode" @change="handleQuery"></currency-select>
<currency-select style="width: 200px;" filterable v-model="queryParams.currencyCode" @change="handleQuery"></currency-select>
</el-form-item>
<el-form-item prop="platformType">
<custom-select v-model="queryParams.platformType" style="width: 200px;" :options="gameTypeOptions" :clearable="false"></custom-select>
<custom-select v-model="queryParams.platformType" filterable style="width: 200px;" :options="gameTypeOptions" :clearable="false"></custom-select>
</el-form-item>
<el-form-item prop="platformName">
<el-input v-model="queryParams.platformName" :placeholder="t('请输入平台名称')" clearable @keyup.enter="handleQuery" />
@ -83,12 +83,14 @@
</el-row>
</template>
</el-table-column>
<el-table-column :label="t('操作')" align="center" class-name="small-padding fixed-width" width="110">
<el-table-column :label="t('操作')" align="center" class-name="small-padding fixed-width" min-width="130">
<template #default="scope">
<el-button link type="primary" @click="handleUpdate(scope.row)"
v-hasPermi="['game:platform:edit']">{{ t('修改') }}</el-button>
<el-button link type="primary" @click="handleSynchronous(scope.row)"
v-hasPermi="['game:platform:sync']">{{ t('同步') }}</el-button>
<el-button link type="primary" @click="fhandleTranslate(scope.row)"
v-hasPermi="['game:platform:name:list']">{{ t('翻译') }}</el-button>
</template>
</el-table-column>
<!-- <table-operation></table-operation> -->
@ -103,10 +105,15 @@
<add-dialog v-if="isShowDialog"
:addEditStatus="addEditStatus" :modifyDate="modifyDate" @submit="getList"
v-model:show="isShowDialog"></add-dialog>
<translate-dialog v-if="translateShowDialog"
:addEditStatus="addEditStatus" :modifyDate="modifyDate" @submit="getList"
v-model:show="translateShowDialog"></translate-dialog>
</template>
<script setup name="Platform">
import AddDialog from "./components/AddDialog"///
import TranslateDialog from "./components/TranslateDialog"
import * as platform from "@/api/game/platform";
import GameRestrictions from "./components/GameRestrictions.vue"
import BettingConfiguration from "./components/bettingConfiguration.vue"
@ -148,7 +155,7 @@ const ids = ref([]);
const single = ref(true);
const multiple = ref(true);
const title = ref("");
const translateShowDialog = ref(false);
const data = reactive({
form: {},
queryParams: {
@ -232,6 +239,11 @@ function handleUpdate(row) {
});
// proxy.$modal.msgError("")
}
const fhandleTranslate = (row) => {
translateShowDialog.value = true;
modifyDate.value = row;
}
const handleSynchronous = (row) => {
proxy.$modal.confirm(proxy.t('当前设置宣传图同步到所有币种下生效')).then(() => {
platform.gamePlatformSync({id:row.id}).then(() => {

View File

@ -0,0 +1,257 @@
<template>
<!-- 新增 -->
<el-dialog :title="addEditStatus=='add' ? t('新增') : t('修改')" align-center :close-on-click-modal="false" v-model="showDialog"
width="800px" append-to-body>
<el-scrollbar max-height="900px">
<el-form ref="formRef" :model="formAll" :rules="rules" label-width="130px" class="add-form">
<el-form-item :label="t('语言名称')" prop="name">
<el-input v-model="formAll.name" :placeholder="t('请输入语言名称')" />
</el-form-item>
<el-form-item :label="t('语言显示')" prop="langDisplay">
<el-input v-model="formAll.langDisplay" :placeholder="t('请输入语言显示')"/>
</el-form-item>
<el-form-item :label="t('国家代码')" prop="country">
<el-input v-model="formAll.country" :placeholder="t('请输入国家代码')"/>
</el-form-item>
<el-form-item :label="t('语种')" prop="langCode">
<el-input v-model="formAll.langCode" :placeholder="t('请输入语种')"/>
</el-form-item>
<el-form-item :label="t('币种图标')" prop="iconUrl">
<image-upload v-model="formAll.iconUrl" :limit="1" :typeUpImg="2" :fileSize="5"></image-upload>
</el-form-item>
<el-form-item :label="t('语种类型')" prop="langType">
<el-radio-group v-model="formAll.langType">
<el-radio :value="1">{{ t('app') }}</el-radio>
<el-radio :value="2">{{ t('后台管理系统') }}</el-radio>
</el-radio-group>
</el-form-item>
<!-- <el-form-item :label="t('是否默认')" prop="langDefault">
<el-switch v-model="formAll.langDefault" :active-value="true" :inactive-value="false"/>
</el-form-item>
<el-form-item :label="t('启用状态')" prop="langStatus">
<el-switch v-model="formAll.langStatus" :active-value="true" :inactive-value="false"/>
</el-form-item> -->
</el-form>
</el-scrollbar>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm" :loading="loadingButton">{{ t('确 定') }}</el-button>
<el-button @click="closeDialog">{{ t(' ') }}</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import { formatTime,finalTimestamp } from '@/utils/ruoyi'; //
import ImageUpload from "@/components/ImageUpload";
import { updateGame } from "@/api/game/game";
import {postLang,updateLang} from "@/api/operation/lang";
import { nextTick, onMounted, ref } from "vue"; //
import { getLocalStorage } from "@/utils/auth";
const langList = getLocalStorage('langList')?.filter(v => v.langType == 1 && v.langStatus).map(item => {
return {
label: item.name,
value: item.id
};
}); //
const loadingButton = ref(false);
const oldForm = shallowRef({ });
const { proxy } = getCurrentInstance() //
const emits = defineEmits(['submit', 'update:show']) //
const props = defineProps({ //
data: {
type: Object, //
default: {}
},
show: {
type: Boolean, //
default: false
},
addEditStatus:{ // /
type: String,
default: 'add'
},
modifyDate: { //
type: Object,
default: {}
}
})
const showDialog = computed({ //
get() {
return props.show
},
set(value) {
emits('update:show', value)
}
})
const activeNameLang = ref(0);//
const langOptionAll = ref([]); // tabs
const formAll = reactive({
langType:1,
})
//
nextTick(() => {
if (props.addEditStatus != 'edit') return;
Object.assign(formAll, props.modifyDate)
setTimeout(() => {
let objForm = { ...formAll }
oldForm.value = JSON.stringify(objForm);
}, 500);
});
//
const rules = reactive({
name: [
{ required: true, message: '请输入语言名称', trigger: 'change' },
],
langDisplay:[
{ required: true, message: '请输入语言显示名称', trigger: 'change' },
],
country:[
{ required: true, message: '请输入语言国家', trigger: 'change' },
],
langCode:[
{ required: true, message: '请输入语言编码', trigger: 'change' },
],
iconUrl:[
{ required: true, message: '请输入图标地址', trigger: 'change' },
],
})
//
const closeDialog = () => {
showDialog.value = false
}
//
const formRef = ref(null)
//
const submitForm = () => {
//
formRef.value.validate(valid => {
if (valid) {
if (props.addEditStatus == 'add'){
loadingButton.value = true;
//
let formData = {
...formAll
};
postLang(formData).then(res => {
loadingButton.value = false;
proxy.$modal.msgSuccess(proxy.t('新增成功'));
emits('submit');
closeDialog();
}).catch(() => {
loadingButton.value = false;
});
}else{
loadingButton.value = true;
//
let formData = {
...formAll
};
if (JSON.stringify(formAll) != oldForm.value) {
updateLang(formData).then(res => {
loadingButton.value = false;
proxy.$modal.msgSuccess(proxy.t('修改成功!'));
emits('submit');
closeDialog();
}).catch(() => {
loadingButton.value = false;
});
}else{
loadingButton.value = false;
closeDialog();
}
}
}
});
};
</script>
<style scope lang="scss">
.w100 {
width: 100%;
}
.upload-box-vioce{
height: 90px !important;
overflow: hidden;
.upload-tips {
color: #999;
font-size: 12px;
line-height: 1.5;
padding-left: 10px;
}
.component-upload-image .el-upload--picture-card {
width: 180px !important;
height: 90px !important;
}
.el-upload-list--picture-card .el-upload-list__item {
width: 180px!important;
height: 90px!important;
}
:deep(.el-upload-list) {
width:180px!important;
height: 90px!important;
.el-upload,
.el-upload-list--picture-card .el-upload-list__item {
width: 180px!important;
height: 90px!important;
}
.el-upload-list__item {
margin: 0;
border: none;
width: 180px!important;
height: 90px!important;
}
}
}
.upload-box-vioce11{
height: 400px !important;
overflow: hidden;
.upload-tips {
color: #999;
font-size: 12px;
line-height: 1.5;
padding-left: 10px;
}
.component-upload-image .el-upload--picture-card {
width: 300px !important;
height: 400px !important;
}
.el-upload-list--picture-card .el-upload-list__item {
width: 300px!important;
height: 400px!important;
}
:deep(.el-upload-list) {
width:300px!important;
height: 400px!important;
.el-upload,
.el-upload-list--picture-card .el-upload-list__item {
width: 300px!important;
height: 400px!important;
}
.el-upload-list__item {
margin: 0;
border: none;
width: 300px!important;
height: 400px!important;
}
}
}
</style>

View File

@ -0,0 +1,182 @@
<template>
<div class="app-container">
<table-search-card :model="queryParams" @getList="getList" @handleQuery="handleQuery" @resetQuery="resetQuery">
<template #left>
<el-form-item prop="name">
<el-input v-model="queryParams.name" :placeholder="t('请输入语种名称')" clearable @clear="handleQuery"
@keyup.enter="handleQuery" style="width: 220px;" />
</el-form-item>
<el-form-item prop="langType">
<el-select v-model="queryParams.langType" :placeholder="t('请选择语种类型')" clearable
style="width: 160px;">
<el-option v-for="item in lang_type" :key="item.value" :label="t(item.label)" :value="item.value" />
</el-select>
</el-form-item>
</template>
<template #right>
<el-button type="primary" plain icon="Plus" @click="handleAdd" >{{ t('新增') }}</el-button>
</template>
</table-search-card>
<!-- 查询表格 -->
<el-table v-loading="loading" :data="dataList" class="c-table-main" stripe border>
<el-table-column :label="t('序号')" align="center" type="index" width="80">
<template #default="{ $index }">
<span>{{ (queryParams.pageNum - 1) * queryParams.pageSize + $index + 1 }}</span>
</template>
</el-table-column>
<el-table-column :label="t('语种图标')" align="center" min-width="100">
<template #default="{ row }">
<el-image class="table-icon-image" :src="fileHost + row.iconUrl" fit="contain" />
</template>
</el-table-column>
<el-table-column :label="t('语言名称')" align="center" prop="name" min-width="100" />
<el-table-column :label="t('国家代码')" align="center" prop="country" min-width="100" />
<el-table-column :label="t('语种')" align="center" prop="langCode" min-width="100" />
<el-table-column :label="t('是否默认')" align="center" min-width="100">
<template #default="{ row }">
<el-switch v-model="row.langDefault" :active-value="true" :inactive-value="false"
:before-change="switchBeforeChange" @click="handleUpdate(row, 'langDefault')" />
</template>
</el-table-column>
<el-table-column :label="t('启用状态')" align="center" min-width="100">
<template #default="{ row }">
<el-switch v-model="row.langStatus" :active-value="true" :inactive-value="false"
:before-change="switchBeforeChange" @click="handleUpdate(row, 'langStatus')" />
</template>
</el-table-column>
<el-table-column :label="t('语种类型')" align="center" min-width="100">
<template #default="{ row }">
{{ t(+row.langType == 1 ? 'app' : t('后台管理系统')) }}
</template>
</el-table-column>
<el-table-column :label="t('操作')" align="center" min-width="120px">
<template #default="scope">
<el-button link type="primary" @click="updateClick(scope.row)"
v-hasPermi="['game:game:edit']">{{ t('修改') }}</el-button>
<el-button link type="primary" @click="deleteClick(scope.row)"
v-hasPermi="['game:game:sync']">{{ 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" />
<add-dialog v-if="isShowDialog"
:addEditStatus="addEditStatus" :modifyDate="modifyDate" @submit="getList"
v-model:show="isShowDialog"></add-dialog>
</div>
</template>
<!-- 语种管理 -->
<script setup name="Lang">
import AddDialog from "./AddDialog"///
import { listLang, updateLang,getOperationLangInfo,delOperationLang } from "@/api/operation/lang";
import { getLocalStorage } from "@/utils/auth";
import { ref } from "vue";
const { proxy } = getCurrentInstance();
//
const lang_type = ref([
{ label: "app", value: "1" },
{ label: proxy.t('后台管理系统'), value: "2" },
]);
const addEditStatus = ref('add'), isShowDialog = ref(false), editDataId = ref(''),modifyDate = ref({});
const fileHost = getLocalStorage('fileUrl') || ''; // host
const dataList = ref([]); // list
const loading = ref(true);
const total = ref(0);
const queryParams = reactive({
pageNum: 1,
pageSize: 20,
orderByColumn: 'createTime',
isAsc: 'desc',
name: '',
langType: ''
});
//
function getList() {
loading.value = true;
listLang(queryParams).then(res => {
dataList.value = res.rows;
total.value = res.total;
loading.value = false;
});
}
getList();
//
const switchBeforeChange = () => {
return false;
}
//
const handleUpdate = (row, type) => {
const params = {
id: row.id
}
switch (type) {
case 'langDefault':
proxy.$modal.confirm(proxy.t('确认{}“' + row.name + '”为默认语种?', row.langDefault ? '取消' : '设定')).then(() => {
params.langDefault = !row.langDefault;
updateLang(params).then(res => {
proxy.$modal.msgSuccess(proxy.t('设置成功!'));
getList();
});
}).catch(() => { });
break
case 'langStatus':
if (row.langDefault && row.langStatus) {
proxy.$modal.msgError(proxy.t('默认语种不允许停用!'));
} else {
proxy.$modal.confirm(proxy.t('确认{}“' + row.name + '”该语种?', row.langStatus ? '停用' : '启用')).then(() => {
params.langStatus = !row.langStatus;
updateLang(params).then(res => {
proxy.$modal.msgSuccess(proxy.t('{}成功!', row.langStatus ? '停用' : '启用'));
getList();
});
}).catch(() => { });
}
break
}
}
//
const deleteClick = (row) => {
proxy.$modal.confirm(proxy.t('确认删除“' + row.name + '”的数据?')).then(() => {
delOperationLang(row.id).then(res => {
proxy.$modal.msgSuccess(proxy.t('删除成功!'));
getList();
});
}).catch(() => { });
}
const handleAdd = () => {
isShowDialog.value = true;
addEditStatus.value = 'add'
}
const updateClick = (row) => {
getOperationLangInfo(row.id).then(res => {
modifyDate.value = res.data;
isShowDialog.value = true;
addEditStatus.value = 'edit'
})
}
//
const handleQuery = () => {
queryParams.pageNum = 1;
getList();
}
//
const resetQuery = () => {
handleQuery();
}
</script>

View File

@ -20,7 +20,7 @@
<custom-select style="width: 130px;" v-if="siteSelect.length > 0" collapse-tags collapse-tags-tooltip v-model="queryParams.tenantId" :options="siteSelect" :placeholder="t('请选择')"></custom-select>
</el-form-item>
<el-form-item prop="currencyCode" class="w120px">
<custom-select v-model="queryParams.currencyCode" :options="currencySelectArr" style="width: 130px;" clearable @change="handleQuery"></custom-select>
<custom-select v-model="queryParams.currencyCode" :options="currencySelectArr" filterable style="width: 130px;" :placeholder="t('请选择币种')" clearable @change="handleQuery"></custom-select>
</el-form-item>
<select-input-form :queryParamsList="queryParamsList" v-model:queryParams="queryParams" :width="[120, 260]"
@handleQuery="handleQuery"></select-input-form>
@ -181,8 +181,14 @@ const queryParamsList = ref([{
value: 'source'
}]);
const currencySelectArr = getLocalStorage('currencySelect')?.map(item => {
let labels = '';
if (item.currencyCode == 'VND11'){
labels = `${item.currencyName}`;
}else{
labels = `${item.currencyName}(${item.currencyCode})`;
}
return {
label: `${item.currencyName}(${item.currencyCode})`,
label: labels,
value: item.currencyCode
};
}); //

View File

@ -6,6 +6,9 @@
<el-form-item :label="t('标题')" prop="title">
<el-input style="width: 550px;" v-model="formAll.title" placeholder="请输入标题"></el-input>
</el-form-item>
<el-form-item :label="t('币种')" prop="currencyCodes">
<checkbox-select style="width: 550px;" collapse-tags collapse-tags-tooltip v-model="formAll.currencyCodes" :options="currencySelectArr"></checkbox-select>
</el-form-item>
<el-form-item :label="t('内容')" prop="content">
<div style="width: 600px;">
<editor v-model="formAll.content" :min-height="260"/>
@ -27,12 +30,10 @@
<el-form-item :label="t('公告类型')" prop="noticeType">
<custom-select style="width: 550px;" v-model="formAll.noticeType" :options="noticeTypeArr"></custom-select>
</el-form-item>
<el-form-item :label="t('公告状态')" prop="noticeStatus">
<!-- <el-form-item :label="t('公告状态')" prop="noticeStatus">
<custom-select style="width: 550px;" v-model="formAll.noticeStatus" :options="noticeStatusArr"></custom-select>
</el-form-item>
<el-form-item :label="t('币种')" prop="currencyCodes">
<checkbox-select style="width: 550px;" collapse-tags collapse-tags-tooltip v-model="formAll.currencyCodes" :options="currencySelectArr"></checkbox-select>
</el-form-item>
</el-form-item> -->
</el-form>
</el-scrollbar>
<template #footer>
@ -145,7 +146,10 @@ const rules = reactive({
],
noticeStatus: [
{ required: true, message: proxy.t('请选择公告状态'), trigger: 'change' }
]
],
currencyCodes: [
{ required: true, message: proxy.t('请选择币种'), trigger: 'change' }
],
})
//
const closeDialog = () => {

View File

@ -59,7 +59,7 @@
</el-table-column>
<el-table-column :label="t('操作')" align="center" width="160">
<template #default="scope">
<el-button link type="primary" @click="handleEdit(scope.row)" v-hasPermi="['tenant:notice:edit']">{{ t('') }}</el-button>
<el-button link type="primary" v-if="scope.row.noticeStatus != 3" @click="handleEdit(scope.row)" v-hasPermi="['tenant:notice:edit']">{{ t('') }}</el-button>
<el-button link type="primary" @click="handleView(scope.row)" v-hasPermi="['tenant:notice:query']">{{ t('') }}</el-button>
</template>
</el-table-column>

View File

@ -7,7 +7,7 @@
<custom-select style="width: 230px;" v-model="queryParams.timeZone" :options="optionsTimeZone" :placeholder="t('时区')"></custom-select>
</el-form-item>
<el-form-item prop="currencyDefault">
<checkbox-select style="width: 230px;" collapse-tags collapse-tags-tooltip v-model="queryParams.currencyDefault" :options="currencySelectArr" :placeholder="t('币种')"></checkbox-select>
<checkbox-select style="width: 230px;" collapse-tags collapse-tags-tooltip v-model="queryParams.currencyDefault" filterable :options="currencySelectArr" :placeholder="t('币种')"></checkbox-select>
</el-form-item>
</template>
<template #right>

View File

@ -6,7 +6,7 @@
<custom-select style="width: 230px;" v-model="queryParams.timeZone" :options="optionsTimeZone" :placeholder="t('时区')"></custom-select>
</el-form-item>
<el-form-item prop="currencyDefault">
<checkbox-select style="width: 230px;" collapse-tags collapse-tags-tooltip v-model="queryParams.currencyDefault" :options="currencySelectArr" :placeholder="t('币种')"></checkbox-select>
<checkbox-select style="width: 230px;" collapse-tags collapse-tags-tooltip v-model="queryParams.currencyDefault" filterable :options="currencySelectArr" :placeholder="t('币种')"></checkbox-select>
</el-form-item>
<!-- <select-input-form ref="selectInputFormRef" :queryParamsList="queryParamsList" :queryParams="queryParams"
@handleQuery="handleQuery">

View File

@ -6,7 +6,7 @@
<custom-select style="width: 230px;" v-model="queryParams.timeZone" :options="optionsTimeZone" :placeholder="t('时区')"></custom-select>
</el-form-item>
<el-form-item prop="currencyDefault">
<checkbox-select style="width: 230px;" collapse-tags collapse-tags-tooltip v-model="queryParams.currencyDefault" :options="currencySelectArr" :placeholder="t('币种')"></checkbox-select>
<checkbox-select style="width: 230px;" collapse-tags collapse-tags-tooltip v-model="queryParams.currencyDefault" :options="currencySelectArr" filterable :placeholder="t('币种')"></checkbox-select>
</el-form-item>
<!-- <select-input-form ref="selectInputFormRef" :queryParamsList="queryParamsList" :queryParams="queryParams"
@handleQuery="handleQuery">

View File

@ -6,7 +6,7 @@
<custom-select style="width: 230px;" v-model="queryParams.timeZone" :options="optionsTimeZone" :placeholder="t('时区')"></custom-select>
</el-form-item>
<el-form-item prop="currencyDefault">
<checkbox-select style="width: 230px;" collapse-tags collapse-tags-tooltip v-model="queryParams.currencyDefault" :options="currencySelectArr" :placeholder="t('币种')"></checkbox-select>
<checkbox-select style="width: 230px;" collapse-tags collapse-tags-tooltip v-model="queryParams.currencyDefault" :options="currencySelectArr" filterable :placeholder="t('币种')"></checkbox-select>
</el-form-item>
<!-- <select-input-form ref="selectInputFormRef" :queryParamsList="queryParamsList" :queryParams="queryParams"
@handleQuery="handleQuery">

View File

@ -6,7 +6,7 @@
<custom-select style="width: 230px;" v-model="queryParams.timeZone" :options="optionsTimeZone" :placeholder="t('时区')"></custom-select>
</el-form-item>
<el-form-item prop="currencyDefault">
<checkbox-select style="width: 230px;" collapse-tags collapse-tags-tooltip v-model="queryParams.currencyDefault" :options="currencySelectArr" :placeholder="t('币种')"></checkbox-select>
<checkbox-select style="width: 230px;" collapse-tags collapse-tags-tooltip v-model="queryParams.currencyDefault" :options="currencySelectArr" filterable :placeholder="t('币种')"></checkbox-select>
</el-form-item>
<!-- <select-input-form ref="selectInputFormRef" :queryParamsList="queryParamsList" :queryParams="queryParams"
@handleQuery="handleQuery">

View File

@ -49,7 +49,12 @@
{{ row.unsettledBill }}
</template>
</el-table-column>
<el-table-column :label="t('透支比例(%)')" width="180" align="center" prop="unsettledBill" />
<el-table-column :label="t('透支比例(%)')" width="180" align="center" prop="overdraftRate" >
<template #default="{row}">
<span v-if=" row.overdraftRate !=null">{{ row.overdraftRate }}%</span>
<span v-else>--</span>
</template>
</el-table-column>
<el-table-column :label="t('昨日在线充值(U)')" align="center" width="160" prop="yesterdayCharge"
:show-overflow-tooltip="true">
<template #default="scope">{{ scope.row.yesterdayCharge||'--' }}</template>

View File

@ -49,7 +49,12 @@
{{ row.unsettledBill }}
</template>
</el-table-column>
<el-table-column :label="t('透支比例(%)')" width="180" align="center" prop="unsettledBill" />
<el-table-column :label="t('透支比例(%)')" width="180" align="center" prop="overdraftRate" >
<template #default="{row}">
<span v-if=" row.overdraftRate !=null">{{ row.overdraftRate }}%</span>
<span v-else>--</span>
</template>
</el-table-column>
<el-table-column :label="t('昨日在线充值(U)')" align="center" width="160" prop="yesterdayCharge"
:show-overflow-tooltip="true">
<template #default="scope">{{ scope.row.yesterdayCharge||'--' }}</template>

View File

@ -49,7 +49,12 @@
{{ row.unsettledBill }}
</template>
</el-table-column>
<el-table-column :label="t('透支比例(%)')" width="180" align="center" prop="unsettledBill" />
<el-table-column :label="t('透支比例(%)')" width="180" align="center" prop="overdraftRate" >
<template #default="{row}">
<span v-if=" row.overdraftRate !=null">{{ row.overdraftRate }}%</span>
<span v-else>--</span>
</template>
</el-table-column>
<el-table-column :label="t('昨日在线充值(U)')" align="center" width="160" prop="yesterdayCharge"
:show-overflow-tooltip="true">
<template #default="scope">{{ scope.row.yesterdayCharge||'--' }}</template>

View File

@ -49,7 +49,12 @@
{{ row.unsettledBill }}
</template>
</el-table-column>
<el-table-column :label="t('透支比例(%)')" width="180" align="center" prop="unsettledBill" />
<el-table-column :label="t('透支比例(%)')" width="180" align="center" prop="overdraftRate" >
<template #default="{row}">
<span v-if=" row.overdraftRate !=null">{{ row.overdraftRate }}%</span>
<span v-else>--</span>
</template>
</el-table-column>
<el-table-column :label="t('昨日在线充值(U)')" align="center" width="160" prop="yesterdayCharge"
:show-overflow-tooltip="true">
<template #default="scope">{{ scope.row.yesterdayCharge||'--' }}</template>

View File

@ -49,7 +49,12 @@
{{ row.unsettledBill }}
</template>
</el-table-column>
<el-table-column :label="t('透支比例(%)')" width="180" align="center" prop="unsettledBill" />
<el-table-column :label="t('透支比例(%)')" width="180" align="center" prop="overdraftRate" >
<template #default="{row}">
<span v-if=" row.overdraftRate !=null">{{ row.overdraftRate }}%</span>
<span v-else>--</span>
</template>
</el-table-column>
<el-table-column :label="t('昨日在线充值(U)')" align="center" width="160" prop="yesterdayCharge"
:show-overflow-tooltip="true">
<template #default="scope">{{ scope.row.yesterdayCharge||'--' }}</template>

View File

@ -53,7 +53,12 @@
{{ row.unsettledBill }}
</template>
</el-table-column>
<el-table-column :label="t('透支比例(%)')" width="180" align="center" prop="overdraftRate" />
<el-table-column :label="t('透支比例(%)')" width="180" align="center" prop="overdraftRate" >
<template #default="{row}">
<span v-if=" row.overdraftRate !=null">{{ row.overdraftRate }}%</span>
<span v-else>--</span>
</template>
</el-table-column>
<el-table-column :label="t('昨日在线充值(U)')" align="center" width="160" prop="yesterdayCharge"
:show-overflow-tooltip="true">
<template #default="scope">{{ scope.row.yesterdayCharge||'--' }}</template>

View File

@ -60,7 +60,7 @@
:placeholder="t('请输入二级域名')"
>
<template #append>
<el-select v-if="lodings" v-model="formAll.domainSupplierId" :placeholder="t('请选择')" style="width: 115px">
<el-select v-if="lodings" v-model="formAll.domainSupplierId" :placeholder="t('请选择')" style="width: 200px">
<el-option v-for="(item,index) in domainSupplierIdArr" :label="item.label" :value="item.value" />
</el-select>
</template>
@ -137,13 +137,13 @@
</el-form-item>
<h3 style="font-weight: 700;">{{ t('站点收费标准') }}</h3>
<el-form-item :label="t('开站费(U)')" >
{{ formAll.openCost }}
<NumberInput v-model="formAll.openCost" :digit="2" :placeholder="t('请输入开站费')"></NumberInput>
</el-form-item>
<el-form-item :label="t('站点押金(U)')" >
{{ formAll.depositCost }}
<NumberInput v-model="formAll.depositCost" :digit="2" :placeholder="t('请输入站点押金')"></NumberInput>
</el-form-item>
<el-form-item :label="t('站点维护费(U)')" >
{{ formAll.maintanceCost }}
<NumberInput v-model="formAll.maintanceCost" :digit="2" :placeholder="t('请输入站点维护费')"></NumberInput>
</el-form-item>
<el-form-item :label="t('站点额度')" prop="creditQuotaType">
<div style="width: 100%;">
@ -154,7 +154,7 @@
<!-- <div style="width: 100%;"> <el-input style="width: 550px;" v-model="formAll.name" disabled placeholder="请输入确认安全码"></el-input></div> -->
</el-form-item>
<el-form-item :label="t('自动额度最小值')" prop="creditQuota">
<div style="width: 100%;"> <el-input style="width: 550px;" v-model="formAll.creditQuota" placeholder="请输入"></el-input></div>
<div style="width: 100%;"><NumberInput v-model="formAll.creditQuota" :digit="2" :placeholder="t('请输入')"></NumberInput></div>
</el-form-item>
<el-form-item :label="t('备注')">
<el-input
@ -186,15 +186,16 @@ import IconTips from "@/components/IconTips"; // 小图标提示
import CheckboxSelect from "@/components/CheckboxSelect"; //
import CustomSelect from "@/components/CustomSelect"; //
import {addSite,getSiteInfo,getMaterialGroupSelect,getDomainSelect,getSiteJdbcSelect} from "@/api/siteManagement";
import NumberInput from "@/components/NumberInput";
// import { updateGame } from "@/api/game/game";
import { nextTick, onMounted, ref } from "vue"; //
import { getLocalStorage } from "@/utils/auth";
const fileHost = getLocalStorage('fileUrl') || ''; // host
const langList = getLocalStorage('langSelect')?.map(item => {
const langList = getLocalStorage('langSelect')?.filter(v => v.langType == 1 && v.langStatus)?.map(item => {
return {
...item,
label: item.name,
label: `${item.name}(${item.langDisplay})`,
value: item.id
};
}); //
@ -307,6 +308,7 @@ const getClientSkin = (val) => {
value: item22.id
}
}) || [];
formAll.clientSkin = '';
lodings.value = false;
nextTick(() => {
lodings.value = true;
@ -359,7 +361,7 @@ const changeLangPattern = () => {
let arr = [];
formAll.langPattern.map(item => {
let langListname = langList.find(item1 => item1.value == item);
arr.push({ value: item, label: `${langListname.label}(${langListname.langDisplay})` });
arr.push({ value: item, label: `${langListname.name}(${langListname.langDisplay})` });
})
langListarr.value =arr;

View File

@ -26,8 +26,14 @@
</el-table-column>
<el-table-column :label="t('状态')" align="center" min-width="120" prop="quota">
<template #default="{ row }">
<el-button v-if="row.status == 1" @click="handleEnable(row)" type="primary">{{t('')}}</el-button>
<el-button v-if="row.status == 0" @click="handleDisable(row)" type="primary">{{t('')}}</el-button>
<el-switch v-model="row.status" :active-value="1" :inactive-value="0"
:active-text="t('启用')"
:inactive-text="t('停用')"
:before-change="switchBeforeChange"
@click="handleDisable(row, 'status')"
inline-prompt/>
<!-- <el-button v-if="row.status == 1" @click="handleEnable(row)" type="primary">{{t('')}}</el-button>
<el-button v-if="row.status == 0" @click="handleDisable(row)" type="primary">{{t('')}}</el-button> -->
</template>
</el-table-column>
<el-table-column :label="t('操作时间')" align="center" min-width="120" prop="currencyCode">
@ -50,7 +56,7 @@
<el-button @click="closeDialog">{{ t(' ') }}</el-button>
</div>
</template>
<el-dialog :title="addStatus == 'add'?t('新增租户'):t('修改租户')" align-center v-model="showDialogTenant" width="700px" append-to-body>
<el-dialog v-if="showDialogTenant" :title="addStatus == 'add'?t('新增租户'):t('修改租户')" align-center v-model="showDialogTenant" width="700px" append-to-body>
<el-form ref="formRef" :model="formAll" :rules="rules" label-width="150px" class="site-form">
<el-form-item label="租户KEY" prop="tenantKey">
@ -136,6 +142,9 @@ const rules = reactive({
})
const tenantList = ref([]);
const switchBeforeChange = () => {
return false
}
const getSiteBindApiGameInfos = () => {
getSiteBindApiGameInfo({
siteId: props.modifyDate.id
@ -155,6 +164,10 @@ const addStatus = ref('add')
const handleAdd = () => {
addStatus.value = 'add';
showDialogTenant.value = true;
formAll.siteId = props.modifyDate.id;
formAll.tenantKey = '';
formAll.secretKey = '';
formAll.currencyCode = '';
}
const handleEdit = (row) => {
@ -175,10 +188,10 @@ const handleDelect = (row) => {
}).catch(() => {})
}
//
const handleDisable = (row) => {
const handleDisable = (row,type) => {
proxy.$modal.confirm(proxy.t('确认是否停用?')).then(() => {
postSiteStopApiGameInfo({siteId:formAll.siteId,id:row.id}).then(() => {
proxy.$modal.msgSuccess(proxy.t('停用成功'));
postSiteStopApiGameInfo({siteId:formAll.siteId,id:row.id,status:row.status == 1 ? 0 : 1}).then(() => {
proxy.$modal.msgSuccess(proxy.t(`${row.status == 1 ? '停用' : '启用'}成功`));
getSiteBindApiGameInfos();
})
}).catch(() => {})

View File

@ -17,7 +17,7 @@
<el-select v-model="formAll.wallet" placeholder="请选择充值类型">
<el-option label="用户钱包" value="BALANCE" />
<el-option label="透支额度" value="OVERDRAW_BALANCE" />
<el-option label="游戏钱包" value="GAME" />
<!-- <el-option label="游戏钱包" value="GAME" /> -->
</el-select>
</el-form-item>
<el-form-item label="备注" prop="remark">

View File

@ -2,7 +2,7 @@
<table-search-card :model="queryParams" @getList="getList" @handleQuery="handleQuery" @resetQuery="resetQuery">
<template #left>
<el-form-item prop="timeType">
<el-select v-model="queryParams.timeType" :placeholder="t('请选择')" clearable style="width: 150px;">
<el-select v-model="queryParams.timeType" :placeholder="t('请选择')" style="width: 150px;">
<el-option :label="t('操作时间')" :value="1" />
<el-option :label="t('注销时间')" :value="2" />
</el-select>
@ -63,8 +63,8 @@
主站点
</template>
</el-table-column> -->
<el-table-column :label="t('站点ID')" align="center" width="120" prop="id" :show-overflow-tooltip="true" />
<el-table-column :label="t('站点名称')" align="center" width="150" prop="siteName" :show-overflow-tooltip="true" />
<el-table-column :label="t('站点ID')" align="center" width="120" prop="id" fixed="left"/>
<el-table-column :label="t('站点名称')" align="center" width="150" prop="siteName" fixed="left" />
<!-- <el-table-column :label="t('持有人')" width="100" align="center" prop="platformCode" /> -->
<el-table-column :label="t('对接商务')" width="100" align="center" prop="gameType" >
<template #default="{row}">
@ -126,7 +126,7 @@
<template #default="scope">
<!-- <el-button link type="primary" @click="handleView(scope.row)" v-hasPermi="['agent:tenant:view']">{{ t('') }}</el-button>
<el-button link type="primary" @click="handleView(scope.row)" v-hasPermi="['agent:tenant:view']">{{ t('') }}</el-button> -->
<el-button link type="primary" @click="handleLogin(scope.row)" >{{ t('租户平台') }}</el-button>
<el-button link type="primary" v-if="scope.row.status == 1" @click="handleLogin(scope.row)" >{{ t('租户平台') }}</el-button>
<el-button link type="primary" @click="handleView(scope.row)" v-hasPermi="['agent:tenant:view']">{{ t('') }}</el-button>
<el-button link type="primary" @click="handleOpenQuota(scope.row)" v-hasPermi="['agent:tenant:view']">{{ t('') }}</el-button>
<el-button link type="primary" @click="handleOpenBind(scope.row)" v-hasPermi="['agent:tenant:view']">{{ t('') }}</el-button>
@ -166,6 +166,7 @@ import QuotaModification from './components/QuotaModification'
import { getLocalStorage } from "@/utils/auth";
import Crontab from '@/components/Crontab'
import { parseTime } from '@/utils/ruoyi'; //
import { onMounted } from "vue";
const router = useRouter();
const { proxy } = getCurrentInstance();
const { ff_tenant_type, ff_tenant_status } = proxy.useDict("ff_tenant_type", "ff_tenant_status");
@ -207,6 +208,7 @@ const data = reactive({
queryParams: {
pageNum: 1,
pageSize: 10,
timeType:1,
orderByColumn:'createTime',
isAsc:'desc',
tenantKey: "",
@ -381,7 +383,9 @@ function submitForm() {
});
}
getList();
onMounted(() => {
getList();
});
// getsuperCommonCurrencySelect();
// getsuperCommonPlatformTypeSelect();
</script>

View File

@ -2,7 +2,7 @@
<table-search-card :model="queryParams" @getList="getList" @handleQuery="handleQuery" @resetQuery="resetQuery">
<template #left>
<el-form-item prop="timeType">
<el-select v-model="queryParams.timeType" :placeholder="t('请选择')" clearable style="width: 150px;">
<el-select v-model="queryParams.timeType" :placeholder="t('请选择')" style="width: 150px;">
<el-option :label="t('操作时间')" :value="1" />
<el-option :label="t('注销时间')" :value="2" />
</el-select>
@ -63,8 +63,8 @@
主站点
</template>
</el-table-column> -->
<el-table-column :label="t('站点ID')" align="center" width="120" prop="id" :show-overflow-tooltip="true" />
<el-table-column :label="t('站点名称')" align="center" width="150" prop="siteName" :show-overflow-tooltip="true" />
<el-table-column :label="t('站点ID')" align="center" width="120" prop="id" fixed="left"/>
<el-table-column :label="t('站点名称')" align="center" width="150" prop="siteName" fixed="left" />
<!-- <el-table-column :label="t('持有人')" width="100" align="center" prop="platformCode" /> -->
<el-table-column :label="t('对接商务')" width="100" align="center" prop="gameType" >
<template #default="{row}">
@ -196,9 +196,10 @@ const data = reactive({
form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
orderByColumn:'createTime',
isAsc:'desc',
pageSize: 10,
timeType:1,
orderByColumn:'createTime',
isAsc:'desc',
tenantKey: "",
},
rules: {
@ -349,7 +350,9 @@ if (valid) {
});
}
getList();
onMounted(() => {
getList();
});
// getsuperCommonCurrencySelect();
// getsuperCommonPlatformTypeSelect();
</script>

View File

@ -2,7 +2,7 @@
<table-search-card :model="queryParams" @getList="getList" @handleQuery="handleQuery" @resetQuery="resetQuery">
<template #left>
<el-form-item prop="timeType">
<el-select v-model="queryParams.timeType" :placeholder="t('请选择')" clearable style="width: 150px;">
<el-select v-model="queryParams.timeType" :placeholder="t('请选择')" style="width: 150px;">
<el-option :label="t('操作时间')" :value="1" />
<el-option :label="t('注销时间')" :value="2" />
</el-select>
@ -63,8 +63,8 @@
主站点
</template>
</el-table-column> -->
<el-table-column :label="t('站点ID')" align="center" width="120" prop="id" :show-overflow-tooltip="true" />
<el-table-column :label="t('站点名称')" align="center" width="150" prop="siteName" :show-overflow-tooltip="true" />
<el-table-column :label="t('站点ID')" align="center" width="120" prop="id" fixed="left"/>
<el-table-column :label="t('站点名称')" align="center" width="150" prop="siteName" fixed="left" />
<!-- <el-table-column :label="t('持有人')" width="100" align="center" prop="platformCode" /> -->
<el-table-column :label="t('对接商务')" width="100" align="center" prop="gameType" >
<template #default="{row}">
@ -197,10 +197,11 @@ form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
timeType:1,
orderByColumn:'createTime',
isAsc:'desc',
status:1,
tenantKey: "",
tenantKey: "",
},
rules: {
account: [{ required: true, message: proxy.t('商户账号不能为空'), trigger: "blur" }],
@ -350,7 +351,9 @@ if (valid) {
});
}
getList();
onMounted(() => {
getList();
});
// getsuperCommonCurrencySelect();
// getsuperCommonPlatformTypeSelect();
</script>

View File

@ -2,7 +2,7 @@
<table-search-card :model="queryParams" @getList="getList" @handleQuery="handleQuery" @resetQuery="resetQuery">
<template #left>
<el-form-item prop="timeType">
<el-select v-model="queryParams.timeType" :placeholder="t('请选择')" clearable style="width: 150px;">
<el-select v-model="queryParams.timeType" :placeholder="t('请选择')" style="width: 150px;">
<el-option :label="t('操作时间')" :value="1" />
<el-option :label="t('注销时间')" :value="2" />
</el-select>
@ -63,8 +63,8 @@
主站点
</template>
</el-table-column> -->
<el-table-column :label="t('站点ID')" align="center" width="120" prop="id" :show-overflow-tooltip="true" />
<el-table-column :label="t('站点名称')" align="center" width="150" prop="siteName" :show-overflow-tooltip="true" />
<el-table-column :label="t('站点ID')" align="center" width="120" prop="id" fixed="left"/>
<el-table-column :label="t('站点名称')" align="center" width="150" prop="siteName" fixed="left" />
<!-- <el-table-column :label="t('持有人')" width="100" align="center" prop="platformCode" /> -->
<el-table-column :label="t('对接商务')" width="100" align="center" prop="gameType" >
<template #default="{row}">
@ -197,6 +197,7 @@ form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
timeType:1,
orderByColumn:'createTime',
status:0,
isAsc:'desc',
@ -350,7 +351,9 @@ if (valid) {
});
}
getList();
onMounted(() => {
getList();
});
// getsuperCommonCurrencySelect();
// getsuperCommonPlatformTypeSelect();
</script>

View File

@ -2,7 +2,7 @@
<table-search-card :model="queryParams" @getList="getList" @handleQuery="handleQuery" @resetQuery="resetQuery">
<template #left>
<el-form-item prop="timeType">
<el-select v-model="queryParams.timeType" :placeholder="t('请选择')" clearable style="width: 150px;">
<el-select v-model="queryParams.timeType" :placeholder="t('请选择')" style="width: 150px;">
<el-option :label="t('操作时间')" :value="1" />
<el-option :label="t('注销时间')" :value="2" />
</el-select>
@ -63,8 +63,8 @@
主站点
</template>
</el-table-column> -->
<el-table-column :label="t('站点ID')" align="center" width="120" prop="id" :show-overflow-tooltip="true" />
<el-table-column :label="t('站点名称')" align="center" width="150" prop="siteName" :show-overflow-tooltip="true" />
<el-table-column :label="t('站点ID')" align="center" width="120" prop="id" fixed="left"/>
<el-table-column :label="t('站点名称')" align="center" width="150" prop="siteName" fixed="left" />
<!-- <el-table-column :label="t('持有人')" width="100" align="center" prop="platformCode" /> -->
<el-table-column :label="t('对接商务')" width="100" align="center" prop="gameType" >
<template #default="{row}">
@ -199,6 +199,7 @@ form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
timeType:1,
orderByColumn:'createTime',
isAsc:'desc',
status:3,
@ -352,7 +353,9 @@ if (valid) {
});
}
getList();
onMounted(() => {
getList();
});
// getsuperCommonCurrencySelect();
// getsuperCommonPlatformTypeSelect();
</script>

View File

@ -2,7 +2,7 @@
<table-search-card :model="queryParams" @getList="getList" @handleQuery="handleQuery" @resetQuery="resetQuery">
<template #left>
<el-form-item prop="timeType">
<el-select v-model="queryParams.timeType" :placeholder="t('请选择')" clearable style="width: 150px;">
<el-select v-model="queryParams.timeType" :placeholder="t('请选择')" style="width: 150px;">
<el-option :label="t('操作时间')" :value="1" />
<el-option :label="t('注销时间')" :value="2" />
</el-select>
@ -63,8 +63,8 @@
主站点
</template>
</el-table-column> -->
<el-table-column :label="t('站点ID')" align="center" width="120" prop="id" :show-overflow-tooltip="true" />
<el-table-column :label="t('站点名称')" align="center" width="150" prop="siteName" :show-overflow-tooltip="true" />
<el-table-column :label="t('站点ID')" align="center" width="120" prop="id" fixed="left"/>
<el-table-column :label="t('站点名称')" align="center" width="150" prop="siteName" fixed="left" />
<!-- <el-table-column :label="t('持有人')" width="100" align="center" prop="platformCode" /> -->
<el-table-column :label="t('对接商务')" width="100" align="center" prop="gameType" >
<template #default="{row}">
@ -197,6 +197,7 @@ form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
timeType:1,
orderByColumn:'createTime',
isAsc:'desc',
status:2,
@ -350,7 +351,9 @@ if (valid) {
});
}
getList();
onMounted(() => {
getList();
});
// getsuperCommonCurrencySelect();
// getsuperCommonPlatformTypeSelect();
</script>

View File

@ -2,7 +2,7 @@
<table-search-card :model="queryParams" @getList="getList" @handleQuery="handleQuery" @resetQuery="resetQuery">
<template #left>
<el-form-item prop="timeType">
<el-select v-model="queryParams.timeType" :placeholder="t('请选择')" clearable style="width: 150px;">
<el-select v-model="queryParams.timeType" :placeholder="t('请选择')" style="width: 150px;">
<el-option :label="t('操作时间')" :value="1" />
<el-option :label="t('注销时间')" :value="2" />
</el-select>
@ -63,8 +63,8 @@
主站点
</template>
</el-table-column> -->
<el-table-column :label="t('站点ID')" align="center" width="120" prop="id" :show-overflow-tooltip="true" />
<el-table-column :label="t('站点名称')" align="center" width="150" prop="siteName" :show-overflow-tooltip="true" />
<el-table-column :label="t('站点ID')" align="center" width="120" prop="id" fixed="left"/>
<el-table-column :label="t('站点名称')" align="center" width="150" prop="siteName" fixed="left" />
<!-- <el-table-column :label="t('持有人')" width="100" align="center" prop="platformCode" /> -->
<el-table-column :label="t('对接商务')" width="100" align="center" prop="gameType" >
<template #default="{row}">
@ -197,6 +197,7 @@ form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
timeType:1,
orderByColumn:'createTime',
isAsc:'desc',
tenantKey: "",
@ -349,7 +350,9 @@ if (valid) {
});
}
getList();
onMounted(() => {
getList();
});
// getsuperCommonCurrencySelect();
// getsuperCommonPlatformTypeSelect();
</script>

View File

@ -114,7 +114,7 @@
<div class="" style="margin-top: 30px;">
<div>{{ t('历史记录') }}</div>
<div class="">
<p v-for="(item,index) in tenantQuotaMonthHistoryLogs">{{ item.createTime }},{{ t('') }}
<p v-for="(item,index) in tenantQuotaMonthHistoryLogs">{{ formatTime( item.updateTime||item.createTime) }},{{ t('') }}
<span style="font-weight:700">{{ item.updateBy }}</span>
{{ t('变更,账单状态更改为') }}
<span style="font-weight:700">

View File

@ -16,7 +16,7 @@
@handleQuery="handleQuery">
</select-input-form>
<el-form-item prop="currencyType">
<custom-select style="width: 130px;" collapse-tags collapse-tags-tooltip v-model="queryParams.currencyType" :options="currencySelectArr" :placeholder="t('币种')"></custom-select>
<custom-select style="width: 130px;" collapse-tags collapse-tags-tooltip filterable v-model="queryParams.currencyType" :options="currencySelectArr" :placeholder="t('币种')"></custom-select>
</el-form-item>
</template>
<template #right>

View File

@ -117,11 +117,8 @@
try {
loading.value = true;
await passwordForm.value.validate();
let objForm = {
newPassword:form.value.newPassword
}
// API
updateUserPassword(objForm).then(response => {
updateUserPassword(form.value.newPassword).then(response => {
ElMessage.success('密码修改成功3秒后自动跳转');

View File

@ -233,8 +233,8 @@
</span>
</template>
<el-radio-group v-model="form.isCache">
<el-radio value="0">缓存</el-radio>
<el-radio value="1">不缓存</el-radio>
<el-radio :value="0">缓存</el-radio>
<el-radio :value="1">不缓存</el-radio>
</el-radio-group>
</el-form-item>
</el-col>

View File

@ -31,8 +31,7 @@
<template #default="{ row }">
<div v-if="row.sysUsers.length > 0">
<span v-for="(item, index) in row.sysUsers.slice(0, 5)" :key="item.userId" @click="handleUserListClick(row)" style="color: rgb(64, 158, 255);cursor: pointer;">
{{ item.userName }}
<span v-if="index < Math.min(5, row.sysUsers.length) - 1">,</span>
{{ item.userName }}<span v-if="index < Math.min(5, row.sysUsers.length) - 1">,</span>
</span>
<span v-if="row.sysUsers.length > 5"> ...</span>
</div>

View File

@ -7,7 +7,7 @@
</template>
<el-form :model="formGoogle" :rules="rulesGoogle" ref="googleRef" label-width="130px">
<el-form-item label="Google验证码" prop="googleCode">
<el-input v-model="formGoogle.googleCode" placeholder="请输入您的Google验证码" maxlength="6" />
<CodeInput v-model="formGoogle.googleCode" placeholder="请输入您的Google验证码" maxlength="6" />
</el-form-item>
</el-form>
<template #footer>
@ -22,6 +22,7 @@
</template>
<script setup>
import { nextTick, ref } from "vue";
import CodeInput from "@/components/CodeInput";
const { proxy } = getCurrentInstance()
const emits = defineEmits(['submit', 'update:show']) //
const props = defineProps({ //

View File

@ -27,7 +27,7 @@ export default defineConfig(({ mode, command }) => {
proxy: {
'/dev-api': {
// target: 'http://192.168.50.139:9080',
target: 'http://192.168.50.233:8081',
target: 'http://192.168.50.234:8081',
// target: 'http://192.168.50.178:8080',
// target: 'http://192.168.50.11:8081',
changeOrigin: true,
@ -36,7 +36,7 @@ export default defineConfig(({ mode, command }) => {
},
// proxy: {
// '/ff-api': {
// target: 'https://superapi.pgbet188.net', // 线上接口地址
// target: 'https://osssuper.kk9game.com', // 线上接口地址
// changeOrigin: true, // 是否允许跨域
// pathRewrite: {
// '^/ff-api': '' // 如果你需要去掉前缀,例如将 /api/xxx 替换为 /xxx