fix:1,优化

main
YuanJian 2025-08-26 10:54:01 +08:00
parent 98510bd781
commit e94808f564
51 changed files with 3478 additions and 612 deletions

BIN
dist.rar

Binary file not shown.

53
src/api/bank.js 100644
View File

@ -0,0 +1,53 @@
import request from '@/utils/request'
// 查询银行管理列表
export function listBank(query) {
return request({
url: '/operation/bank/list',
method: 'get',
params: query
})
}
// 查询银行管理详细
export function getBank(id) {
return request({
url: '/operation/bank/' + id,
method: 'get'
})
}
// 新增银行管理
export function addBank(data) {
return request({
url: '/operation/bank',
method: 'post',
data: data
})
}
// 修改银行管理
export function updateBank(data) {
return request({
url: '/operation/bank',
method: 'put',
data: data
})
}
// 删除银行管理
export function delBank(id) {
return request({
url: '/operation/bank/' + id,
method: 'delete'
})
}
// 修改银行状态
export function changeBankStatus(data) {
return request({
url: '/operation/bank/changeStatus',
method: 'put',
data: data
})
}

View File

@ -1,71 +1,120 @@
import request from '@/utils/request'
// 登录方法
export function login(username, password, code, uuid, loginType) {
const data = {
username,
password,
code,
uuid,
loginType,
}
return request({
url: '/login',
headers: {
isToken: false,
repeatSubmit: false
},
method: 'post',
data: data
})
}
export function bindGoogleCode(data) {
return request({
url: '/bindGoogleCode',
headers: {
isToken: false,
repeatSubmit: false
},
method: 'post',
data: data
})
export function login(username, password, code, uuid,loginDomain) {
const data = {
username,
password,
code,
uuid,
loginDomain
}
return request({
url: '/login',
headers: {
isToken: false,
repeatSubmit: false
},
method: 'post',
data: data
})
}
// 注册方法
export function register(data) {
return request({
url: '/register',
headers: {
isToken: false
},
method: 'post',
data: data
})
return request({
url: '/register',
headers: {
isToken: false
},
method: 'post',
data: data
})
}
// 获取用户详细信息
export function getInfo() {
return request({
url: '/getInfo',
method: 'get'
})
return request({
url: '/getInfo',
method: 'get'
})
}
// 获取全局字典
export function getDict() {
return request({
url: '/system/dict/data/allList',
method: 'get'
})
}
// 退出方法
export function logout() {
return request({
url: '/logout',
method: 'post'
})
return request({
url: '/logout',
headers: {
repeatSubmit: false
},
method: 'post'
})
}
// 检查是否绑定
export function googleBinding(data) {
return request({
url: '/google/binding',
method: 'post',
headers: {
repeatSubmit: false
},
data: data
})
}
// 获得两步验证二维码
export function getTwoStepVerificationQRCode(data) {
return request({
url: '/google/getTwoStepVerificationQRCode',
method: 'post',
headers: {
repeatSubmit: false,
Authorization: 'Bearer ' + data.token
},
})
}
// 执行谷歌两步验证绑定
export function bindingTwoFactorValidate(data,token) {
return request({
url: '/google/bindingTwoFactorValidate',
method: 'post',
headers: {
repeatSubmit: false,
Authorization: 'Bearer ' + token
},
data:data
})
}
// 验证谷歌两步验证码的接口
export function validateGoogleTwoFactor(data,token) {
return request({
url: '/google/validateGoogleTwoFactor',
method: 'post',
headers: {
repeatSubmit: false,
Authorization: 'Bearer ' + token
},
data:data
})
}
// 获取验证码
export function getCodeImg() {
return request({
url: '/captchaImage',
headers: {
isToken: false
},
method: 'get',
timeout: 20000
})
return request({
url: '/captchaImage',
headers: {
isToken: false
},
method: 'get',
timeout: 20000
})
}

View File

@ -0,0 +1,401 @@
import request from '@/utils/request'
// 查询所有会员列表
export function listMember(query) {
return request({
url: '/member/member/list',
method: 'get',
params: query
})
}
//在线人数
export function getOnlineNumber(query) {
return request({
url: '/member/member/getOnlineNumber',
method: 'get',
params: query
})
}
//提现大类
export function getWithdrawWayParentList(query) {
return request({
url: '/member/memberAccount/withdrawWayParentList',
method: 'get',
params: query
})
}
// 查询所有会员详细
export function getMember(id) {
return request({
url: '/member/member/' + id,
method: 'get'
})
}
// 新增所有会员
export function addMember(data) {
return request({
url: '/member/member',
method: 'post',
data: data
})
}
// 修改所有会员
export function updateMember(data) {
return request({
url: '/member/member',
method: 'put',
data: data
})
}
// 查看会员是否存在
export function getUserByMemberAccount(query) {
return request({
url: 'member/member/getUserByMemberAccount',
method: 'get',
params: query
})
}
// 删除所有会员
export function delMember(id) {
return request({
url: '/member/member/' + id,
method: 'delete'
})
}
// 批量修改状态
export function editMemberStatus(data) {
return request({
url: '/member/member/editMemberStatus',
method: 'put',
data: data
})
}
// 批量修改备注
export function editMemberRemark(data) {
return request({
url: '/member/member/editMemberRemark',
method: 'put',
data: data
})
}
// 批量修改登录密码
export function editMemberPass(data) {
return request({
url: '/member/member/editMemberPass',
method: 'put',
data: data
})
}
// 根据条件修改会员状态
export function editMemberStatusByCondition(data) {
return request({
url: '/member/member/editMemberStatusByCondition',
method: 'put',
data: data
})
}
// 根据条件修改会员状态
export function editMemberStatusByConditionForRelation(data) {
return request({
url: '/member/member/editMemberStatusByConditionForRelation',
method: 'put',
data: data
})
}
// 根据条件修改会员状态
export function editMemberIdCard(data) {
return request({
url: 'member/member/editMember',
method: 'put',
data: data
})
}
export function editMemberPassByConditionForRelation(data) {
return request({
url: '/member/member/editMemberPassByConditionForRelation',
method: 'put',
data: data
})
}
export function editMemberRemarkByConditionForRelation(data) {
return request({
url: '/member/member/editMemberRemarkByConditionForRelation',
method: 'put',
data: data
})
}
// 根据条件修改会员密码
export function editMemberPassByCondition(data) {
return request({
url: '/member/member/editMemberPassByCondition',
method: 'put',
data: data
})
}
// 根据条件修改会员备注
export function editMemberRemarkByCondition(data) {
return request({
url: '/member/member/editMemberRemarkByCondition',
method: 'put',
data: data
})
}
// 会员提现账号列表
export function accountList(query) {
return request({
url: '/member/memberAccount/list',
method: 'get',
params: query
})
}
// 会员提现账号删除
export function accountDelete(id) {
return request({
url: '/member/memberAccount/' + id,
method: 'delete'
})
}
// 会员提现账号状态修改
export function accountUpdateStatus(data) {
return request({
url: '/member/memberAccount/updateStatus',
method: 'put',
data
})
}
// 新增会员提现账户
export function accountAdd(data) {
return request({
url: '/member/memberAccount',
method: 'post',
data
})
}
// 修改会员提现账户
export function accountUpdate(data) {
return request({
url: '/member/memberAccount',
method: 'put',
data
})
}
// 提现大类列表
export function withdrawWayList(query) {
return request({
url: '/member/memberAccount/withdrawWayList',
method: 'get',
params: query
})
}
// 账户明细列表
export function accountDetailList(query) {
return request({
url: '/member/accountDetail/list',
method: 'get',
params: query
})
}
//修改会员状态
export function editMemberStatusNo(data) {
return request({
url: '/member/member/editMemberStatusAndRemark',
method: 'put',
data: data
})
}
//修改会员标签
export function editMemberLabelId(data) {
return request({
url: '/member/member/editMemberLabel',
method: 'put',
data: data
})
}
// //修改会员层级
export function editMemberLevelId(data) {
return request({
url: '/member/member/editMemberLevel',
method: 'put',
data: data
})
}
//修改会员密码
export function editMemberPassword(data) {
return request({
url: '/member/member/editMemberPassword',
method: 'put',
data: data
})
}
//修改会员提现密码
export function editMemberWithdrawPassword(data) {
return request({
url: '/member/member/editMemberWithdrawPassword',
method: 'put',
data: data
})
}
//修改会员真实姓名
export function editMemberRealName(data) {
return request({
url: '/member/member/editMemberRealName',
method: 'put',
data: data
})
}
//修改会员邮箱
export function editMemberEmail(data) {
return request({
url: '/member/member/editMemberEmail',
method: 'put',
data: data
})
}
//修改会员性别
export function editMemberSex(data) {
return request({
url: '/member/member/editMemberSex',
method: 'put',
data: data
})
}
//修改会员生日
export function editMemberBirthday(data) {
return request({
url: '/member/member/editMemberBirthday',
method: 'put',
data: data
})
}
//修改会员faceBook账号
export function editMemberFaceBookAccount(data) {
return request({
url: '/member/member/editMemberFaceBook',
method: 'put',
data: data
})
}
//修改会员phoneNumber账号
export function editMemberPhoneNumber(data) {
return request({
url: '/member/member/editMemberFaceBook',
method: 'put',
data: data
})
}
//修改会员lineAccount账号
export function editMemberLineAccount(data) {
return request({
url: '/member/member/editMemberFaceBook',
method: 'put',
data: data
})
}
//修改会员twitterAccount账号
export function editMemberTwitterAccount(data) {
return request({
url: '/member/member/editMemberFaceBook',
method: 'put',
data: data
})
}
//修改会员telegram账号
export function editMemberTelegramAccount(data) {
return request({
url: '/member/member/editMemberTelegram',
method: 'put',
data: data
})
}
//修改会员whatsapp账号
export function editMemberWhatsappAccount(data) {
return request({
url: '/member/member/editMemberWhatsapp',
method: 'put',
data: data
})
}
//修改会员zalo账号
export function editMemberZaloAccount(data) {
return request({
url: '/member/member/editMemberZalo',
method: 'put',
data: data
})
}
//修改会员备注
export function editMemberRemarkNo(data) {
return request({
url: '/member/member/editRemark',
method: 'put',
data: data
})
}
// 获取会员财务信息
export function getFinanceInfo(query) {
return request({
url: '/member/member/getFinanceInfo',
method: 'get',
params: query
})
}
//修改会员vip等级
export function editUserVip(data) {
return request({
url: '/member/member/editUserVip',
method: 'put',
data: data
})
}
// 关联账号
export function getRelationMember(query) {
return request({
url: '/member/member/getRelationMember',
method: 'get',
params: query
})
}
// 会员消息
export function getnoticeList(query) {
return request({
url: '/operation/notice/member/list',
method: 'get',
params: query
})
}

View File

@ -92,6 +92,16 @@ export function getTimeZone(query) {
data: data
})
}
//站点开启
export function postMaintenanceOpen(data) {
return request({
url: '/site/maintenance/open',
method: 'post',
data: data
})
}
//站点额度列表
export function getSiteQuotasList(query) {
return request({
@ -109,6 +119,28 @@ export function getSiteJdbcSelect(query) {
params: query
})
}
//站点额度修改
export function postSiteQuotaChange(data) {
return request({
url: '/site/quota/change',
method: 'post',
data: data
})
}
//绑定api租户
export function postSiteBindApiGame(data) {
return request({
url: '/site/bind/api/game',
method: 'post',
data: data
})
}
//登录方法
export function tenantLogin(data) {
return request({
url: '/tenant/login',
method: 'post',
data: data
})
}

View File

@ -0,0 +1,381 @@
import request from '@/utils/request'
// 提现列表
export function listWithdraw(query) {
return request({
url: '/member/withdraw/list',
method: 'get',
params: query
})
}
// 提现方式
export function withdrawWayList(query) {
return request({
url: '/member/withdraw/withdrawWayList',
method: 'get',
params: query
})
}
// 三方代付
export function withdrawChannelList(query) {
return request({
url: '/member/withdraw/withdrawChannelList',
method: 'get',
params: query
})
}
// 代付记录
export function behalfList(query) {
return request({
url: '/member/withdraw/behalfList',
method: 'get',
params: query
})
}
// 修改备注
export function updateRemark(data) {
return request({
url: '/member/withdraw/updateRemark',
method: 'put',
data: data
})
}
// 解锁上锁订单
export function updateLockStatus(data) {
return request({
url: '/member/withdraw/updateLockStatus',
method: 'put',
data: data
})
}
// 解锁上锁风控订单
export function updateRiskLockStatus(data) {
return request({
url: '/member/withdraw/updateRiskLockStatus',
method: 'put',
data: data
})
}
// 审核出款
export function behalfOrder(data) {
return request({
url: '/member/withdraw/behalfOrder',
method: 'put',
data: data
})
}
// 风控审核审核出款
export function riskAudit(data) {
return request({
url: 'member/withdraw/riskAudit',
method: 'put',
data: data
})
}
// 拒绝提现
export function refuseOrder(data) {
return request({
url: '/member/withdraw/refuseOrder',
method: 'put',
data: data
})
}
// 强制取消
export function cancelOrder(data) {
return request({
url: '/member/withdraw/cancelOrder',
method: 'put',
data: data
})
}
// 强制出款
export function forceOrder(data) {
return request({
url: '/member/withdraw/forceOrder',
method: 'put',
data: data
})
}
// 重新出款
export function againOrder(data) {
return request({
url: '/member/withdraw/againOrder',
method: 'put',
data: data
})
}
// 人工出款
export function artificialOrder(data) {
return request({
url: '/member/withdraw/artificialOrder',
method: 'put',
data: data
})
}
// 人工出款
export function failOrder(data) {
return request({
url: '/member/withdraw/failOrder',
method: 'put',
data: data
})
}
// 刷新状态
export function refreshOrder(data) {
return request({
url: '/member/withdraw/refreshOrder',
method: 'put',
data: data
})
}
// 用户账户余额信息
export function getUserBanlanceInfo(query) {
return request({
url: '/member/withdraw/getUserBanlanceInfo',
method: 'get',
params: query
})
}
// 用户提现账户列表
export function getWithdrawAccountList(query) {
return request({
url: '/member/withdraw/getWithdrawAccountList',
method: 'get',
params: query
})
}
// 获取提现手续费
export function getWithdrawOrderFee(data) {
return request({
url: '/member/withdraw/getWithdrawOrderFee',
method: 'post',
data
})
}
// 新增提现
export function withdrawSubmit(data) {
return request({
url: '/member/withdraw/withdrawSubmit',
method: 'post',
data
})
}
//提现设置列表
export function getWithdrawWayList(query) {
return request({
url: '/payment/withdrawWay/withdrawWayList',
method: 'get',
params: query
})
}
//是否允许绑定
export function putWithdrawSwitchBind(data) {
return request({
url: '/payment/withdrawWay/withdrawSwitchBind',
method: 'put',
data: data
})
}
//是否允许会员改删
export function putWithdrawSwitchMember(data) {
return request({
url: '/payment/withdrawWay/withdrawSwitchMember',
method: 'put',
data: data
})
}
//是否允许会员改删
export function putWithdrawSwitchDigital(data) {
return request({
url: '/payment/withdrawWay/withdrawSwitchDigital',
method: 'put',
data: data
})
}
//是否支持普通提现
export function putWithdrawSwitchNormal(data) {
return request({
url: '/payment/withdrawWay/withdrawSwitchNormal',
method: 'put',
data: data
})
}
//修改提现方式
export function putEditWithdrawWay(data) {
return request({
url: '/payment/withdrawWay/editWithdrawWay',
method: 'put',
data: data
})
}
//查询提现设置信息
export function getPaymentWithdrawSetting(query) {
return request({
url: '/payment/paymentWithdrawSetting',
method: 'get',
params: query
})
}
//修改提现设置
export function putPaymentWithdrawSetting(data) {
return request({
url: '/payment/paymentWithdrawSetting',
method: 'put',
data: data
})
}
//免审自动出款
export function getSetting(query) {
return request({
url: '/payment/paymentWithdrawAutoOut/getSetting',
method: 'get',
params: query
})
}
//修改提现设置
export function putSetting(data) {
return request({
url: '/payment/paymentWithdrawAutoOut/setting',
method: 'put',
data: data
})
}
//财务出款数量查询
export function getFinancePayOutCount(query) {
return request({
url: '/member/withdraw/getFinancePayOutCount',
method: 'get',
params: query
})
}
//获取各状态提现订单数量
export function getTypeCount(query) {
return request({
url: '/member/withdraw/getTypeCount',
method: 'get',
params: query
})
}
//第三方代付平台列表
export function getWithdrawChannelThirdList(query) {
return request({
url: '/payment/withdrawChannel/thirdList',
method: 'get',
params: query
})
}
//第三方代付列表
export function getWithdrawChannelList(query) {
return request({
url: '/payment/withdrawChannel/list',
method: 'get',
params: query
})
}
//三方代付详情
export function getWithdrawChannelInfo(id) {
return request({
url: '/payment/withdrawChannel/' + id,
method: 'get'
})
}
//三方代付启用停用
export function putWithdrawChannelEditStatus(data) {
return request({
url: '/payment/withdrawChannel/editStatus',
method: 'put',
data: data
})
}
// 新增三方代付
export function postWithdrawChannel(data) {
return request({
url: '/payment/withdrawChannel',
method: 'post',
data
})
}
//修改三方代付
export function putWithdrawChannel(data) {
return request({
url: '/payment/withdrawChannel',
method: 'put',
data: data
})
}
//删除第三方代付
export function deleteWithdrawChannel(id) {
return request({
url: '/payment/withdrawChannel/' + id,
method: 'delete'
})
}
//排序
export function getUpdateSort(data) {
return request({
url: '/payment/withdrawWay/updateSort',
method: 'post',
data
})
}
//排序
export function getWithdrawChannelUpdateSort(data) {
return request({
url: '/payment/withdrawChannel/updateSort',
method: 'post',
data
})
}
//代付列表
export function getPaymentWithdrawChannelStatistics(query) {
return request({
url: '/payment/withdrawChannel/statistics',
method: 'get',
params: query
})
}

View File

@ -16,7 +16,7 @@
<el-sub-menu v-else ref="subMenu" :index="resolvePath(item.path)" teleported>
<template v-if="item.meta" #title>
<div class="sub-menu-item">
<svg-icon :icon-class="item.meta && item.meta.icon"/>
<svg-icon v-if="item.meta.icon != 'log'" :icon-class="item.meta && item.meta.icon"/>
<span class="menu-title" :title="hasTitle(item.meta.title)">{{ item.meta.title }}</span>
</div>
</template>

View File

@ -41,6 +41,11 @@ router.beforeEach((to, from, next) => {
getCurrencySelect().then((resCurrency) => {
setLocalStorage('currencySelect', resCurrency.data);
})
useUserStore().getDict().then(res => {
setLocalStorage('dict', res.data);
})
let obj = {
materialTypes:7,
}

View File

@ -2,7 +2,7 @@ const useDictStore = defineStore(
'dict',
{
state: () => ({
dict: new Array()
dicts: {}
}),
actions: {
// 获取字典
@ -10,46 +10,13 @@ const useDictStore = defineStore(
if (_key == null && _key == "") {
return null;
}
try {
for (let i = 0; i < this.dict.length; i++) {
if (this.dict[i].key == _key) {
return this.dict[i].value;
}
}
} catch (e) {
return null;
}
return this.dicts[_key];
},
// 设置字典
setDict(_key, value) {
if (_key !== null && _key !== "") {
this.dict.push({
key: _key,
value: value
});
this.dicts[_key] = value;
}
},
// 删除字典
removeDict(_key) {
var bln = false;
try {
for (let i = 0; i < this.dict.length; i++) {
if (this.dict[i].key == _key) {
this.dict.splice(i, 1);
return true;
}
}
} catch (e) {
bln = false;
}
return bln;
},
// 清空字典
cleanDict() {
this.dict = new Array();
},
// 初始字典
initDict() {
}
}
})

View File

@ -1,4 +1,4 @@
import { login, logout, getInfo } from '@/api/login'
import { login, logout, getInfo,getDict } from '@/api/login'
import { getToken, setToken, removeToken } from '@/utils/auth'
import defAva from '@/assets/images/profile.jpg'
@ -25,10 +25,10 @@ const useUserStore = defineStore(
login(username, password, code, uuid, loginType).then(res => {
// console.log(res);
// setToken(res.token)
// this.token = res.token
resolve(res)
this.token = res.token
resolve(res.token)
}).catch(error => {
resolve(error)
reject(error)
})
})
},
@ -54,6 +54,16 @@ const useUserStore = defineStore(
})
})
},
// 获取字典
getDict() {
return new Promise((resolve, reject) => {
getDict().then(res => {
resolve(res)
}).catch(error => {
reject(error)
})
})
},
// 退出系统
logOut() {
return new Promise((resolve, reject) => {

View File

@ -1,24 +1,16 @@
import useDictStore from '@/store/modules/dict'
import { getDicts } from '@/api/system/dict/data'
import { getLocalStorage } from '@/utils/auth'
/**
* 获取字典数据
*/
export function useDict(...args) {
const res = ref({});
return (() => {
args.forEach((dictType, index) => {
res.value[dictType] = [];
const dicts = useDictStore().getDict(dictType);
if (dicts) {
res.value[dictType] = dicts;
} else {
getDicts(dictType).then(resp => {
res.value[dictType] = resp.data.map(p => ({ label: p.dictLabel, value: p.dictValue, elTagType: p.listClass, elTagClass: p.cssClass }))
useDictStore().setDict(dictType, res.value[dictType]);
})
}
})
return toRefs(res.value);
})()
const dictList = getLocalStorage('dict');
const needDict = ref({});
return (() => {
args.forEach((dictType, index) => {
needDict.value[dictType] = dictList.filter(item => item.dictType === dictType).map(p => ({ label: p.dictLabel, value: p.dictValue, elTagType: p.listClass, elTagClass: p.cssClass, remark: p.remark }));
})
return needDict.value;
})()
}

View File

@ -174,19 +174,28 @@ import { el } from 'element-plus/es/locales.mjs';
currencyType: {
type: String,
default: 'VND'
},
homeOperationReportResponses: {
type: Array,
default: () => []
},
tenantId: {
type: String,
default: ''
},
isLoading: {
type: Boolean,
default: false
}
})
const operateTimeType = ref('week'); //
const dataList = ref([]);
const getList = () => {
let obj = {
currencyCode:props.currencyType,
}
loadingList.value = true;
getHomeIndex(obj).then(res => {
dataList.value = props.homeOperationReportResponses;
nextTick(() => {
loadingList.value = false;
dataList.value = res.data.homeOperationReportResponses;
});
})
}
const activeName1 = ref('first');
@ -223,8 +232,10 @@ import { el } from 'element-plus/es/locales.mjs';
}
const operationList = ref([]);
const homeOperationLists = () => {
if (!props.isLoading)return;
loadings.value = false;
let obj = {
tenantId:props.tenantId,
operationType:tabPosition.value,
currencyCode:props.currencyType,
startDate:dateRange.value[0],

View File

@ -26,6 +26,14 @@
currencyType: {
type: String,
default: 'VND'
},
tenantId: {
type: String,
default: ''
},
isLoading: {
type: Boolean,
default: false
}
})
const platformCode = ref('');//code
@ -54,6 +62,7 @@
const numberList = ref([]);//
//
const getGamePlatformSelects = () => {
if (!props.isLoading)return;
loadings.value = false;
getDistinctShowSelect().then(res => {
platformCode.value = res.data[0];
@ -70,7 +79,9 @@
//
const homeNumberLists = () => {
if (!props.isLoading)return;
let obj = {
tenantId:props.tenantId,
platformCode: platformCode.value,
numberType: activeName.value,
currencyCode: props.currencyType

View File

@ -107,6 +107,14 @@ const { ff_registe_way, ff_verify_way, ff_member_status } = proxy.useDict('ff_re
currencyType: {
type: String,
default: 'VND'
},
tenantId:{
type: String,
default: ''
},
isLoading: {
type: Boolean,
default: false
}
})
const activeName = ref('1');
@ -122,7 +130,9 @@ const showUserInfo = (id) => {
}
const rankingList = ref([])
const homeRankingLists = (params) => {
if (!props.isLoading)return;
let obj = {
tenantId:props.tenantId,
currencyCode: props.currencyType,
rankingType:activeName.value,
}

View File

@ -0,0 +1,176 @@
<template>
<el-dialog :title="t('{}银行信息', addEditStatus === 'add' ? '新增' : '修改')" align-center v-model="isShowDialog" width="600px"
append-to-body @close="closeDialog('close')">
<el-form ref="formRef" :model="formData" :rules="rules" label-width="100px" v-loading="loading">
<el-form-item :label="t('币种:')" prop="currencyType">
<currency-select v-model="formData.currencyType" style="width: 100%;"></currency-select>
</el-form-item>
<el-form-item :label="t('银行名称')" prop="bankName">
<el-input v-model="formData.bankName" :placeholder="t('请输入银行名称')" />
</el-form-item>
<el-form-item :label="t('银行代码')" prop="bankCode">
<el-input v-model="formData.bankCode" :placeholder="t('请输入银行代码')" />
</el-form-item>
<el-form-item :label="t('银行图标')" prop="bankIcon">
<div class="upload-box">
<image-upload v-model="formData.bankIcon" :typeUpImg="24" :limit="1" :isShowTip="false"></image-upload>
<div class="upload-tips">
<div>{{ t('图标大小60*60') }}</div>
<div>{{ t('PNG或JPG格式') }}</div>
</div>
</div>
</el-form-item>
<el-form-item :label="t('启用状态')" prop="status">
<el-switch v-model="formData.status" active-value="0" inactive-value="1" />
</el-form-item>
<el-form-item :label="t('备注')" prop="remark">
<el-input v-model="formData.remark" type="textarea" :placeholder="t('请输入内容')" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button v-if="addEditStatus === 'add'" @click="resetForm">{{ t(' ') }}</el-button>
<el-button v-else @click="closeDialog('close')">{{ t(' ') }}</el-button>
<el-button type="primary" @click="submitForm" :loading="loadingButton">{{ t('确 定') }}</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import { getBank, addBank, updateBank } from "@/api/bank";
import ImageUpload from "@/components/ImageUpload";
const props = defineProps({
addEditStatus: {
type: String,
default: 'add'
},
id: {
type: [String, Number],
default: ''
}
});
const { proxy } = getCurrentInstance();
const emit = defineEmits(['closeDialog']);
const loading = ref(false);
const loadingButton = ref(false);
const oldForm = shallowRef({ });
const isShowDialog = ref(true); //
const formRef = ref();
const formData = reactive({ //
currencyType: null,
bankName: null,
bankCode: null,
bankIcon: null,
status: '1',
remark: null
});
//
const rules = reactive({
currencyType: [
{ required: true, message: proxy.t('币种不能为空'), trigger: 'change' }
],
bankName: [
{ required: true, message: proxy.t('银行名称不能为空'), trigger: 'blur' }
],
bankCode: [
{ required: true, message: proxy.t('银行代码不能为空'), trigger: 'blur' }
],
bankIcon: [
{ required: true, message: proxy.t('银行图标地址不能为空'), trigger: 'blur' }
]
});
//
if (props.addEditStatus === 'edit' && props.id) {
loading.value = true;
getBank(props.id).then(res => {
loading.value = false;
//
for (var key in formData) {
if (formData.hasOwnProperty(key)) formData[key] = res.data[key];
}
formData.id = res.data.id; // ID
setTimeout(() => {
let objForm = { ...formData }
oldForm.value = JSON.stringify(objForm);
}, 500);
});
}
//
const submitForm = () => {
formRef.value.validate(valid => {
if (valid) {
loadingButton.value = true;
if (props.addEditStatus === 'add') {
addBank(formData).then(res => {
loadingButton.value = false;
proxy.$modal.msgSuccess(proxy.t('新增成功!'));
closeDialog('add-edit');
}).catch(() => {
loadingButton.value = false;
});
} else if (props.addEditStatus === 'edit') {
if (JSON.stringify(formData) != oldForm.value) {
updateBank(formData).then(res => {
loadingButton.value = false;
proxy.$modal.msgSuccess(proxy.t('修改成功!'));
closeDialog('add-edit');
}).catch(() => {
loadingButton.value = false;
});
}else{
loadingButton.value = false;
closeDialog('close');
}
}
}
})
}
//
const resetForm = () => {
formRef.value.resetFields();
}
//
const closeDialog = (type) => {
emit('closeDialog',type);
}
</script>
<style scoped lang='scss'>
.upload-box {
height: 60px;
overflow: hidden;
.upload-tips {
color: #999;
font-size: 12px;
line-height: 1.5;
padding-left: 10px;
}
:deep(.el-upload-list) {
width: 60px;
height: 60px;
.el-upload,
.el-upload-list__item {
width: 60px;
height: 60px;
}
.el-upload-list__item {
margin: 0;
border: none;
}
}
}
</style>

View File

@ -0,0 +1,173 @@
<template>
<div class="app-container">
<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"
@change="handleQuery"></currency-select>
</el-form-item>
<el-form-item prop="bankName">
<el-input v-model="queryParams.bankName" :placeholder="t('请输入银行名称')" clearable @clear="handleQuery"
@keyup.enter="handleQuery" style="width: 220px;" />
</el-form-item>
<el-form-item prop="bankCode">
<el-input v-model="queryParams.bankCode" :placeholder="t('请输入银行代码')" clearable @clear="handleQuery"
@keyup.enter="handleQuery" style="width: 220px;" />
</el-form-item>
</template>
<template #right>
<el-button @click="handleAdd" type="primary" plain icon="Plus" v-hasPermi="['operation:bank:add']">{{
t('新增') }}</el-button>
</template>
</table-search-card>
<!-- 查询表格 -->
<el-table v-loading="loading" :data="bankList" 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" prop="currencyType" min-width="100" />
<el-table-column :label="t('银行名称')" align="center" prop="bankName" min-width="100" />
<el-table-column :label="t('银行代码')" align="center" prop="bankCode" min-width="100" />
<el-table-column :label="t('银行图标')" align="center" min-width="100">
<template #default="{ row }">
<el-image class="table-icon-image" :src="fileHost + row.bankIcon" fit="contain" />
</template>
</el-table-column>
<el-table-column :label="t('是否开启')" align="center" min-width="160">
<template #default="{ row }">
<el-switch v-model="row.status" active-value="0" inactive-value="1" :before-change="switchBeforeChange"
@click="changeStatus(row)" />
</template>
</el-table-column>
<el-table-column :label="t('备注')" align="center" min-width="100">
<template #default="{ row }">
{{ row.remark || '-' }}
</template>
</el-table-column>
<el-table-column :label="t('操作')" align="center" width="160">
<template #default="{ row }">
<el-button link type="primary" @click="handleUpdate(row)" v-hasPermi="['operation:bank:edit']">{{ t('')
}}</el-button>
<!-- <el-button link type="primary" @click="handleDelete(row)" v-hasPermi="['operation:bank:remove']">{{
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-edit-dialog :id="editDataId" :addEditStatus="addEditStatus" v-if="isShowDialog"
@closeDialog="closeDialog"></add-edit-dialog>
</div>
</template>
<script setup name="BankingRegulations">
import { listBank, delBank, changeBankStatus } from "@/api/bank";
import AddEditDialog from "./components/AddEditDialog.vue";
import CurrencySelect from '@/components/CurrencySelect'; //
import { getLocalStorage } from "@/utils/auth";
const { proxy } = getCurrentInstance();
const fileHost = getLocalStorage('fileUrl') || ''; // host
const bankList = ref([]);
const loading = ref(true);
const total = ref(0);
const queryParams = reactive({
pageNum: 1,
pageSize: 20,
currencyType: 'VND',
bankCode: null,
status: null
});
//
function getList() {
loading.value = true;
listBank(queryParams).then(res => {
bankList.value = res.rows;
total.value = res.total;
loading.value = false;
});
}
//
const addEditStatus = ref('add'), isShowDialog = ref(false), editDataId = ref('');
const handleAdd = () => {
isShowDialog.value = true;
addEditStatus.value = 'add';
}
//
const handleUpdate = (row) => {
editDataId.value = row.id;
isShowDialog.value = true;
addEditStatus.value = 'edit';
}
//
const closeDialog = (type) => {
switch (type) {
case 'add-edit': // -
addEditStatus.value = 'add'; //
isShowDialog.value = false;
//
getList();
break
case 'close': // -
addEditStatus.value = 'add'; //
isShowDialog.value = false;
break
}
}
//
const switchBeforeChange = () => {
return false;
}
//
const changeStatus = (row) => { // row.status: 0- 1-
proxy.$modal.confirm( proxy.t('确认{}“' + row.bankName + '”?', +row.status === 1 ? '启用' : '停用')).then(() => {
changeBankStatus({ id: row.id, status: +row.status === 1 ? 0 : 1 }).then(res => {
proxy.$modal.msgSuccess(proxy.t(row.bankName + ' {}成功!', +row.status === 1 ? '启用' : '停用'));
getList();
})
}).catch(() => { });
}
//
const handleDelete = (row) => {
proxy.$modal.confirm(proxy.t('确认删除“' + row.bankName + '”的数据?')).then(() => {
return delBank(row.id);
}).then(() => {
getList();
proxy.$modal.msgSuccess(proxy.t('删除成功!'));
}).catch(() => { });
}
//
const handleQuery = () => {
queryParams.pageNum = 1;
getList();
}
//
const resetQuery = () => {
handleQuery();
}
getList();
</script>
<style lang="scss" scoped>
.app-container{
height: 100%;
overflow-x: auto;
}
</style>

View File

@ -0,0 +1,52 @@
<template>
<div class="app-container">
<!-- <el-tabs v-model="activeName">
<el-tab-pane name="rateConfiguration" :label="t('汇率配置')"></el-tab-pane>
<el-tab-pane name="syncHistory" :label="t('同步历史记录')"></el-tab-pane>
<el-tab-pane name="bankManagement" :label="t('银行管理')"></el-tab-pane>
</el-tabs> -->
<!-- 列表组件 -->
<bank-management v-if="activeName == 'bankManagement'"></bank-management>
<!-- <div class="tabs-main-box">
<rate-configuration v-if="activeName == 'rateConfiguration'"></rate-configuration>
<sync-history v-if="activeName == 'syncHistory'"></sync-history>
</div> -->
<!-- 会员信息弹窗 -->
<!-- <user-info ref="userInfoRef"></user-info> -->
</div>
</template>
<!-- 稽核管理 -->
<script setup name="BankingRegulations">
import BankManagement from "./bankManagement"; //
import RateConfiguration from "./rateConfiguration"; //
import SyncHistory from "./syncHistory";
const activeName = ref('bankManagement'); //
const memberAccount = ref(''); //
//
onActivated(() => {
const routeParams = useRoute().query;
//
if (Object.keys(routeParams).length) {
activeName.value = routeParams.activeName || 'auditManage';
memberAccount.value = routeParams.memberAccount || '';
}
//
useRouter().replace({ query: {} });
});
//
const userInfoRef = ref(null);
const showUserInfo = (id) => {
userInfoRef.value.showModal(id);
}
</script>
<style scoped lang='scss'></style>

View File

@ -0,0 +1,161 @@
<template>
<div class="app-container">
<el-table class="c-table-main" ref="tableRef" v-loading="loading" row-key="id" :data="dataList" stripe border>
<el-table-column prop="currencyCode" :label="t('原币种')" align="center">
<template #default="{row}">
{{ row.currencyCode }}
</template>
</el-table-column>
<el-table-column prop="currencyCode" :label="t('基础币种')" align="center">
<template #default="{row}">
{{ row.currencyCode }}
</template>
</el-table-column>
<el-table-column prop="exchangeCurrencyCode" :label="t('兑换币种')" align="center">
<template #default="{row}">
{{ row.exchangeCurrencyCode }}
</template>
</el-table-column>
<el-table-column prop="exchangeRate" :label="t('站点汇率')" align="center">
<template #default="{row}">
{{row.exchangeRate}}
</template>
</el-table-column>
<el-table-column align="center" label-class-name="c-table-column-center12">
<template #header>
<div style="width: 100%;text-align: center;">汇率差设置</div>
<div style="width: 100%;text-align: center;color: #8b8b8b;font-weight: 400;">即比市场更高或更低的部分</div>
</template>
<el-table-column prop="exchangeRate" :label="t('单位')" label-class-name="c-table-column-center12" align="center">
<template #default="{row}">
<span v-if="row.differenceType == 1">{{ t('') }}</span>
<span v-if="row.differenceType == 2">{{ t('') }}</span>
</template>
</el-table-column>
<el-table-column prop="exchangeRate" :label="t('汇率差')" label-class-name="c-table-column-center12" align="center">
<template #default="{row}">
<span v-if="row.differenceType == 1">{{row.exchangeCurrencyCode}}+{{row.differenceValue}}%</span>
<span v-if="row.differenceType == 2">{{row.differenceValue}}</span>
</template>
</el-table-column>
</el-table-column>
<el-table-column prop="exchangeRate" label-class-name="c-table-column-center12" align="center">
<template #header>
<div style="width: 100%;text-align: center;">{{ t('生效汇率') }}</div>
<div style="width: 100%;text-align: center;color: #8b8b8b;font-weight: 400;">{{ t('(市场汇率 + 汇率差)') }}</div>
</template>
<template #default="{row}">
{{row.actualBalance}}
</template>
</el-table-column>
<el-table-column prop="exchangeRate" :label="t('操作')" align="center">
<template #default="{row}">
<!-- <el-button link type="primary" >{{
t('修改') }}</el-button> -->
--
</template>
</el-table-column>
</el-table>
</div>
</template>
<script setup name="BankingRegulations">
import { listBank, delBank, changeBankStatus } from "@/api/bank";
import { getLocalStorage } from "@/utils/auth";
import { getTenantExchangeSelect } from "@/api/system/siteInformation";
const { proxy } = getCurrentInstance();
const fileHost = getLocalStorage('fileUrl') || ''; // host
const bankList = ref([]);
const loading = ref(true);
const dataList = ref([]);
const total = ref(0);
const queryParams = reactive({
pageNum: 1,
pageSize: 20,
currencyType: null,
bankCode: null,
status: null
});
//
function getList() {
loading.value = true;
getTenantExchangeSelect({}).then(res => {
dataList.value = res.data;
loading.value = false;
})
}
//
const addEditStatus = ref('add'), isShowDialog = ref(false), editDataId = ref('');
const handleAdd = () => {
isShowDialog.value = true;
addEditStatus.value = 'add';
}
//
const handleUpdate = (row) => {
editDataId.value = row.id;
isShowDialog.value = true;
addEditStatus.value = 'edit';
}
//
const closeDialog = (type) => {
switch (type) {
case 'add-edit': // -
addEditStatus.value = 'add'; //
isShowDialog.value = false;
break
}
//
getList();
}
//
const switchBeforeChange = () => {
return false;
}
//
const changeStatus = (row) => { // row.status: 0- 1-
proxy.$modal.confirm( proxy.t('确认{}“' + row.bankName + '”?', +row.status === 1 ? '启用' : '停用')).then(() => {
changeBankStatus({ id: row.id, status: +row.status === 1 ? 0 : 1 }).then(res => {
proxy.$modal.msgSuccess(proxy.t(row.bankName + ' {}成功!', +row.status === 1 ? '启用' : '停用'));
getList();
})
}).catch(() => { });
}
//
const handleDelete = (row) => {
proxy.$modal.confirm(proxy.t('确认删除“' + row.bankName + '”的数据?')).then(() => {
return delBank(row.id);
}).then(() => {
getList();
proxy.$modal.msgSuccess(proxy.t('删除成功!'));
}).catch(() => { });
}
//
const handleQuery = () => {
queryParams.pageNum = 1;
getList();
}
//
const resetQuery = () => {
handleQuery();
}
getList();
</script>
<style lang="scss" scoped>
:deep(.c-table-column-center12){
background: #fbf4c4!important;
}
</style>

View File

@ -0,0 +1,93 @@
<template>
<div class="app-container">
研发中...
</div>
</template>
<script setup name="BankingRegulations">
import { listBank, delBank, changeBankStatus } from "@/api/payment/bank";
import { getLocalStorage } from "@/utils/auth";
const { proxy } = getCurrentInstance();
const fileHost = getLocalStorage('fileUrl') || ''; // host
const bankList = ref([]);
const loading = ref(true);
const total = ref(0);
const queryParams = reactive({
pageNum: 1,
pageSize: 20,
currencyType: null,
bankCode: null,
status: null
});
//
function getList() {
}
//
const addEditStatus = ref('add'), isShowDialog = ref(false), editDataId = ref('');
const handleAdd = () => {
isShowDialog.value = true;
addEditStatus.value = 'add';
}
//
const handleUpdate = (row) => {
editDataId.value = row.id;
isShowDialog.value = true;
addEditStatus.value = 'edit';
}
//
const closeDialog = (type) => {
switch (type) {
case 'add-edit': // -
addEditStatus.value = 'add'; //
isShowDialog.value = false;
break
}
//
getList();
}
//
const switchBeforeChange = () => {
return false;
}
//
const changeStatus = (row) => { // row.status: 0- 1-
proxy.$modal.confirm( proxy.t('确认{}“' + row.bankName + '”?', +row.status === 1 ? '启用' : '停用')).then(() => {
changeBankStatus({ id: row.id, status: +row.status === 1 ? 0 : 1 }).then(res => {
proxy.$modal.msgSuccess(proxy.t(row.bankName + ' {}成功!', +row.status === 1 ? '启用' : '停用'));
getList();
})
}).catch(() => { });
}
//
const handleDelete = (row) => {
proxy.$modal.confirm(proxy.t('确认删除“' + row.bankName + '”的数据?')).then(() => {
return delBank(row.id);
}).then(() => {
getList();
proxy.$modal.msgSuccess(proxy.t('删除成功!'));
}).catch(() => { });
}
//
const handleQuery = () => {
queryParams.pageNum = 1;
getList();
}
//
const resetQuery = () => {
handleQuery();
}
getList();
</script>

View File

@ -1,14 +1,14 @@
<template>
<table-search-card :model="queryParams" @getList="getList" @handleQuery="handleQuery" @resetQuery="resetQuery">
<template #left>
<select-input-form ref="selectInputFormRef" :queryParamsList="queryParamsList" :queryParams="queryParams"
<select-input-form ref="selectInputFormRef" :width="[150, 170]" :queryParamsList="queryParamsList" :queryParams="queryParams"
@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>
</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>
<checkbox-select style="width: 230px;" collapse-tags collapse-tags-tooltip v-model="queryParams.supportedFeatures" :options="supportedFeaturesSelectArr" :placeholder="t('支持功能')"></checkbox-select>
</el-form-item>
</template>
<template #right>
@ -162,7 +162,7 @@ form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
currency:[],
currency:['VND'],
supportedFeatures:[],
searchType: 'thirdPartyName',
orderByColumn:'totalRechargeCount',
@ -198,6 +198,8 @@ getList();
/** 重置按钮操作 */
function resetQuery() {
proxy.resetForm("queryRef");
queryParams.value.currency = ['VND'];
handleQuery();
}
onMounted(() => {

View File

@ -1,14 +1,14 @@
<template>
<table-search-card :model="queryParams" @getList="getList" @handleQuery="handleQuery" @resetQuery="resetQuery">
<template #left>
<select-input-form ref="selectInputFormRef" :queryParamsList="queryParamsList" :queryParams="queryParams"
<select-input-form ref="selectInputFormRef" :width="[150, 170]" :queryParamsList="queryParamsList" :queryParams="queryParams"
@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>
</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>
<checkbox-select style="width: 230px;" collapse-tags collapse-tags-tooltip v-model="queryParams.supportedFeatures" :options="supportedFeaturesSelectArr" :placeholder="t('支持功能')"></checkbox-select>
</el-form-item>
</template>
<template #right>
@ -163,7 +163,7 @@ queryParams: {
pageNum: 1,
pageSize: 10,
thirdPartyStatus:0,
currency:[],
currency:['VND'],
supportedFeatures:[],
searchType: 'thirdPartyName',
orderByColumn:'totalRechargeCount',
@ -199,6 +199,7 @@ getList();
/** 重置按钮操作 */
function resetQuery() {
proxy.resetForm("queryRef");
queryParams.value.currency = ['VND'];
handleQuery();
}
onMounted(() => {

View File

@ -1,14 +1,14 @@
<template>
<table-search-card :model="queryParams" @getList="getList" @handleQuery="handleQuery" @resetQuery="resetQuery">
<template #left>
<select-input-form ref="selectInputFormRef" :queryParamsList="queryParamsList" :queryParams="queryParams"
<select-input-form ref="selectInputFormRef" :width="[150, 170]" :queryParamsList="queryParamsList" :queryParams="queryParams"
@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>
</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>
<checkbox-select style="width: 230px;" collapse-tags collapse-tags-tooltip v-model="queryParams.supportedFeatures" :options="supportedFeaturesSelectArr" :placeholder="t('支持功能')"></checkbox-select>
</el-form-item>
</template>
<template #right>
@ -163,7 +163,7 @@ queryParams: {
pageNum: 1,
pageSize: 10,
thirdPartyStatus:1,
currency:[],
currency:['VND'],
supportedFeatures:[],
searchType: 'thirdPartyName',
orderByColumn:'totalRechargeCount',
@ -199,6 +199,7 @@ getList();
/** 重置按钮操作 */
function resetQuery() {
proxy.resetForm("queryRef");
queryParams.value.currency = ['VND'];
handleQuery();
}
onMounted(() => {

View File

@ -6,7 +6,7 @@
</el-tabs>
<!-- 列表组件 -->
<div class="tabs-main-box">
<account-changes v-if="activeName == 'ThirdOthersPayment'"></account-changes>
<third-payment v-if="activeName == 'ThirdOthersPayment'"></third-payment>
<third-channel-list :typeOS="typeOS" :typeName="typeName" v-if="activeName === 'ThirdPartyPayment'"></third-channel-list>
</div>
</div>
@ -17,8 +17,9 @@
import BillingRecords from "./billingRecords/list.vue";
import AccountChanges from "./accountChanges/list.vue";
import DepositOrder from "./depositOrder/list.vue";
import thirdChannelList from "./thirdChannelList/list"
const activeName = ref('BillingRecords'); //
import ThirdChannelList from "./thirdChannelList/list"
import ThirdPayment from "./thirdPayment"
const activeName = ref('ThirdPartyPayment'); //
const memberAccount = ref(''); //
const typeOS = ref('1');
const typeName = ref('');
@ -27,7 +28,7 @@ onActivated(() => {
const routeParams = useRoute().query;
//
if (Object.keys(routeParams).length) {
activeName.value = routeParams.activeName || 'BillingRecords';
activeName.value = routeParams.activeName || 'ThirdPartyPayment';
memberAccount.value = routeParams.memberAccount || '';
}

View File

@ -0,0 +1,378 @@
<template>
<el-dialog :title="!isEdit ? t('新增代付商户') : t('修改代付商户')" v-model="isShowDialog" width="1300" append-to-body
@close="closeDialog">
<el-form ref="formRef" :model="formData" :rules="rules" label-width="150">
<el-row v-if="lodingShow" :span="24">
<el-col :span="10">
<el-form-item :label="t('代付币种')" prop="currencyType">
<currency-select style="width: 100%;" v-model="formData.currencyType"
@change="currencyTypeChange" :placeholder="t('请选择代付币种')"
:disabled="isEdit"></currency-select>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item :label="t('三方代付')" prop="merchCode">
<el-select style="width: 100%;" v-model="formData.merchCode" :placeholder="t('请选择第三方支付')"
@change="thirdChannelChange" :disabled="isEdit">
<el-option v-for="item in thirdChannelList" :key="item.code" :value="item.code"
:label="item.name"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item :label="t('三方代付平台名')" prop="channelName">
<el-input v-model="formData.channelName" :maxlength="50" :placeholder="t('请输入第三方支付平台名,最多50个字')" />
</el-form-item>
</el-col>
<el-col v-for="(item,index) in fieldConfigList" :key="index" :span="item.fieldCode =='merchantId' ?10 :20">
<el-form-item :label="t(item.fieldName)" :prop="item.mustFlag == 1?'tradeParams.'+item.fieldCode:''"
:rules="item.mustFlag == 1 ? [{ required: true, message: `请输入${item.fieldName}`, trigger: 'change' }] : []"
>
<el-input v-model="formData.tradeParams[item.fieldCode]" :placeholder="t('请输入'+item.fieldName)"/>
</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 v-if="lodings" :label="t('提现方式')" prop="wayIds">
<CheckboxSelect v-model="formData.wayIds" collapse-tags :options="withdrawWayParentList" />
</el-form-item>
</el-col>
<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="balanceQueryUrl">
<el-input v-model="formData.balanceQueryUrl" :maxlength="255" show-word-limit
:placeholder="t('请输入余额查询地址')" />
</el-form-item>
</el-col>
<el-col :span="20">
<el-form-item :label="t('代付限额')">
<div class="input-group">
<el-form-item prop="moneyMin" :rules="[{
required: true,
message: '请输入最小代付限额'
}, {
validator: (rule, value, callback) => {
if (value >= formData.moneyMax) {
return callback(new Error('最小金额应小于最大金额'))
} else {
return callback()
}
}
}]">
<number-input v-model="formData.moneyMin" :maxlength="16"
:placeholder="t('请输入最小通道单笔限额')" />
</el-form-item>
<span class="ml20 mr20">~</span>
<el-form-item prop="moneyMax" :rules="[{
required: true,
message: '请输入最大代付限额'
}, {
validator: (rule, value, callback) => {
if (value <= formData.moneyMin) {
return callback(new Error('最大金额应大于最小金额'))
} else {
return callback()
}
}
}]">
<number-input v-model="formData.moneyMax" :maxlength="16"
:placeholder="t('请输入最大通道单笔限额')" />
</el-form-item>
</div>
</el-form-item>
</el-col>
</el-row>
</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 * as recharge from "@/api/finance/recharge"
import { listThirdChannel } from "@/api/payment/thirdChannel";
import { getWithdrawChannelThirdList,postWithdrawChannel,putWithdrawChannel,getWithdrawChannelInfo } from "@/api/withdrawal";
import * as member from '@/api/member/member'
import BaseCheckbox from "@/components/BaseCheckbox"; //
import CheckboxSelect from "@/components/CheckboxSelect/index.vue";
import NumberInput from "@/components/NumberInput/index.vue"; //
import useInitDataStore from "@/store/modules/initData";
import { getCurrencyDisplay } from "@/utils/index";
import { nextTick } from 'vue';
const useInitData = useInitDataStore();
const { proxy } = getCurrentInstance();
const emits = defineEmits(['submit'])
//
const moreReceiveConfig = {
hasCheckAll: false,
filterValue: []
};
const isShowDialog = ref(false);
const loadingButton = ref(false);
const oldForm = shallowRef({ });
const formData = ref({
currencyType: useInitData.currencyCode,
merchCode: null,
merchName: null,
merchId: null,
merchKey: null,
payUrl: null,
wayIds: [],
payQueryUrl: null,
tradeParams:{
},
})
const rules = reactive({
currencyType: [
{ required: true, message: proxy.t('请选择通道币种'), trigger: 'change' }
],
merchCode: [
{ required: true, message: proxy.t('请选择第三方支付'), trigger: 'change' }
],
merchName: [
{ required: true, message: proxy.t('请输入第三方支付平台名,最多50个字'), trigger: 'change' }
],
wayIds: [
{ 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 getWithdrawChannelInfo(id).then(res => {
res.data.tradeParams = JSON.parse(res.data.tradeParams);
let dataObj ={
...res.data,
wayIds:res.data?.wayIds?.split(',')||[],
}
formData.value = dataObj;
getListThirdChannel().then(itemCLO => {
thirdChannelChange(res.data.merchCode);
const find = thirdChannelList.value.find(item => item.code === res.data.merchCode)
})
})
}
const submitForm = async () => {
//
const isFormValid = await proxy.$refs.formRef.validate()
// RechargeChannel
if (isFormValid) {
let _data = JSON.parse(JSON.stringify(formData.value));
_data = {
...formData.value,
merchId:formData.value.tradeParams.merchantId,
wayIds:formData.value.wayIds?.join(','),
channelName:formData.value.channelName||formData.value.merchName,
tradeParams:JSON.stringify(formData.value.tradeParams),
}
loadingButton.value = true;
if (isEdit.value) {
if (JSON.stringify(formData.value) != oldForm.value) {
putWithdrawChannel(_data).then(res => {
loadingButton.value = false;
proxy.$modal.msgSuccess(proxy.t("修改成功"));
closeDialog()
emits('submit')
}).catch(() => {
loadingButton.value = false;
})
}else{
loadingButton.value = false;
closeDialog()
}
} else {
postWithdrawChannel(_data).then(res => {
loadingButton.value = false;
proxy.$modal.msgSuccess(proxy.t("新增成功"));
closeDialog()
emits('submit')
}).catch(() => {
loadingButton.value = false;
})
}
} else {
// RechargeChannel
console.log('RechargeChannel 组件中的表单校验未通过');
}
}
//
const thirdChannelList = ref([])
const getListThirdChannel = (val) => {
return new Promise((resolve, reject) => {
const _params = {
page: 1,
limit: 1000,
currencyType: formData.value.currencyType
}
getWithdrawChannelThirdList(_params).then(res => {
let data = JSON.parse(res.data)
resolve(data);
thirdChannelList.value = data;
});
})
}
//
const lodingShow = ref(true);
const currencyTypeChange = () => {
fieldConfigList.value = [];
formData.value.channelName= null
formData.value.merchName = null
formData.value.merchId = null
formData.value.merchKey = null
formData.value.payQueryUrl = null
formData.value.payUrl = null
formData.value.merchCode = null
formData.value.balanceQueryUrl = null;
formData.value.moneyMin = null;
formData.value.moneyMax = null;
lodingShow.value = false;
nextTick(() => {
lodingShow.value = true;
getWithdrawWayParentLists();
})
}
// currencyType
// const currencySign = computed(() => {
// if (formData.value.currencyType) {
// getCurrencyDisplay(formData.value.currencyType, 'currencySign')
// }
// })
const currencySign = ref(null)
watch(() => formData.value.currencyType, (val) => {
getListThirdChannel(val)
currencySign.value = getCurrencyDisplay(val, 'currencySign')
}, { immediate: true })
const fieldConfigList = ref([])
const thirdChannelChange = (val) => {
const find = thirdChannelList.value.find(item => item.code === val)
const { merchName, merchId,code, merchKey, payQueryUrl, payUrl } = find
fieldConfigList.value = find.fieldConfigList
formData.value.merchCode = code
formData.value.merchName = find.name
formData.value.channelName = formData.value.channelName||find.name
formData.value.moneyMax = find.productList[0].limitMax
formData.value.moneyMin = find.productList[0].limitMin
formData.value.productCode = find.productList[0].productCode
formData.value.balanceQueryUrl = find.balanceUrl
formData.value.merchId = merchId
formData.value.payQueryUrl = payQueryUrl
formData.value.payUrl = payUrl
setTimeout(() => {
let objForm = formData.value;
oldForm.value = JSON.stringify(objForm);
}, 500);
}
const withdrawWayParentList = ref([])
const lodings = ref(true)
const getWithdrawWayParentLists = () => {
lodings.value = false;
member.withdrawWayList({}).then(res => {
let _data = [];
res.data.map((item)=>{
if(item.currencyType == formData.value.currencyType){
_data.push({ label: item.wayName, value: item.id });
}
});
withdrawWayParentList.value = _data;
lodings.value = true;
})
}
onMounted(() => {
getWithdrawWayParentLists();
})
defineExpose({ openDialog })
</script>
<style scoped lang="scss">
.input-group {
width: 100%;
display: flex;
align-items: center;
gap: 10px;
}
.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,283 @@
<!-- 三方代付 -->
<template>
<table-search-card :model="queryParams" @getList="getList" :leftSpan="20" :rightSpan="4"
@handleQuery="handleQuery('search')" @resetQuery="resetQuery">
<template #left>
<select-input-form @handleQuery="handleQuery" :queryParamsList="queryParamsList"
v-model:queryParams="queryParams" :width="[120, 260]"></select-input-form>
<!-- <el-form-item prop="wayId">
<custom-select v-model="queryParams.wayId" v-if="lodingShows" :options="withdrawalArr" :placeholder="t('提现方式')" @change="handleQuery"></custom-select>
</el-form-item> -->
<!-- <el-form-item prop="currencyType">
<custom-select v-model="queryParams.currencyType" :options="stateArr" :placeholder="t('状态')" @change="handleQuery"></custom-select>
</el-form-item> -->
<!-- <el-form-item prop="currencyType">
<custom-select v-model="queryParams.currencyType" :options="paymentTypeArr" :placeholder="t('代付类型')" @change="handleQuery"></custom-select>
</el-form-item> -->
<el-form-item prop="currencyType">
<currency-select @change="handleQuery" v-model="queryParams.currencyType" :hasDefault="true"
style="width: 120px;"></currency-select>
</el-form-item>
</template>
<template #right>
<el-button type="success" plain icon="Plus" @click="handleAdd"
v-hasPermi="['payment:withdrawChannel:add']">{{
t('新增商户') }}</el-button>
</template>
</table-search-card>
<!-- 数据列表 -->
<el-table class="c-table-main" v-if="!loading" v-loading="loading" stripe border :data="dataList">
<table-drag-sort v-model:tableList="dataList" @dragEnd="dragEnd"
v-hasPermi="['member:memberEmailSmtpConfig:edit']"></table-drag-sort>
<el-table-column :label="t('三方代付平台')" prop="channelName" min-width="160" align="center"></el-table-column>
<el-table-column :label="t('三方代付')" prop="merchName" align="center"></el-table-column>
<el-table-column :label="t('三方商户号')" prop="merchId" align="center"></el-table-column>
<el-table-column :label="t('提现方式')" prop="wayName" align="center">
<template #default="{ row }">
<span v-if="row.wayName">{{ row.wayName }}</span>
<span v-else>--</span>
<!-- {{getWithdrawalLabel(row.wayName)}} -->
</template>
</el-table-column>
<el-table-column :label="t('代付币种')" prop="currencyType" align="center"></el-table-column>
<el-table-column align="center" min-width="160">
<template #header>
<p class="quota-text">{{ t('最小限额') }}</p>
<p class="quota-text">{{ t('最大限额') }}</p>
</template>
<template #default="{ row }">
{{ moneyFormat(row.moneyMin, true) }}<br/>
{{ moneyFormat(row.moneyMax, true) }}
</template>
</el-table-column>
<el-table-column :label="t('备注')" prop="remark" align="center"></el-table-column>
<table-operation></table-operation>
<el-table-column :label="t('启/停用')" prop="name" align="center">
<template #default="{ row }">
<el-switch v-hasPermi="['payment:withdrawChannel:edit']" style="margin-right: 10px; --el-switch-on-color: #13ce66;" v-model="row.switchStatus"
:active-value="1" :inactive-value="0" :before-change="switchBeforeChange"
@click="noticeEditSystemKey(row)" />
</template>
</el-table-column>
<el-table-column align="center" :label="t('操作')" width="200">
<template #default="{ row }">
<el-button link type="primary" @click="opInfo(row, 'edit')"
v-hasPermi="['payment:withdrawChannel:edit']">{{
t('修改') }}</el-button>
<el-button link type="primary" @click="opInfo(row, 'delete')"
:disabled="row.status == 1 ? true : false"
v-hasPermi="['payment:withdrawChannel:remove']">{{
t('删除') }}</el-button>
</template>
</el-table-column>
</el-table>
<third-channel-add v-if="showLoding" ref="thirdChannelAddRef" @submit="handleQuery"></third-channel-add> <!-- 添加第三方渠道 -->
</template>
<script setup>
import { getWithdrawChannelList,putWithdrawChannelEditStatus,deleteWithdrawChannel,getWithdrawChannelThirdList,getWithdrawChannelUpdateSort } from "@/api/withdrawal";
import TableDragSort from '@/components/TableDragSort'; //
import IconTips from "@/components/IconTips"; //
import CustomSelect from '@/components/CustomSelect'; //
import ThirdChannelAdd from "./components/ThirdChannelAdd" //
import { getCurrencyDisplay, moneyFormat } from "@/utils";
import { ref } from "vue";
import { nextTick } from "vue";
import { set } from "nprogress";
import { id } from "element-plus/es/locales.mjs";
const { proxy } = getCurrentInstance();
const loading = ref(false); // loading
const withdrawalArr = ref([]);
const stateArr = ref([{
label: proxy.t('启用'),
value: 1
}, {
label: proxy.t('停用'),
value: 0
}]);
const paymentTypeArr = ref([{
label: proxy.t('手动'),
value: 1
}, {
label: proxy.t('自动'),
value: 2
}]);
//
const queryParamsList = ref([{
label: proxy.t('三方代付平台名'),
value: 'channelName',
inputConfig: { maxlength: '16' }
}]);
//
const queryParams = reactive({
pageNum: 1,
pageSize: 20,
searchType: 'channelName',
memberAccount: '',
memberId: '',
currencyType: 'CNY'
});
//
const dataInfo = ref({}), dataList = ref([]); //
const getList = () => {
loading.value = true;
getWithdrawChannelList(queryParams).then(res => {
const _data = res.rows;
dataList.value = _data.map((item) => {
let isTop = item.sort == 1 ? true : false;
return {
...item,
sortNo: item.sort, //
isTop: isTop, //
}
});
loading.value = false;
}).catch(() => {
loading.value = false;
});
}
//
const dragEnd = (row) => {
let Obj = {
id: row.id,
sort: row.sortNo
}
getWithdrawChannelUpdateSort(Obj).then(() => {
if (row.isTop) {
proxy.$modal.msgSuccess("置顶成功");
} else {
proxy.$modal.msgSuccess('更改排序成功');
}
getList();
});
}
const lodingShows = ref(true); //
const getWithdrawChannelThirdLists = () => {
lodingShows.value = false;
getWithdrawChannelThirdList({}).then(res => {
let _data = JSON.parse(res.data);
withdrawalArr.value = _data.map((item)=>{
return {
label:item.name,
value:item.id
}
});
lodingShows.value = true;
});
};
const showLoding = ref(true); //
//
const opInfo = (row, type) => {
switch (type) {
case 'edit':
showLoding.value = false;
nextTick(() => {
showLoding.value = true;
setTimeout(() => {
proxy.$refs['thirdChannelAddRef'].openDialog(row.id);
}, 10);
})
break
case 'delete':
proxy.$modal.confirm('确认删除该记录?').then(() => {
loading.value = true;
deleteWithdrawChannel(row.id).then(res => {
loading.value = false;
proxy.$modal.msgSuccess('删除成功!');
handleQuery();
}).catch(() => {
loading.value = false;
});
}).catch(() => { });
break
}
}
const switchBeforeChange = () => {
return false
}
const noticeEditSystemKey = (row) => {
proxy.$modal.confirm(proxy.t('确认此操作,是否继续?')).then(() => {
let obj = {
id:row.id,
switchStatus: row.switchStatus == 1 ? 0 : 1
}
return putWithdrawChannelEditStatus(obj);
}).then(() => {
getList()
proxy.$modal.msgSuccess(proxy.t('操作成功!'));
}).catch(() => { });
}
//
const refresh = (row) => {
const params = {
memberId: dataInfo.value.memberId,
currencyType: queryParams.currencyType,
refreshType: row.code
}
loading.value = true;
}
//
const handleQuery = (type) => {
queryParams.pageNum = 1;
getList();
}
//
const resetQuery = () => {
dataInfo.value = {};
dataList.value = [];
}
//
const isShowAddSubDialog = ref(false), opType = ref('');
/**
* 打开新增修改第三方弹窗
* @param row
*/
const handleAdd = (row) => {
showLoding.value = false;
nextTick(() => {
showLoding.value = true;
setTimeout(() => {
proxy.$refs['thirdChannelAddRef'].openDialog(row.merchName)
}, 10);
})
}
const openAddSubDialog = (type) => {
isShowAddSubDialog.value = true;
opType.value = type;
}
//
const closeDialog = (type) => {
isShowAddSubDialog.value = false;
if (type === 'submit') handleQuery();
}
//
onMounted(async() => {
await getWithdrawChannelThirdLists()
getList();
})
</script>
<style scoped lang='scss'>
.quota-text {
padding: 0;
margin: 0;
width: 100%;
text-align: right;
}
</style>

View File

@ -4,19 +4,21 @@
<div style="margin-bottom: 15px;">
<custom-select v-model="currencyType" :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" :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">
<dashboard-card v-if="loadings" :cardData="cardData" :currencyType="currencyType"></dashboard-card>
<dashboard-card v-if="loadings" :cardData="cardData" :currencyType="currencyType" :tenantId="tenantId"></dashboard-card>
</el-col>
<el-col :span="24" style="background:rgb(255,255,255);padding:16px 16px 0px;margin-bottom:32px">
<today-ranking-card v-if="loadings" :currencyType="currencyType"></today-ranking-card>
<today-ranking-card v-if="loadings" :isLoading="isLoading" :currencyType="currencyType" :tenantId="tenantId"></today-ranking-card>
</el-col>
<el-col :span="24" style="background:rgb(255,255,255);padding:16px 16px 0px;margin-bottom:32px">
<recently-card v-if="loadings" :currencyType="currencyType"></recently-card>
<recently-card v-if="loadings" :isLoading="isLoading" :currencyType="currencyType" :tenantId="tenantId"></recently-card>
</el-col>
<el-col :span="24" style="background:rgb(255,255,255);padding:16px 16px 0px;margin-bottom:32px">
<operation-card v-if="loadings" :currencyType="currencyType"></operation-card>
<operation-card v-if="loadings" :isLoading="isLoading" :currencyType="currencyType" :homeOperationReportResponses="homeOperationReportResponses" :tenantId="tenantId"></operation-card>
</el-col>
</el-row>
</div>
@ -31,8 +33,9 @@ import OperationCard from "./components/OperationCard";
import CurrencySelect from '@/components/CurrencySelect'; //
import CustomSelect from '@/components/CustomSelect';
import { getLocalStorage } from "@/utils/auth";
import {getSiteSelect} from "@/api/operations";
import {getHomeIndex} from "@/api/home";
import { ref } from "vue";
const currencyType = ref('VND');
const cardData = ref({});
const loadings = ref(true);
@ -41,17 +44,40 @@ const currencySelectArr = getLocalStorage('currencySelect')?.map(item => {
label: `${item.currencyName}(${item.currencyCode})`,
value: item.currencyCode
};
}); //
});
const siteSelect = ref([]);
const tenantId = ref('');
const homeOperationReportResponses = ref([]);
const isLoading = ref(false);
const getSiteSelects = () => {
getSiteSelect().then(response => {
siteSelect.value = response.data.map((item,index) => {
if (index == 0){
tenantId.value = item.tenantId;
}
return {
...item,
label: item.siteName,
value: item.tenantId,
}
});
getHomeIndexs();
})
}
const getHomeIndexs = async () => {
getHomeIndex({currencyCode:currencyType.value}).then((res) => {
getHomeIndex({currencyCode:currencyType.value,tenantId:tenantId.value}).then((res) => {
cardData.value = res.data.homePageResponse;
homeOperationReportResponses.value = res.data.homeOperationReportResponses;
isLoading.value = true;
loadings.value = false;
nextTick(() => {
loadings.value = true;
})
});
}
getHomeIndexs();
getSiteSelects();
</script>
<style lang="scss" scoped>

View File

@ -16,7 +16,7 @@
</div>
<div class="title-container">
<img style="width: 40px;" src="@/assets/logo/logo.png" />
<h3 class="title titleONG">站长后台管理系统</h3>
<h3 class="title titleONG">超管系统</h3>
</div>
<el-form-item prop="username" class="el-form-item-class">
<el-input v-model="loginForm.username" type="text" size="large" style="height: 52px;" class="backgr-class"
@ -41,23 +41,7 @@
</template>
</el-input>
</el-form-item>
<!-- <el-form-item v-if="captchaEnabled">
<el-input
v-model="loginForm.code"
size="large"
auto-complete="off"
placeholder="验证码"
style="width: 63%"
@keyup.enter="handleLogin"
>
<template #prefix><svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template>
</el-input>
<div class="login-code">
<img :src="codeUrl" @click="getCode" class="login-code-img"/>
</div>
</el-form-item> -->
<el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;"></el-checkbox>
<!-- <el-form-item prop="isShowEnabled" v-if="captchaEnabled">
<el-form-item prop="isShowEnabled" v-if="captchaEnabled">
<div class="geetest-container">
<div class="geetest-left botion_gradient_bar"></div>
<div v-if="loginForm.isShowEnabled" class="geetest-right botion_tip">
@ -69,29 +53,24 @@
</div>
</div>
<Vcode :show="isShow" @success="onSuccess" @close="onClose" />
</el-form-item> -->
</el-form-item>
<el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">{{ t('') }}</el-checkbox>
<el-form-item style="width:100%;">
<el-button
:loading="loading"
size="large"
type="primary"
style="width:100%;"
@click.prevent="handleLogin"
>
<span v-if="!loading"> </span>
<span v-else> ...</span>
<el-button :loading="loading" size="large" type="primary" style="width:100%;" @click.prevent="handleLogin">
<span v-if="!loading">{{ t(' ') }}</span>
<span v-else>{{ t(' ') }}...</span>
</el-button>
<div style="float: right;" v-if="register">
<router-link class="link-type" :to="'/register'">{{ t('立即注册') }}</router-link>
</div>
<p class="password-container">{{ t('忘记密码或两步验证,请联系内部管理员,若仍无法解决,可联系') }}<span>{{ t('技术支持') }}</span></p>
</el-form-item>
<p class="password-container">{{ t('忘记密码或两步验证,请联系内部管理员,若仍无法解决,可联系') }}<span>{{ t('技术支持') }}</span></p>
</el-form>
<el-dialog v-model="goodDialogVisible" style="margin-top: 45vh !important;" :title="t('温馨提示')" width="418" :before-close="handleClose">
<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="">
<el-input v-model="gooleCode" style="width: 90%" :placeholder="t('验证码只能为数字')" />
<number-input v-model="gooleCode" style="width: 90%" :placeholder="t('验证码只能为数字')" ></number-input>
</div>
<template #footer>
<div class="dialog-footer">
@ -102,7 +81,7 @@
</div>
</template>
</el-dialog>
<el-dialog v-model="goodDialogShow" :title="t('谷歌验证')" width="500" :before-close="authenticatorClose">
<el-dialog v-model="goodDialogShow" align-center :title="t('谷歌验证')" width="500" @close="" :before-close="authenticatorClose">
<div style="width: 100%;margin-bottom: 20px;text-align: center;">
<img style="width: 70%;" :src="imgCods"/>
</div>
@ -111,7 +90,7 @@
</div>
<el-form ref="authenticatorRef" :model="authenticatorForm" :rules="authenticatorRules">
<el-form-item label="谷歌验证码" prop="authenticatorCode">
<el-input v-model="authenticatorForm.authenticatorCode" :digit="2" style="width: 100%;height: 36px;" :placeholder="t('验证码只能为数字')" />
<number-input v-model="authenticatorForm.authenticatorCode" style="width: 100%;height: 36px;" :placeholder="t('验证码只能为数字')" ></number-input>
</el-form-item>
</el-form>
<div class="" style="margin-top: 20px;margin-bottom: 20px;">
@ -129,21 +108,20 @@
</el-dialog>
<!-- 底部 -->
<div class="el-login-footer">
<span>Copyright © 2018-2025</span>
<span>Copyright ©2024</span>
</div>
</div>
</template>
<script setup>
import { getCodeImg,bindGoogleCode } from "@/api/login";
import { getCodeImg,googleBinding,getTwoStepVerificationQRCode,bindingTwoFactorValidate,validateGoogleTwoFactor } from "@/api/login";
import Cookies from "js-cookie";
import { encrypt, decrypt } from "@/utils/jsencrypt";
import useUserStore from '@/store/modules/user';
import { i18nScope } from "@/languages"
import useUserStore from '@/store/modules/user'
import NumberInput from "@/components/NumberInput";
import Vcode from "vue3-puzzle-vcode";
import { i18nScope } from "@/languages"
import { setToken } from '@/utils/auth'
import {selectListLang} from '@/api/super/agent'
import Vcode from "vue3-puzzle-vcode";
const userStore = useUserStore()
const route = useRoute();
@ -151,8 +129,8 @@ const router = useRouter();
const { proxy } = getCurrentInstance();
const loginForm = ref({
username: "admin",
password: "aaa111",
username: "",
password: "",
rememberMe: false,
isShowEnabled: false,
code: "",
@ -160,8 +138,8 @@ const loginForm = ref({
});
const loginRules = {
username: [{ required: true, trigger: "blur", message: proxy.t('请输入您的账号') }],
password: [{ required: true, trigger: "blur", message: proxy.t('请输入您的密码') }],
username: [{ required: true, trigger: "change", message: proxy.t('请输入您的账号') }],
password: [{ required: true, trigger: "change", message: proxy.t('请输入您的密码') }],
code: [{ required: true, trigger: "change", message: proxy.t('请输入验证码') }],
isShowEnabled: [
{
@ -177,6 +155,7 @@ const loginRules = {
}
]
};
const codeUrl = ref("");
const loading = ref(false);
//
@ -184,6 +163,24 @@ const captchaEnabled = ref(false);
//
const register = ref(false);
const redirect = ref(undefined);
const goodDialogVisible = ref(false);
const goodDialogShow = ref(false);
const gooleCode = ref('666666');// google
const tokenCode = ref('');
watch(route, (newRoute) => {
redirect.value = newRoute.query && newRoute.query.redirect;
}, { immediate: true });
const handleClose = () => {
loading.value = false;
goodDialogVisible.value = false;
};
const authenticatorClose = () => {
loading.value = false;
goodDialogShow.value = false;
}
const authenticatorRef = ref(null);
const authenticatorForm = ref({
authenticatorCode: '',
randomSecretKey:'',
@ -191,28 +188,45 @@ const authenticatorForm = ref({
const imgCods = ref('');
const authenticatorRules = {
authenticatorCode: [
{ required: true, message: '请输入验证码', trigger: 'change' },
{ pattern: /^\d+$/, message: '验证码只能是数字', trigger: 'change' }
{ required: true, message: '请输入验证码', trigger: 'change' }
]
};
const isShow = ref(false)
const onShow = () => {
isShow.value = true
const loginGoogle = () => {
proxy.$refs.authenticatorRef.validate(valid => {
if (valid) {
bindingTwoFactorValidate({inputGoogleCode:authenticatorForm.value.authenticatorCode,randomSecretKey:authenticatorForm.value.randomSecretKey},tokenCode.value).then((res) => {
setToken(tokenCode.value);
localStorage.setItem('loginStatus', '1')// ()
router.push({
path: '/set-password',
query:null
});
})
}
})
}
const onClose = () => {
isShow.value = false
const goolesubmit = async() => {
if (gooleCode.value != '') {
validateGoogleTwoFactor({inputGoogleCode:gooleCode.value},tokenCode.value).then((res) => {
if (res.code == 200){
const query = route.query;
setToken(tokenCode.value);
const otherQueryParams = Object.keys(query).reduce((acc, cur) => {
if (cur !== "redirect") {
acc[cur] = query[cur];
}
return acc;
}, {});
router.push({ path: redirect.value || "/", query: otherQueryParams });
localStorage.setItem('loginStatus', '1')// ()
}
})
}
}
const onSuccess = () => {
loginForm.value.isShowEnabled = true
onClose()
//
const clickVisible = () => {
loading.value = false;
goodDialogVisible.value = false;
}
watch(route, (newRoute) => {
redirect.value = newRoute.query && newRoute.query.redirect;
}, { immediate: true });
function handleLogin() {
proxy.$refs.loginRef.validate(valid => {
if (valid) {
@ -228,53 +242,51 @@ function handleLogin() {
Cookies.remove("password");
Cookies.remove("rememberMe");
}
let formDatas = { ...loginForm.value };
delete formDatas.isShowEnabled;
// action
userStore.login(loginForm.value).then((res) => {
console.log(res)
if (res.code == '200'){
setToken(res.token);
router.push({
path: '/index',
query:null
});
return;
}
if (sessionStorage.getItem('TepdCode') == 500 && captchaEnabled.value == false){
captchaEnabled.value = true;
loading.value = false;
return;
}
if (res.data.code == '500'){
if (sessionStorage.getItem('TepdCode') == undefined){
captchaEnabled.value = true;
}
if (loginForm.value.isShowEnabled){
loginForm.value.isShowEnabled = false;
}
sessionStorage.setItem('TepdCode', 500);
loading.value = false;
}else{
// setToken(res.data.token);
if (res.data.bindStatus == true){
userStore.login(formDatas).then((result) => {
tokenCode.value = result;
googleBinding({username:loginForm.value.username}).then((res) => {
if (res.data == true){
goodDialogVisible.value = true;
}else if (res.data.bindStatus == false){
}else{
getTwoStepVerificationQRCode({token:result}).then((res) => {
imgCods.value = res.data.base64Url;
authenticatorForm.value.randomSecretKey = res.data.randomSecretKey;
})
goodDialogShow.value = true;
imgCods.value = res.data.bindQrCode;
authenticatorForm.value.randomSecretKey = res.data.randomSecretKey;
}
}
}).catch(() => {
});
}).catch((err) => {
loginForm.value.isShowEnabled = false;
captchaEnabled.value = true;
loading.value = false;
//
if (captchaEnabled.value) {
getCode();
}
});
}
});
}
const passwordVisible = ref(false)
const togglePassword = () => {
passwordVisible.value = !passwordVisible.value
}
const canLogin = ref(false)
const isShow = ref(false)
const onShow = () => {
isShow.value = true
}
const onClose = () => {
isShow.value = false
}
const onSuccess = () => {
loginForm.value.isShowEnabled = true
onClose()
//
}
function getCode() {
getCodeImg().then(res => {
captchaEnabled.value = res.captchaEnabled === undefined ? true : res.captchaEnabled;
@ -284,11 +296,7 @@ function getCode() {
}
});
}
const passwordVisible = ref(false)
const togglePassword = () => {
passwordVisible.value = !passwordVisible.value
}
function getCookie() {
const username = Cookies.get("username");
const password = Cookies.get("password");
@ -296,74 +304,13 @@ function getCookie() {
loginForm.value = {
username: username === undefined ? loginForm.value.username : username,
password: password === undefined ? loginForm.value.password : decrypt(password),
rememberMe: rememberMe === undefined ? false : Boolean(rememberMe),
rememberMe: rememberMe === undefined ? false : Boolean(rememberMe)
};
}
getCode();
// getCode();
getCookie();
const goodDialogVisible = ref(false);
const gooleCode = ref('');// google
const goodDialogShow = ref(false);
const handleClose = () => {
goodDialogVisible.value = false;
};
const clickVisible = () => {
loading.value = false;
goodDialogVisible.value = false;
}
const goolesubmit = async() => {
if (gooleCode.value != '') {
let objForm = {
...loginForm.value,
code:gooleCode.value,
}
userStore.login(objForm).then((res) => {
if (res.code == 200){
const query = route.query;
if (res.data.token){
setToken(res.data.token);
sessionStorage.removeItem('TepdCode');
const otherQueryParams = Object.keys(query).reduce((acc, cur) => {
if (cur !== "redirect") {
acc[cur] = query[cur];
}
return acc;
}, {});
router.push({ path: redirect.value || "/", query: otherQueryParams });
}
}
})
}else{
proxy.$message.error('请输入谷歌验证码');
}
}
const loginGoogle = () => {
proxy.$refs.authenticatorRef.validate(valid => {
if (valid) {
let objForm = {
...loginForm.value,
code:authenticatorForm.value.authenticatorCode,
randomSecretKey: authenticatorForm.value.randomSecretKey
}
bindGoogleCode(objForm).then((res) => {
if (res.data.token){
setToken(res.data.token);
sessionStorage.removeItem('TepdCode');
router.push({
path: '/',
query:null
});
}
})
}
})
}
const authenticatorClose = () => {
goodDialogShow.value = false;
loading.value = false;
}
const languagesSelect = ref('')
//
const languagesChange = async (countryLang) => {
@ -406,7 +353,7 @@ getLanguagesList()
background-size: cover;
}
.title {
margin: 0px auto 30px auto;
// margin: 0px auto 30px auto;
text-align: center;
color: #707070;
}
@ -446,7 +393,7 @@ getLanguagesList()
background: #39c522;
}
.login-form {
background-color: #fff;
background-color: #fff;
border-radius: 5px;
max-width: 100%;
padding: 65px 35px 10px;
@ -478,6 +425,12 @@ getLanguagesList()
vertical-align: middle;
}
}
.titleONG{
color: #666;
font-size: 20px;
font-weight: 700;
text-align: center;
}
.el-login-footer {
height: 40px;
line-height: 40px;
@ -494,6 +447,25 @@ getLanguagesList()
height: 40px;
padding-left: 12px;
}
.password-container {
color: #c5c5c5;
font-size: 13px;
line-height: 18px;
text-align: center;
width: 100%;
}
.password-container>span {
color: #18f;
cursor: pointer;
text-decoration: underline;
}
.title-container {
align-items: center;
display: flex;
justify-content: center;
margin-bottom: 20px;
position: relative;
}
.el-form-item-class {
background: rgba(0,0,0,.1);
border: 1px solid hsla(0,0%,100%,.1);
@ -533,33 +505,4 @@ select:-webkit-autofill:focus) {
background-color: transparent !important;
color: fieldtext !important;
}
.titleONG{
color: #666;
font-size: 20px;
font-weight: 700;
text-align: center;
margin:0;
}
.title-container {
align-items: center;
display: flex;
justify-content: center;
margin-bottom: 20px;
position: relative;
}
.password-container {
color: #c5c5c5;
font-size: 13px;
line-height: 18px;
text-align: center;
width: 100%;
}
.password-container>span {
color: #18f;
cursor: pointer;
text-decoration: underline;
}
:deep(.topMaing .el-dialog:not(.is-fullscreen)) {
margin-top: 44vh !important;
}
</style>

View File

@ -34,7 +34,8 @@
</el-table-column>
<el-table-column :label="t('站点名称(ID)')" align="center" min-width="150" >
<template #default="{row}">
{{ row.siteName || '--' }}
<span v-if="row.siteName">{{ `${row.siteName}(${row.siteId})`}}</span>
<span v-else>--</span>
</template>
</el-table-column>
@ -75,7 +76,8 @@
</el-table-column>
<el-table-column :label="t('操作')" align="center" width="160">
<template #default="scope">
<el-button link type="primary" @click="handleView(scope.row)" v-hasPermi="['tenant:notice:query']">{{ t('') }}</el-button>
--
<!-- <el-button link type="primary" @click="handleView(scope.row)" v-hasPermi="['tenant:notice:query']">{{ t('') }}</el-button> -->
</template>
</el-table-column>
</el-table>

View File

@ -2,8 +2,8 @@
<div class="app-container">
<table-search-card :model="queryParams" @getList="getList" @handleQuery="handleQuery" @resetQuery="resetQuery">
<template #left>
<el-form-item prop="siteId">
<custom-select style="width: 130px;" v-if="siteSelect.length > 0" collapse-tags collapse-tags-tooltip v-model="queryParams.siteId" :options="siteSelect" :placeholder="t('请选择')"></custom-select>
<el-form-item >
<custom-select style="width: 130px;" v-if="siteSelect.length > 0" collapse-tags collapse-tags-tooltip v-model="siteIdNo" :options="siteSelect" :placeholder="t('请选择')"></custom-select>
</el-form-item>
<el-form-item prop="timeType">
<el-select v-model="queryParams.timeType" :placeholder="t('请选择')" clearable style="width: 150px;">
@ -13,7 +13,7 @@
</el-form-item>
<table-search-date v-model:dateRange="dateRange" v-model:operateTimeType="operateTimeType"></table-search-date>
<select-input-form ref="selectInputFormRef" :queryParamsList="queryParamsList" :queryParams="queryParams"
<select-input-form ref="selectInputFormRef" :queryParamsList="queryParamsList" :queryParams="queryParams"
@handleQuery="handleQuery">
</select-input-form>
<el-form-item prop="currencyType">
@ -229,16 +229,9 @@ const queryParamsList = ref([{
value: 'company',
}
]);
const queryParamsList2 = ref([{
label: proxy.t('在线状态'),
value: 'accountStatus1',
inputType: 'select',
inputConfig: {
options: accountStatusArr,
}
},{
const queryParamsList2 = ref([{
label: proxy.t('账号状态'),
value: 'accountStatus2',
value: 'accountStatus',
inputType: 'select',
inputConfig: {
options: accountStatusArr,
@ -253,14 +246,14 @@ queryParams: {
pageNum: 1,
pageSize: 10,
timeType:1,
siteId:'',
orderByColumn:'createTime',
isAsc:'desc',
searchType:'account',
accountType:'accountStatus1',
accountType:'accountStatus',
},
});
const siteIdNo = ref('');
//
const tableRef = ref(),
isAllSelection = ref(false), //
@ -284,6 +277,7 @@ function getList() {
loading.value = true;
let params = {
...queryParams.value,
siteId: siteIdNo.value,
beginTime: finalTimestamp(dateRange.value[0]),
endTime: finalTimestamp(dateRange.value[1]),
}
@ -299,7 +293,7 @@ const getSiteSelects = () => {
getSiteSelect().then(response => {
siteSelect.value = response.data.map((item,index) => {
if (index == 0){
queryParams.value.siteId = item.id;
siteIdNo.value = item.id;
}
return {
...item,
@ -307,9 +301,10 @@ const getSiteSelects = () => {
value: item.id,
}
});
getList();
})
}
getSiteSelects();
const handleView = (row) => {
openView.value = true;
@ -328,9 +323,7 @@ handleQuery();
}
//
onMounted(() => {
setTimeout(() => {
getList();
}, 50);
getSiteSelects();
});
</script>

View File

@ -0,0 +1,356 @@
<template>
<div class="app-container">
<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('请选择币种类型')"
clearable></dict-select>
</el-form-item>
<el-form-item :label="t('币种名称')" prop="currencyName">
<el-input v-model="queryParams.currencyName" :placeholder="t('请输入币种名称')" clearable
@keyup.enter="handleQuery" />
</el-form-item>
</template>
<template #right>
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['operation:currency:add']">{{
t('新增') }}</el-button>
</template>
</table-search-card>
<el-table class="c-table-main" v-if="!loading" v-loading="loading" :data="currencyList" @selection-change="handleSelectionChange"
border stripe style="height: calc(100vh - 250px);">
<el-table-column type="selection" width="55" align="center" />
<table-drag-sort v-hasPermi="['operation:currency:edit']" v-model:tableList="currencyList" @dragEnd="dragEnd"></table-drag-sort>
<el-table-column :label="t('币种名称')" align="center" prop="currencyName" />
<el-table-column :label="t('币种国家')" align="center" prop="country" />
<el-table-column :label="t('国家/地区代码')" align="center" prop="countryCode" />
<el-table-column :label="t('币种代码')" align="center" prop="currencyCode" />
<el-table-column :label="t('币种图标')" align="center" prop="icon">
<template #default="{ row }">
<el-image class="icon-image" :src="fileUrl + row.icon"></el-image>
</template>
</el-table-column>
<el-table-column :label="t('虚拟货币(是/否)')" align="center" prop="digitalFlag">
<template #default="{ row }">
{{ row.digitalFlag == 1 ? t('是') : t('否') }}
</template>
</el-table-column>
<el-table-column :label="t('币种符号')" align="center" prop="currencySign" />
<el-table-column :label="t('币种比例')" align="center" prop="gameRate" />
<el-table-column :label="t('币种类型')" align="center" prop="currencyType">
<template #default="scope">
<dict-tag :options="ff_currency" :value="scope.row.currencyType" />
</template>
</el-table-column>
<el-table-column :label="t('币种开关')" align="center" prop="status">
<template #default="{ row }">
<base-switch v-model="row.status" active-value="0" inactive-value="1"
:before-change="() => handleStateChange(row)" v-hasPermi="['operation:currency:changeStatus']" style="--el-switch-on-color: #00a854;" />
</template>
</el-table-column>
<el-table-column :label="t('币种通道')" align="center" prop="currencyAisle">
<template #default="{ row }">
<span>{{ row.currencyAisle ?? '-' }}</span>
</template>
</el-table-column>
<el-table-column :label="t('币种展示内容')" align="center" prop="currencyDisplay" />
<el-table-column :label="t('币种全称')" align="center" prop="fullName" />
<el-table-column :label="t('操作')" align="center" class-name="small-padding fixed-width">
<template #default="scope">
<el-button link type="primary" @click="handleUpdate(scope.row)"
v-hasPermi="['operation:currency:edit']">{{ t('修改') }}</el-button>
<!-- <el-button link type="primary" @click="handleDelete(scope.row)"
v-hasPermi="['operation:currency:remove']">删除</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" />
<!-- 添加或修改币种管理对话框 -->
<el-dialog :title="title" v-model="open" width="600px" append-to-body>
<el-form ref="currencyRef" :model="form" :rules="rules" label-width="120px">
<el-form-item :label="t('币种名称')" prop="currencyName">
<el-input v-model="form.currencyName" :placeholder="t('请输入币种名称')" />
</el-form-item>
<el-form-item :label="t('币种国家')" prop="country">
<el-input v-model="form.country" :placeholder="t('请输入币种国家')" />
</el-form-item>
<el-form-item :label="t('国家/地区代码')">
<el-input v-model="form.countryCode" :placeholder="t('请输入国家/地区代码')" />
</el-form-item>
<el-form-item :label="t('虚拟货币(是/否)')" prop="digitalFlag">
<el-radio-group v-model="form.digitalFlag">
<el-radio :value="1">{{ t('是') }}</el-radio>
<el-radio :value="0">{{ t('否') }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item :label="t('币种类型')" prop="currencyType">
<el-select v-model="form.currencyType" :placeholder="t('请选择币种类型')" @change="typeChange">
<el-option v-for="dict in ff_currency" :key="dict.value" :label="dict.label"
:value="dict.value"></el-option>
</el-select>
</el-form-item>
<el-form-item :label="t('币种图标')" prop="icon">
<image-upload v-model="form.icon" :limit="1" :typeUpImg="2" :fileSize="5"></image-upload>
</el-form-item>
<el-form-item :label="t('币种符号')" prop="currencySign">
<el-input v-model="form.currencySign" :placeholder="t('请输入币种符号')" />
</el-form-item>
<el-form-item :label="t('游戏汇率')" prop="gameRate">
<el-input-number v-model="form.gameRate" :placeholder="t('请输入游戏汇率')" :precision="2" :step="0.1"
:min="0.01" style="width: 100%;" />
</el-form-item>
<el-form-item :label="t('币种通道')" prop="currencyAisle">
<el-input v-model="form.currencyAisle" :placeholder="t('请输入币种通道')" />
</el-form-item>
<el-form-item :label="t('币种展示内容')" prop="currencyDisplay">
<el-input v-model="currencyDisplay" :placeholder="t('请输入币种展示内容')" disabled />
</el-form-item>
<el-form-item :label="t('币种全称')" prop="fullName">
<el-input v-model="form.fullName" :placeholder="t('请输入币种全称')" />
</el-form-item>
<el-form-item :label="t('币种开关')" prop="status">
<el-switch v-model="form.status" style="--el-switch-on-color: #00a854;" active-value="0"
inactive-value="1" />
</el-form-item>
<el-form-item :label="t('描述')" prop="remark">
<el-input v-model="form.remark" type="textarea" :placeholder="t('请输入内容')" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm" :loading="loadingButton">{{ t('确 定') }}</el-button>
<el-button @click="cancel">{{ t(' ') }}</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup name="Currency">
import baseSwitch from "@/components/BaseSwitch"
import * as currency from "@/api/currency";
import { getLocalStorage, setLocalStorage } from "@/utils/auth";
import TableDragSort from '@/components/TableDragSort'; //
import ImageUpload from "@/components/ImageUpload";
const { proxy } = getCurrentInstance();
const { ff_currency } = proxy.useDict('ff_currency');
const fileUrl = getLocalStorage('fileUrl') || '';
const currencyList = ref([]);
const open = ref(false);
const loading = ref(true);
const ids = ref([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const title = ref("");
const loadingButton = ref(false);
const oldForm = shallowRef({ });
const data = reactive({
form: {
digitalFlag:0,
},
queryParams: {
pageNum: 1,
pageSize: 20,
currencyType: null,
currencyName: null
},
rules: {
currencyType: [{ required: true, message: proxy.t("请选择币种类型") }],
currencyCode: [{ required: true, message: proxy.t("请输入币种代码") }],
currencySign: [{ required: true, message: proxy.t("请输入币种符号") }],
gameRate: [{ required: true, message: proxy.t("请输入游戏汇率") }],
country: [{ required: true, message: proxy.t("请输入币种国家") }],
digitalFlag:[{ required: true, message: proxy.t("请输入数字标识") }],
icon: [{ required: true, message: proxy.t("请输入币种图标链接") }],
currencyDisplay: [{ required: true, message: proxy.t("请输入币种展示内容") }],
currencyName: [{ required: true, message: proxy.t("请输入币种名称") }],
fullName: [{ required: true, message: proxy.t("请输入币种全称") }],
}
});
const { queryParams, form, rules } = toRefs(data);
/** 查询币种管理列表 */
function getList() {
loading.value = true;
currency.listCurrency(queryParams.value).then(response => {
currencyList.value = response.rows;
total.value = response.total;
loading.value = false;
});
}
//
function cancel() {
open.value = false;
reset();
}
//
function reset() {
form.value = {
id: null,
currencyName: null,
digitalFlag:0,
country: null,
countryCode:null,
currencyType: null,
icon: null,
currencySign: null,
currencyCode: null,
gameRate: null,
currencyAisle: null,
currencyDisplay: null,
fullName: null,
status: '0',
remark: null
};
proxy.resetForm("currencyRef");
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1;
getList();
}
//
function handleSelectionChange(selection) {
ids.value = selection.map(item => item.id);
single.value = selection.length != 1;
multiple.value = !selection.length;
}
/** 新增按钮操作 */
function handleAdd() {
reset();
open.value = true;
title.value = proxy.t("添加币种管理");
}
//
const dragEnd = (row) => {
currency.currencyUpdateSort(row).then(() => {
if (row.isTop) {
proxy.$modal.msgSuccess(proxy.t('置顶成功'));
} else {
proxy.$modal.msgSuccess(proxy.t('更改排序成功'));
}
handleQuery();
});
}
/** 修改按钮操作 */
function handleUpdate(row) {
reset();
const _id = row.id || ids.value
currency.getCurrency(_id).then(response => {
form.value = {
...response.data,
digitalFlag:response.data.digitalFlag == null?0:response.data.digitalFlag,
};
open.value = true;
title.value = proxy.t("修改币种管理");
});
setTimeout(() => {
let objForm = { ...form.value }
oldForm.value = JSON.stringify(objForm);
}, 500);
}
/** 提交按钮 */
function submitForm() {
proxy.$refs["currencyRef"].validate(valid => {
if (valid) {
loadingButton.value = true;
if (form.value.id != null) {
if (JSON.stringify(form.value) != oldForm.value) {
currency.updateCurrency(form.value).then(response => {
proxy.$modal.msgSuccess(proxy.t("修改成功"));
open.value = false;
loadingButton.value = false;
getList();
updateLocalStorage(); //
}).catch(() => {
loadingButton.value = false;
});
}else{
open.value = false;
loadingButton.value = false;
}
} else {
currency.addCurrency(form.value).then(response => {
proxy.$modal.msgSuccess(proxy.t("新增成功"));
open.value = false;
loadingButton.value = false;
getList();
updateLocalStorage(); //
}).catch(() => {
loadingButton.value = false;
});
}
}
});
}
/** 删除按钮操作 */
// function handleDelete(row) {
// const _ids = row.id || ids.value;
// proxy.$modal.confirm('"' + _ids + '"').then(function () {
// return currency.delCurrency(_ids);
// }).then(() => {
// getList();
// proxy.$modal.msgSuccess(t(""));
// }).catch(() => { });
// }
//
const typeChange = (value) => {
const find = ff_currency.find(item => item.value == value)
form.value.currencyCode = find.label
}
const currencyDisplay = computed(() => {
let { currencyCode, gameRate } = form.value
form.value.currencyDisplay = `${currencyCode ?? ''}${gameRate > 1 ? gameRate + ':1' : ''}`
return form.value.currencyDisplay
})
//
const handleStateChange = async (row) => {
try {
const params = { id: row.id, status: row.status === '0' ? '1' : '0' }
currency.changeStatusCurrency(params).then(response => {
proxy.$modal.msgSuccess(`${row.status === '0' ? proxy.t('关闭成功') : proxy.t('开启成功')}`);
getList();
updateLocalStorage(); //
return true;
});
} catch (error) {
console.error('接口调用失败', error);
return false; //
}
}
getList();
//
const updateLocalStorage = () => {
currency.listCurrency({ pageNum: 1, pageSize: 1000 }).then(res => {
setLocalStorage('currencyList', res.rows);
});
}
</script>
<style scoped lang="scss">
.icon-image {
width: 50px;
height: 50px;
}
</style>

View File

@ -15,6 +15,9 @@
<table-search-date ref="searchDateRef" v-model:dateRange="dateRange"
v-model:operateTimeType="operateTimeType" @dateChange="handleQuery"></table-search-date>
</span>
<el-form-item >
<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>
</el-form-item>
@ -140,7 +143,7 @@
</template>
<script setup name="Feedback">
import { feedbackList, feedbackDetail, ignoreFeedback } from "@/api/operations";
import { feedbackList, feedbackDetail, ignoreFeedback,getSiteSelect } from "@/api/operations";
import TableSearchDate from "@/components/TableSearchDate"; //
import AutoRefreshTime from "@/components/AutoRefreshTime"; //
import CurrencySelect from '@/components/CurrencySelect'; //
@ -187,6 +190,7 @@ const searchDateRef = ref(null), dateRange = ref([]), operateTimeType = ref('');
const queryParams = reactive({
pageNum: 1,
pageSize: 20,
tenantId: '',
timeType: '',
searchType: 'memberAccount', //
memberAccount: '',
@ -263,6 +267,26 @@ const opInfo = (row, type) => {
break;
}
}
const siteSelect = ref([]);
const getSiteSelects = () => {
getSiteSelect().then(response => {
siteSelect.value = response.data.map((item,index) => {
if (index == 0){
queryParams.tenantId = item.tenantId;
}
return {
...item,
label: item.siteName,
value: item.tenantId,
}
});
//
initByListType(props.listType)
})
}
getSiteSelects();
//
const closeDialog = (type) => {
@ -361,40 +385,33 @@ const resetQuery = () => {
handleQuery();
}
//
watch(() => props.listType, (val) => {
//
switch (val) {
case 'pending':
queryParams.feedbackStatus = '1'; //
break;
case 'accepted':
queryParams.feedbackStatus = '2'; //
break;
case 'neglected':
queryParams.feedbackStatus = '3'; //
break;
case 'all':
queryParams.feedbackStatus = ''; //
break;
}
const initByListType = (val) => {
switch (val) {
case 'pending':
queryParams.feedbackStatus = '1';
break;
case 'accepted':
queryParams.feedbackStatus = '2';
break;
case 'neglected':
queryParams.feedbackStatus = '3';
break;
case 'all':
queryParams.feedbackStatus = '';
break;
}
if (val === 'pending') {
setTimeout(() => handleQuery(), 500);
} else {
setTimeout(() => handleQuery(), 500);
}
}
watch(() => props.listType, (val) => {
initByListType(val)
}, { immediate: false }) // immediate false
//
if (val === 'pending') {
// queryParams.timeType = ''; //
handleQuery();
} else {
nextTick(() => {
// queryRef.value = null; //
// dateRange.value = [];
// operateTimeType.value = '';
// queryParams.timeType = '1'; //
handleQuery();
});
}
}, {
immediate: true
});
</script>
<style scoped lang='scss'>

View File

@ -108,7 +108,8 @@ const formAll = reactive({
currencyCodes:[]
})
const loadingButton = ref(false)
const loadingButton = ref(false);
const oldForm = shallowRef({ });
//
nextTick(() => {
console.log(formAll.addEditStatus);
@ -118,8 +119,10 @@ nextTick(() => {
formAll.currencyCodes = props.modifyDate.currencyDisplay.split(',');
formAll.noticeStatus = `${props.modifyDate.noticeStatus}`
formAll.noticeType = `${props.modifyDate.noticeType}`
setTimeout(() => {
let objForm = { ...formAll }
oldForm.value = JSON.stringify(objForm);
}, 500);
});
//
@ -165,22 +168,27 @@ const submitForm = () => {
if (props.addEditStatus == 'add') {
postTenantNotice(formData).then(res => {
loadingButton.value = false;
proxy.$modal.msgSuccess(proxy.t('修改成功!'));
proxy.$modal.msgSuccess(proxy.t('新增成功!'));
emits('submit');
closeDialog();
}).catch(error => {
loadingButton.value = false;
});
}else{
putTenantNotice(formData).then(res => {
if (JSON.stringify(formAll) != oldForm.value) {
putTenantNotice(formData).then(res => {
loadingButton.value = false;
proxy.$modal.msgSuccess(proxy.t('修改成功!'));
emits('submit');
closeDialog();
}).catch(error => {
loadingButton.value = false;
});
}else{
loadingButton.value = false;
proxy.$modal.msgSuccess(proxy.t('修改成功!'));
emits('submit');
closeDialog();
}).catch(error => {
loadingButton.value = false;
});
}
}
}
});

View File

@ -126,7 +126,7 @@ const { ff_tenant_type, ff_tenant_status } = proxy.useDict("ff_tenant_type", "ff
const optionsTimeZone = getLocalStorage('timeZone')?.map(item => {
return {
label: item.description,
value: item.zoneId
value: item.utcOffset
};
});
const currencySelectArr = getLocalStorage('currencySelect')?.map(item => {

View File

@ -124,7 +124,8 @@
<table-operation></table-operation>
<el-table-column :label="t('操作')" align="center" width="200" class-name="small-padding fixed-width">
<template #default="scope">
<el-button link type="primary" @click="handleStop(scope.row)" v-hasPermi="['site:maintenance:stop']">{{ t('') }}</el-button>
<el-button link type="primary" @click="handleOpen(scope.row)" v-hasPermi="['site:maintenance:stop']">{{ 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="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>
@ -149,7 +150,7 @@
<script setup name="Agent">
import { listAgent, createAgent, selectPlatform } from "@/api/agent";
import { superTenantQuotaflow,superCommonCurrencySelect,superCommonPlatformTypeSelect,getSuperBetlist } from "@/api/super/tenant";
import {getMaintenanceList,postMaintenanceStop} from "@/api/siteManagement";
import {getMaintenanceList,postMaintenanceOpen} from "@/api/siteManagement";
import CustomSelect from '@/components/CustomSelect';
import CheckboxSelect from "@/components/CheckboxSelect"; //
import TableSearchDate from '@/components/TableSearchDate'
@ -164,7 +165,7 @@ const { ff_tenant_type, ff_tenant_status } = proxy.useDict("ff_tenant_type", "ff
const optionsTimeZone = getLocalStorage('timeZone')?.map(item => {
return {
label: item.description,
value: item.zoneId
value: item.utcOffset
};
});
const currencySelectArr = getLocalStorage('currencySelect')?.map(item => {
@ -241,12 +242,12 @@ total.value = response.total;
loading.value = false;
});
}
const handleStop = (row) => {
const handleOpen = (row) => {
proxy.$modal.confirm(proxy.t('确认此操作,是否继续?')).then(() => {
let obj = {
id: row.id,
}
return postMaintenanceStop(obj);
return postMaintenanceOpen(obj);
}).then(() => {
getList();
proxy.$modal.msgSuccess(proxy.t('站点注销成功!'));

View File

@ -164,7 +164,7 @@ const { ff_tenant_type, ff_tenant_status } = proxy.useDict("ff_tenant_type", "ff
const optionsTimeZone = getLocalStorage('timeZone')?.map(item => {
return {
label: item.description,
value: item.zoneId
value: item.utcOffset
};
});
const currencySelectArr = getLocalStorage('currencySelect')?.map(item => {

View File

@ -164,7 +164,7 @@ const { ff_tenant_type, ff_tenant_status } = proxy.useDict("ff_tenant_type", "ff
const optionsTimeZone = getLocalStorage('timeZone')?.map(item => {
return {
label: item.description,
value: item.zoneId
value: item.utcOffset
};
});
const currencySelectArr = getLocalStorage('currencySelect')?.map(item => {

View File

@ -164,7 +164,7 @@ const { ff_tenant_type, ff_tenant_status } = proxy.useDict("ff_tenant_type", "ff
const optionsTimeZone = getLocalStorage('timeZone')?.map(item => {
return {
label: item.description,
value: item.zoneId
value: item.utcOffset
};
});
const currencySelectArr = getLocalStorage('currencySelect')?.map(item => {

View File

@ -0,0 +1,247 @@
<template>
<!-- 详情 -->
<el-dialog :title="t('额度修改')" :close-on-click-modal="false" align-center v-model="showDialog" width="700px" append-to-body>
<el-form ref="formRef" :model="formAll" :rules="rules" label-width="150px" class="site-form">
<el-form-item label="租户id" prop="tenantKey">
<el-input v-model="formAll.tenantKey" placeholder="请输入租户id" />
</el-form-item>
<el-form-item label="密钥" prop="secretKey">
<el-input v-model="formAll.secretKey" placeholder="请输入密钥" />
</el-form-item>
<el-form-item label="日期" prop="ShowStartTime">
<el-date-picker
style="width: 600px;"
v-model="formAll.ShowStartTime"
type="datetimerange"
range-separator="-"
:start-placeholder="t('开始时间')"
:end-placeholder="t('结束时间')"
/>
</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="closeDialog">{{ t(' ') }}</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import { formatTime,finalTimestamp } from '@/utils/ruoyi'; //
import ImageUpload from "@/components/ImageUpload";
import BaseCheckbox from "@/components/BaseCheckbox"; //
import IconTips from "@/components/IconTips"; //
// import SkinSelector from "@/components/SkinSelector";
import CurrencySelect from '@/components/CurrencySelect'; //
import CheckboxSelect from "@/components/CheckboxSelect"; // /
import CustomSelect from "@/components/CustomSelect";
import NumberInput from "@/components/NumberInput";
import { updateGame } from "@/api/game/game";
import { getMaterialList } from "@/api/common"; //
import { nextTick, onMounted, ref } from "vue"; //
import { getLocalStorage } from "@/utils/auth";
import { postSiteBindApiGame } from "@/api/siteManagement";
import { id } from 'element-plus/es/locales.mjs';
const langListRaw = getLocalStorage('langList') || []
const langList = Array.from(
new Map(
langListRaw?.filter(v => v.langType == 1 && v.langStatus).map(item => [item.countryLang, {
label: item.name,
value: item.id
}])
).values()
) //
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({
ShowStartTime:[]
})
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' }
]
})
//
nextTick(() => {
Object.assign(formAll, props.modifyDate)
});
const getClientSkinName = (val) => {
let resdata = getLocalStorage('materialGroupSelect');
let items = resdata.find(item => item.id == val.clientSkinStyle)?.gameMaterialDatas||[];
return items.find(item => item.id == val.clientSkin)?.mainColor || '--';
}
const getLangName = (langPattern) => {
let resdata = getLocalStorage('langSelect');
let arrSelect = langPattern.split(',');
let arrName = [];
arrSelect.forEach(itemSele => {
let names = resdata.find(item => item.id == itemSele)?.name;
arrName.push(names);
})
return arrName.join(',');
}
//
const closeDialog = () => {
showDialog.value = false
}
const formRef = ref(null);
const loadingButton = ref(false);
//
const submitForm = () => {
//
formRef.value.validate(valid => {
if (valid) {
loadingButton.value = true;
//
let formData = {
siteId: formAll.siteId,
tenantKey:formAll.tenantKey,
secretKey:formAll.secretKey,
beginTime:finalTimestamp(formAll.ShowStartTime[0]),
endTime:finalTimestamp(formAll.ShowStartTime[1]),
};
postSiteBindApiGame(formData).then(res => {
loadingButton.value = false;
proxy.$modal.msgSuccess(proxy.t('修改成功!'));
emits('submit');
closeDialog();
}).catch(error => {
loadingButton.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;
}
}
}
</style>
<style >
.el-form-ge .el-form-item__content{
align-items: flex-start!important;
}
</style>

View File

@ -1,100 +1,34 @@
<template>
<!-- 详情 -->
<el-dialog :title="t('详情')" :close-on-click-modal="false" align-center v-model="showDialog" width="1300px" append-to-body>
<el-scrollbar max-height="900px" >
<el-descriptions :column="3">
<el-descriptions-item label="站点类型">--</el-descriptions-item>
<el-descriptions-item label="站点ID">{{ modifyDate.id }}</el-descriptions-item>
<el-dialog :title="t('额度修改')" :close-on-click-modal="false" align-center v-model="showDialog" width="700px" append-to-body>
<el-descriptions-item label="推荐方式">-</el-descriptions-item>
<el-descriptions-item label="时区">
{{ modifyDate.timeZone }}
</el-descriptions-item>
<el-descriptions-item label="币种">
{{ modifyDate.currencyPattern }}
<el-form ref="formRef" :model="formAll" :rules="rules" label-width="150px" class="site-form">
</el-descriptions-item>
<el-descriptions-item label="站点名称">
{{ modifyDate.siteName }}
<el-form-item label="额度" prop="balance">
<NumberInput v-model="formAll.balance" placeholder="请输入额度" />
</el-form-item>
<el-form-item label="充值类型" prop="isOut">
<el-radio-group v-model="formAll.isOut">
<el-radio :value="false" size="large">扣除</el-radio>
<el-radio :value="true" size="large">充值</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="钱包类型" prop="wallet">
<el-select v-model="formAll.wallet" placeholder="请选择充值类型">
<el-option label="用户钱包" value="BALANCE" />
<el-option label="透支额度" value="OVERDRAW_BALANCE" />
<el-option label="游戏钱包" value="GAME" />
</el-select>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input type="textarea" :rows="5" v-model="formAll.remark" placeholder="请输入备注" />
</el-descriptions-item>
<el-descriptions-item label="客户端皮肤">
{{ getClientSkinName(modifyDate) }}
</el-descriptions-item>
<el-descriptions-item label="所属集团">
--
</el-descriptions-item>
<el-descriptions-item label="所属公司">
--
</el-descriptions-item>
<el-descriptions-item label="客户端语言匹配模式">
<span v-if="modifyDate.clientLangMatchPattern == 0"></span>
<span v-if="modifyDate.clientLangMatchPattern == 1"></span>
</el-descriptions-item>
<el-descriptions-item label="持有人">
--
</el-descriptions-item>
<el-descriptions-item label="OSS厂商">
阿里云
</el-descriptions-item>
<el-descriptions-item label="代理模式">
-
</el-descriptions-item>
<el-descriptions-item label="语言">
<div style="width: 400px;">
{{ getLangName(modifyDate.langPattern) }}
</div>
</el-descriptions-item>
<el-descriptions-item label="对接商务">
--
</el-descriptions-item>
<el-descriptions-item label="推荐人/推荐单位">
--
</el-descriptions-item>
<el-descriptions-item label="后台域名">
<div>{{ t('主:') }} {{ modifyDate.backendDomain }}</div>
<div>{{ t('备:') }} {{ modifyDate.backendDomain }}</div>
</el-descriptions-item>
<el-descriptions-item label="可用额度(U)">
{{ modifyDate.creditQuota }}
</el-descriptions-item>
<el-descriptions-item label="授信额度(U)">
{{ modifyDate.creditQuota }}
</el-descriptions-item>
<el-descriptions-item label="开站状态">
<el-tag v-if="modifyDate.status == 0" type="info"></el-tag>
<el-tag v-if="modifyDate.status == 1" type="info"></el-tag>
<el-tag v-if="modifyDate.status == 2" type="info"></el-tag>
<el-tag v-if="modifyDate.status == 3" type="info"></el-tag>
</el-descriptions-item>
<el-descriptions-item label="站点余额(U)">
{{ modifyDate.quota }}
</el-descriptions-item>
<el-descriptions-item label="站点透支额比例">
0%
</el-descriptions-item>
<el-descriptions-item label="备注">
{{ modifyDate.remark }}
</el-descriptions-item>
<el-descriptions-item label="开站费(U)">
{{ modifyDate.openCost }}
</el-descriptions-item>
<el-descriptions-item label="站点押金(U)">
{{ modifyDate.depositCost }}
</el-descriptions-item>
<el-descriptions-item label="未结账单(U)">
0.0
</el-descriptions-item>
<el-descriptions-item label="线路费用(U)">
{{ modifyDate.maintanceCost }}
</el-descriptions-item>
</el-descriptions>
</el-scrollbar>
</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="closeDialog">{{ t('') }}</el-button>
<el-button type="primary" @click="submitForm" :loading="loadingButton">{{ t('确 定') }}</el-button>
<el-button @click="closeDialog">{{ t(' ') }}</el-button>
</div>
</template>
@ -109,11 +43,13 @@ import IconTips from "@/components/IconTips"; // 小图标提示
import CurrencySelect from '@/components/CurrencySelect'; //
import CheckboxSelect from "@/components/CheckboxSelect"; // /
import CustomSelect from "@/components/CustomSelect";
import NumberInput from "@/components/NumberInput";
import { updateGame } from "@/api/game/game";
import { getMaterialList } from "@/api/common"; //
import { nextTick, onMounted, ref } from "vue"; //
import { getLocalStorage } from "@/utils/auth";
import * as siteInformation from "@/api/system/siteInformation";
import { postSiteQuotaChange,postSiteBindApiGame } from "@/api/siteManagement";
import { id } from 'element-plus/es/locales.mjs';
const langListRaw = getLocalStorage('langList') || []
@ -154,66 +90,31 @@ const showDialog = computed({ //弹窗显示控制
emits('update:show', value)
}
})
const timeZoneCityMap = {
'-720': '(国际换日线西)',
'-660': '(萨摩亚)',
'-600': '(夏威夷)',
'-540': '(阿拉斯加)',
'-480': '(洛杉矶,加州)',
'-420': '(丹佛)',
'-360': '(芝加哥)',
'-300': '(纽约)',
'-240': '(圣地亚哥,智利)',
'-180': '(布宜诺斯艾利斯)',
'-120': '(中大西洋)',
'-60': '(佛得角)',
'0': '(伦敦)',
'60': '(柏林,巴黎)',
'120': '(雅典,开罗)',
'180': '(莫斯科)',
'240': '(阿联酋,迪拜)',
'300': '(巴基斯坦)',
'330': '(印度)',
'345': '(尼泊尔)',
'360': '(孟加拉国)',
'420': '(越南,泰国)',
'480': '(中国,新加坡,马来西亚)',
'540': '(日本,韩国)',
'570': '(澳大利亚北部)',
'600': '(悉尼)',
'660': '(新喀里多尼亚)',
'720': '(斐济)',
'780': '(汤加)',
};
const offsetMinutes = -new Date().getTimezoneOffset()
const formAll = reactive({
langPattern:[],
currencyPattern:[],
isOut:true,
wallet:'BALANCE',
remark:'',
})
const loadingButton = ref(false);
const skinTabsData = ref([
{
key: 'asiaStyle',
label: '亚太风',
list: [
{ name: 'Bvlgari 蓝黑', value: 'bvlgari_blue_black', isNew: true, previewImg: '/images/bvlgari.png' },
{ name: 'Armani 红色', value: 'armani_red', previewImg: '/images/armani.png' },
]
},
{
key: 'europeStyle',
label: '欧美风',
list: [
{ name: 'Tom Ford 绿色', value: 'tomford_green', previewImg: '/images/tomford.png' },
{ name: 'Ferrari 黑黄', value: 'ferrari_black_yellow', previewImg: '/images/ferrari.png' },
]
}
]);
const rules = reactive({
balance: [
{ required: true, message: proxy.t('请输入额度'), trigger: 'change' },
{ type: 'number', message: proxy.t('请输入数字'), trigger: ['blur', 'change'] }
],
wallet: [
{ required: true, message: proxy.t('请选择钱包类型'), trigger: 'change' },
],
isOut: [
{ required: true, message: proxy.t('请选择充值类型'), trigger: 'change' },
],
})
//
nextTick(() => {
// Object.assign(formAll, props.modifyDate)
Object.assign(formAll, props.modifyDate)
});
const getClientSkinName = (val) => {
@ -238,6 +139,34 @@ const closeDialog = () => {
showDialog.value = false
}
const formRef = ref(null);
const loadingButton = ref(false);
//
const submitForm = () => {
//
formRef.value.validate(valid => {
if (valid) {
loadingButton.value = true;
//
let formData = {
id:formAll.id,
wallet:formAll.wallet,
isOut:formAll.isOut,
balance:formAll.balance,
remark:formAll.remark,
};
postSiteQuotaChange(formData).then(res => {
loadingButton.value = false;
proxy.$modal.msgSuccess(proxy.t('修改成功!'));
emits('submit');
closeDialog();
}).catch(error => {
loadingButton.value = false;
});
}
});
};
</script>
<style scope lang="scss">

View File

@ -122,13 +122,14 @@
</template>
</el-table-column>
<table-operation></table-operation>
<el-table-column :label="t('操作')" align="center" width="200" class-name="small-padding fixed-width">
<el-table-column :label="t('操作')" align="center" width="260" class-name="small-padding fixed-width">
<template #default="scope">
<!-- <el-button link type="primary" @click="handleView(scope.row)" v-hasPermi="['agent:tenant:view']">{{ t('') }}</el-button>
<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" @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="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>
</template>
</el-table-column>
@ -146,16 +147,22 @@
v-model:show="isShowDialog"></add-site-dialog>
<modify-dialog v-if="openView" :modifyDate="modifyDate" @submit="getList"
v-model:show="openView"></modify-dialog>
<bind-tenant v-if="openBind" :modifyDate="modifyDate" @submit="getList"
v-model:show="openBind"></bind-tenant>
<quota-modification v-if="openQuota" :modifyDate="modifyDate" @submit="getList"
v-model:show="openQuota"></quota-modification>
</template>
<script setup name="Agent">
import { listAgent, createAgent, selectPlatform } from "@/api/agent";
import { superTenantQuotaflow,superCommonCurrencySelect,superCommonPlatformTypeSelect,getSuperBetlist } from "@/api/super/tenant";
import {getSiteList} from "@/api/siteManagement";
import {getSiteList,tenantLogin} from "@/api/siteManagement";
import CustomSelect from '@/components/CustomSelect'
import TableSearchDate from '@/components/TableSearchDate'
import AddSiteDialog from "./components/AddSiteDialog"; //
import ModifyDialog from "./components/ModifyDialog";
import BindTenant from "./components/BindTenant";
import QuotaModification from './components/QuotaModification'
import { getLocalStorage } from "@/utils/auth";
import Crontab from '@/components/Crontab'
import { parseTime } from '@/utils/ruoyi'; //
@ -263,7 +270,18 @@ function handleQuery() {
queryParams.value.pageNum = 1;
getList();
}
//
const handleLogin = (row) => {
tenantLogin({
tenantId: row.tenantId,
}).then(res => {
console.log(res);
// if (res.code == 200) {
// window.open(res.data.loginUrl);
// }
})
};
/** 重置按钮操作 */
function resetQuery() {
proxy.resetForm("queryRef");
@ -283,6 +301,16 @@ function handleView(row) {
modifyDate.value = row;
}
const openBind = ref(false);
const openQuota = ref(false);
const handleOpenBind = (row) => {
openBind.value = true;
modifyDate.value = row;
}
const handleOpenQuota = (row) => {
openQuota.value = true;
modifyDate.value = row;
}
const sys_job_group = ref([]);
const showLoding1 = ref(true);

View File

@ -3,16 +3,16 @@
<el-dialog :title="t('详情')" :close-on-click-modal="false" align-center v-model="showDialog" width="1400px" append-to-body>
<el-scrollbar max-height="900px" >
<el-descriptions border :column="1" label-width="150px">
<el-descriptions-item :label="t('站点名称')">
<el-descriptions-item label-class-name="label-class-name" :label="t('站点名称')">
{{ formData.siteName|| '--' }}
</el-descriptions-item>
<el-descriptions-item :label="t('账单月份')">
<el-descriptions-item label-class-name="label-class-name" :label="t('账单月份')">
{{ formData.month||'--' }}
</el-descriptions-item>
<el-descriptions-item :label="t('经营地(含时区)')">
<el-descriptions-item label-class-name="label-class-name" :label="t('经营地(含时区)')">
{{ formData.timeZone||'--' }}
</el-descriptions-item>
<el-descriptions-item :label="t('主语言')">
<el-descriptions-item label-class-name="label-class-name" :label="t('主语言')">
{{ formData?.lang?.name||'--' }}
</el-descriptions-item>
</el-descriptions>
@ -299,7 +299,9 @@ const clickQuotaMonthDetails = (tenantQuotaMonthCurrencyDetailsId) => {
}
}
.label-class-name{
width: 180px;
}
.upload-box-vioce11{
height: 400px !important;
overflow: hidden;

View File

@ -32,7 +32,9 @@
</el-table-column>
<el-table-column :label="t('线路名称')" align="center" min-width="150" >
<template #default="{row}">
{{ row.siteName || '--' }}
<span v-if="row.siteName">{{ `${row.siteName}(${row.siteId})` }}</span>
<span v-else>--</span>
</template>
</el-table-column>
<el-table-column :label="t('租户')" align="center" min-width="150" >
@ -100,9 +102,9 @@
<el-table-column :label="t('操作')" align="center" width="160">
<template #default="{ row }">
<el-button link type="primary" @click="handleView(row)" v-hasPermi="['report:month:query']">{{ t('') }}</el-button>
<el-button link @click="opInfo(row,'payment')" :disabled="row.billStatus != 4 || row.billStatus != 5" v-hasPermi="['report:month:payment:adjust']">{{
<el-button link @click="opInfo(row,'payment')" :disabled="row.billStatus != 2 || row.billStatus != 3 || row.billStatus != 4 || row.billStatus != 5" v-hasPermi="['report:month:payment:adjust']">{{
t('调整支付额度') }}</el-button>
<el-button link :disabled="row.billStatus != 4 || row.billStatus != 5" @click="opInfo(row,'confirm')" v-hasPermi="['report:month:update:status']">{{
<el-button link :disabled="row.billStatus != 3" @click="opInfo(row,'confirm')" v-hasPermi="['report:month:update:status']">{{
t('直接确认无误') }}</el-button>
</template>

View File

@ -79,7 +79,7 @@ import AddSiteDialog from "./components/AddSiteDialog"; // 新增站点弹窗
import ModifyDialog from "./components/ModifyDialog";
import { getLocalStorage } from "@/utils/auth";
import Crontab from '@/components/Crontab'
import { parseTime } from '@/utils/ruoyi'; //
import { parseTime,finalTimestamp } from '@/utils/ruoyi'; //
const router = useRouter();
const { proxy } = getCurrentInstance();
const agentList = ref([]);
@ -100,7 +100,7 @@ const changeTargetArr = ref([
{ label: proxy.t('站点'), value: 4 },
{ label: proxy.t('钱包'), value: 5 },
]);
const dateRange = ref([]),operateTimeType = ref("");
const dateRange = ref([]),operateTimeType = ref("day");
const formatType = 'YYYY-MM-DD HH:mm:ss'; //
const data = reactive({
form: {},
@ -118,8 +118,12 @@ const { queryParams } = toRefs(data);
/** 查询列表 */
function getList() {
loading.value = true;
getSiteFlowUserList(proxy.addDateRange(queryParams.value, dateRange.value)).then(response => {
let params = {
...queryParams.value,
beginTime: finalTimestamp(dateRange.value[0]),
endTime: finalTimestamp(dateRange.value[1]),
}
getSiteFlowUserList(params).then(response => {
agentList.value = response.rows;
total.value = response.total;
loading.value = false;

View File

@ -104,7 +104,7 @@ import AddSiteDialog from "./components/AddSiteDialog"; // 新增站点弹窗
import ModifyDialog from "./components/ModifyDialog";
import { getLocalStorage } from "@/utils/auth";
import Crontab from '@/components/Crontab'
import { parseTime } from '@/utils/ruoyi'; //
import { parseTime,finalTimestamp } from '@/utils/ruoyi'; //
import { onMounted } from "vue";
const router = useRouter();
const { proxy } = getCurrentInstance();
@ -117,6 +117,7 @@ const openView = ref(false);
const queryParamsList = ref([{
label: proxy.t('站点ID'),
value: 'siteId',
inputType: 'number',
},{
label: proxy.t('所属站点'),
value: 'siteName',
@ -124,6 +125,7 @@ const queryParamsList = ref([{
{
label: proxy.t('编号'),
value: 'id',
inputType: 'number',
},
]);
const changeTypeArr = ref([
@ -160,7 +162,7 @@ const changeTargetArr = ref([
{ label: proxy.t('公司'), value: '3' },
{ label: proxy.t('站点'), value: '4' },
])
const dateRange = ref([]),operateTimeType = ref("");
const dateRange = ref([]),operateTimeType = ref("day");
const data = reactive({
form: {},
queryParams: {
@ -178,8 +180,12 @@ const { queryParams } = toRefs(data);
/** 查询列表 */
function getList() {
loading.value = true;
getSiteFlowQuotasList(proxy.addDateRange(queryParams.value, dateRange.value)).then(response => {
let params = {
...queryParams.value,
beginTime: finalTimestamp(dateRange.value[0]),
endTime: finalTimestamp(dateRange.value[1]),
}
getSiteFlowQuotasList(params).then(response => {
agentList.value = response.rows;
total.value = response.total;
loading.value = false;

View File

@ -115,7 +115,7 @@ import AddSiteDialog from "./components/AddSiteDialog"; // 新增站点弹窗
import ModifyDialog from "./components/ModifyDialog";
import { getLocalStorage } from "@/utils/auth";
import Crontab from '@/components/Crontab'
import { parseTime } from '@/utils/ruoyi'; //
import { parseTime,finalTimestamp } from '@/utils/ruoyi'; //
import { onMounted } from "vue";
const router = useRouter();
const { proxy } = getCurrentInstance();
@ -126,6 +126,7 @@ const openView = ref(false);
const queryParamsList = ref([{
label: proxy.t('站点ID'),
value: 'siteId',
inputType: 'number',
},{
label: proxy.t('站点名称'),
value: 'siteName',
@ -133,6 +134,7 @@ const queryParamsList = ref([{
const queryParamsList2 = ref([{
label: proxy.t('订单号'),
value: 'orderId',
inputType: 'number',
},{
label: proxy.t('交易哈希值'),
value: 'tradeHash',
@ -153,7 +155,7 @@ const orderTypeArr = ref([
{label: proxy.t('链上转账'),value: '2'},
{label: proxy.t('保证金充值'),value: '3'},
])
const dateRange = ref([]),operateTimeType = ref("");
const dateRange = ref([]),operateTimeType = ref("day");
const data = reactive({
queryParams: {
pageNum: 1,
@ -173,8 +175,12 @@ const { queryParams} = toRefs(data);
/** 查询列表 */
function getList() {
loading.value = true;
getSiteFlowGameCurrencyList(proxy.addDateRange(queryParams.value, dateRange.value)).then(response => {
let params = {
...queryParams.value,
beginTime: finalTimestamp(dateRange.value[0]),
endTime: finalTimestamp(dateRange.value[1]),
}
getSiteFlowGameCurrencyList(params).then(response => {
agentList.value = response.rows;
total.value = response.total;
loading.value = false;

View File

@ -180,7 +180,7 @@ const multiple = ref(true);
const total = ref(0);
const title = ref("");
const dateRange = ref([]);
const oldForm = shallowRef({ });
const data = reactive({
form: {},
queryParams: {
@ -263,6 +263,10 @@ function handleUpdate(row) {
form.value = response.data;
open.value = true;
title.value = "修改参数";
setTimeout(() => {
let objForm = form.value
oldForm.value = JSON.stringify(objForm);
}, 500);
});
}
@ -271,11 +275,15 @@ function submitForm() {
proxy.$refs["configRef"].validate(valid => {
if (valid) {
if (form.value.configId != undefined) {
updateConfig(form.value).then(response => {
proxy.$modal.msgSuccess("修改成功");
open.value = false;
getList();
});
if (JSON.stringify(form.value) != oldForm.value) {
updateConfig(form.value).then(response => {
proxy.$modal.msgSuccess("修改成功");
open.value = false;
getList();
});
}else{
open.value = false;
}
} else {
addConfig(form.value).then(response => {
proxy.$modal.msgSuccess("新增成功");

View File

@ -154,7 +154,7 @@ const title = ref("");
const deptOptions = ref([]);
const isExpandAll = ref(true);
const refreshTable = ref(true);
const oldForm = shallowRef({ });
const data = reactive({
form: {},
queryParams: {
@ -245,6 +245,10 @@ function handleUpdate(row) {
form.value = response.data;
open.value = true;
title.value = "修改部门";
setTimeout(() => {
let objForm = form.value
oldForm.value = JSON.stringify(objForm);
}, 500);
});
}
@ -253,11 +257,15 @@ function submitForm() {
proxy.$refs["deptRef"].validate(valid => {
if (valid) {
if (form.value.deptId != undefined) {
updateDept(form.value).then(response => {
proxy.$modal.msgSuccess("修改成功");
open.value = false;
getList();
});
if (JSON.stringify(form.value) != oldForm.value) {
updateDept(form.value).then(response => {
proxy.$modal.msgSuccess("修改成功");
open.value = false;
getList();
});
}else{
open.value = false;
}
} else {
addDept(form.value).then(response => {
proxy.$modal.msgSuccess("新增成功");

View File

@ -195,6 +195,7 @@ const title = ref("");
const defaultDictType = ref("");
const typeOptions = ref([]);
const route = useRoute();
const oldForm = shallowRef({ });
//
const listClassOptions = ref([
{ value: "default", label: "默认" },
@ -312,6 +313,10 @@ function handleUpdate(row) {
form.value = response.data;
open.value = true;
title.value = "修改字典数据";
setTimeout(() => {
let objForm = form.value
oldForm.value = JSON.stringify(objForm);
}, 500);
});
}
@ -320,12 +325,16 @@ function submitForm() {
proxy.$refs["dataRef"].validate(valid => {
if (valid) {
if (form.value.dictCode != undefined) {
updateData(form.value).then(response => {
useDictStore().removeDict(queryParams.value.dictType);
proxy.$modal.msgSuccess("修改成功");
open.value = false;
getList();
});
if (JSON.stringify(form.value) != oldForm.value) {
updateData(form.value).then(response => {
useDictStore().removeDict(queryParams.value.dictType);
proxy.$modal.msgSuccess("修改成功");
open.value = false;
getList();
});
}else{
open.value = false;
}
} else {
addData(form.value).then(response => {
useDictStore().removeDict(queryParams.value.dictType);

View File

@ -188,6 +188,7 @@ const multiple = ref(true);
const total = ref(0);
const title = ref("");
const dateRange = ref([]);
const oldForm = shallowRef({ });
const data = reactive({
form: {},
@ -269,6 +270,10 @@ function handleUpdate(row) {
form.value = response.data;
open.value = true;
title.value = "修改字典类型";
setTimeout(() => {
let objForm = form.value
oldForm.value = JSON.stringify(objForm);
}, 500);
});
}
@ -277,11 +282,15 @@ function submitForm() {
proxy.$refs["dictRef"].validate(valid => {
if (valid) {
if (form.value.dictId != undefined) {
updateType(form.value).then(response => {
proxy.$modal.msgSuccess("修改成功");
open.value = false;
getList();
});
if (JSON.stringify(form.value) != oldForm.value) {
updateType(form.value).then(response => {
proxy.$modal.msgSuccess("修改成功");
open.value = false;
getList();
});
}else{
open.value = false;
}
} else {
addType(form.value).then(response => {
proxy.$modal.msgSuccess("新增成功");

View File

@ -305,6 +305,7 @@ const menuOptions = ref([]);
const isExpandAll = ref(false);
const refreshTable = ref(true);
const iconSelectRef = ref(null);
const oldForm = shallowRef({ });
const data = reactive({
form: {},
@ -414,6 +415,10 @@ async function handleUpdate(row) {
form.value = response.data;
open.value = true;
title.value = "修改菜单";
setTimeout(() => {
let objForm = form.value
oldForm.value = JSON.stringify(objForm);
}, 500);
});
}
@ -422,11 +427,15 @@ function submitForm() {
proxy.$refs["menuRef"].validate(valid => {
if (valid) {
if (form.value.menuId != undefined) {
updateMenu(form.value).then(response => {
proxy.$modal.msgSuccess("修改成功");
open.value = false;
getList();
});
if (JSON.stringify(form.value) != oldForm.value) {
updateMenu(form.value).then(response => {
proxy.$modal.msgSuccess("修改成功");
open.value = false;
getList();
});
}else{
open.value = false;
}
} else {
addMenu(form.value).then(response => {
proxy.$modal.msgSuccess("新增成功");

View File

@ -268,6 +268,7 @@ const deptOptions = ref([]);
const openDataScope = ref(false);
const menuRef = ref(null);
const deptRef = ref(null);
const oldForm = shallowRef({ });
/** 数据范围选项*/
const dataScopeOptions = ref([
@ -444,6 +445,11 @@ function handleUpdate(row) {
});
});
});
setTimeout(() => {
form.value.menuIds = getMenuAllCheckedKeys();
let objForm = form.value
oldForm.value = JSON.stringify(objForm);
}, 500);
title.value = "修改角色";
});
}
@ -513,11 +519,15 @@ function submitForm() {
if (valid) {
if (form.value.roleId != undefined) {
form.value.menuIds = getMenuAllCheckedKeys();
updateRole(form.value).then(response => {
proxy.$modal.msgSuccess("修改成功");
if (JSON.stringify(form.value) != oldForm.value) {
updateRole(form.value).then(response => {
proxy.$modal.msgSuccess("修改成功");
open.value = false;
getList();
});
}else{
open.value = false;
getList();
});
}
} else {
form.value.menuIds = getMenuAllCheckedKeys();
addRole(form.value).then(response => {