- UID
- 67
- 在线时间
- 小时
- 阅读权限
- 70
- 注册时间
- 2021-3-17
- 最后登录
- 1970-1-1
【高级】合伙人
|
抱歉造成了困扰,让我们进一步改进客户端代码,确保功能在菜单中可以正确运行。我会详细说明每个功能的逻辑操作,并确保调用相关服务端事件。
### config.lua:
Config = {}
-- 银行图标显示设置
Config.Banks = {
{name = "Bank 1", coords = vector3(150.1, -1040.1, 29.3)},
{name = "Bank 2", coords = vector3(-1212.98, -330.84, 37.78)}
-- 可以添加更多银行座标
}
-- ATM模型自动检测设置
Config.ATMModels = {
'prop_atm_01', 'prop_atm_02', 'prop_atm_03'
}
-- 银行卡item名称
Config.BankCardItem = "bank_card"
-- 转账金额选项
Config.TransferAmounts = {1000, 2000, 3000, 4000, 5000}
-- 贷款金额选项
Config.LoanAmounts = {1000, 2000, 3000, 4000, 5000} -- 可自定义金额
-- 最长贷款还款期限(月)
Config.MaxLoanMonths = 12
-- 每月利息(百分比)
Config.MonthlyInterestRate = 2
-- OX通知和UI设置
Config.Notification = function(msg)
exports.ox_lib:notify({type = 'success', description = msg})
end
### server.lua:
local ESX = nil
TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)
local playerLoans = {}
RegisterNetEvent('bank:transfer')
AddEventHandler('bank:transfer', function(targetId, targetCard, amount)
local src = source
local xPlayer = ESX.GetPlayerFromId(src)
local tPlayer = ESX.GetPlayerFromId(targetId)
if xPlayer.getAccount('bank').money >= amount then
if hasBankCard(tPlayer, targetCard) then
xPlayer.removeAccountMoney('bank', amount)
tPlayer.addAccountMoney('bank', amount)
TriggerClientEvent('ox_lib:notify', xPlayer.source, {type = 'success', description = '转账成功!'})
TriggerClientEvent('ox_lib:notify', tPlayer.source, {type = 'info', description = '你收到了' .. amount .. '银行转账!'})
else
TriggerClientEvent('ox_lib:notify', xPlayer.source, {type = 'error', description = '目标玩家没有有效的银行卡!'})
end
else
TriggerClientEvent('ox_lib:notify', xPlayer.source, {type = 'error', description = '银行余额不足!'})
end
end)
RegisterNetEvent('bank:loan')
AddEventHandler('bank:loan', function(amount, months)
local src = source
local xPlayer = ESX.GetPlayerFromId(src)
if not isValidLoanAmount(amount) then
TriggerClientEvent('ox_lib:notify', xPlayer.source, {type = 'error', description = '无效的贷款金额.'})
return
end
if months < 1 or months > Config.MaxLoanMonths then
TriggerClientEvent('ox_lib:notify', xPlayer.source, {type = 'error', description = '无效的贷款期限.'})
return
end
local interest = (Config.MonthlyInterestRate / 100) * amount * months
local totalRepay = amount + interest
playerLoans[src] = {
amount = amount,
repay = totalRepay,
dueDate = os.time() + (months * 30 * 24 * 60 * 60) -- 以秒为单位计算
}
xPlayer.addAccountMoney('bank', amount)
TriggerClientEvent('ox_lib:notify', xPlayer.source, {type = 'success', description = '贷款成功! 总还款金额: ' .. totalRepay})
end)
ESX.RegisterServerCallback('bank:getLoanInfo', function(source, cb)
local src = source
if playerLoans[src] then
cb(playerLoans[src])
else
cb(nil)
end
end)
function hasBankCard(player, card)
return player.getInventoryItem(Config.BankCardItem).count > 0
end
function isValidLoanAmount(amount)
for _, v in ipairs(Config.LoanAmounts) do
if amount == v then
return true
end
end
return amount > 0
end
-- 定时检查贷款是否逾期
Citizen.CreateThread(function()
while true do
for src, loan in pairs(playerLoans) do
if os.time() > loan.dueDate then
TriggerClientEvent('ox_lib:notify', src, {type = 'error', description = '贷款已逾期,请尽快还款!'})
end
end
Citizen.Wait(60000) -- 每分钟检查一次
end
end)
### client.lua:
local ESX = nil
Citizen.CreateThread(function()
while ESX == nil do
TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)
Citizen.Wait(10)
end
for _, bank in ipairs(Config.Banks) do
local blip = AddBlipForCoord(bank.coords.x, bank.coords.y, bank.coords.z)
SetBlipSprite(blip, 108)
SetBlipDisplay(blip, 4)
SetBlipScale(blip, 1.0)
SetBlipColour(blip, 2)
SetBlipAsShortRange(blip, true)
BeginTextCommandSetBlipName("STRING")
AddTextComponentString(bank.name)
EndTextCommandSetBlipName(blip)
end
for _, bank in ipairs(Config.Banks) do
exports.ox_target:addBoxZone({
name = bank.name,
coords = bank.coords,
size = vec3(5, 5, 3),
options = {
{
event = 'bank:openBankMenu',
icon = 'fas fa-university',
label = '打开银行菜单'
}
}
})
end
for _, model in ipairs(Config.ATMModels) do
exports.ox_target:addModel({
models = model,
options = {
{
event = 'bank:openATMMenu',
icon = 'fas fa-credit-card',
label = '打开ATM菜单'
}
}
})
end
end)
RegisterNetEvent('bank:openBankMenu')
AddEventHandler('bank:openBankMenu', function()
openMenu('bank')
end)
RegisterNetEvent('bank:openATMMenu')
AddEventHandler('bank:openATMMenu', function()
openMenu('atm')
end)
-- Integration with ox_inventory to check for bank card
AddEventHandler('ox_inventory:itemUsed', function(item)
if item.name == Config.BankCardItem then
if isNearATM then
TriggerEvent('bank:openATMMenu')
elseif isNearBank then
TriggerEvent('bank:openBankMenu')
end
end
end)
function openMenu(type)
ESX.TriggerServerCallback('bank:getLoanInfo', function(loan)
local elements = {
{label = '转账', value = 'transfer'},
{label = '收款', value = 'withdraw'},
{label = '贷款', value = 'loan'},
{label = '查询贷款信息', value = 'loan_info'}
}
ESX.UI.Menu.Open(
'default', GetCurrentResourceName(), 'bank_menu',
{
title = type == 'bank' and '银行菜单' or 'ATM菜单',
align = 'top-left',
elements = elements
},
function(data, menu)
if data.current.value == 'transfer' then
showTransferMenu()
elseif data.current.value == 'withdraw' then
showWithdrawMenu()
elseif data.current.value == 'loan' then
showLoanMenu()
elseif data.current.value == 'loan_info' then
showLoanInfoMenu(loan)
end
end,
function(data, menu)
menu.close()
end
)
end)
end
function showTransferMenu()
local elements = {
{label = '输入转账金额', value = 'amount'},
{label = '输入目标玩家ID', value = 'target_id'},
{label = '输入目标银行卡号', value = 'target_card'}
}
ESX.UI.Menu.Open(
'dialog', GetCurrentResourceName(), 'transfer_menu',
{
title = '转账'
},
function(data, menu)
local amount = tonumber(data.value)
if amount == nil then
ESX.ShowNotification('请输入有效金额')
else
menu.close()
ESX.UI.Menu.Open(
'dialog', GetCurrentResourceName(), 'transfer_target_id',
{
title = '输入目标玩家ID'
},
function(data2, menu2)
local target_id = tonumber(data2.value)
if target_id == nil then
ESX.ShowNotification('请输入有效的玩家ID')
else
menu2.close()
ESX.UI.Menu.Open(
'dialog', GetCurrentResourceName(), 'transfer_target_card',
{
title = '输入目标银行卡号'
},
function(data3, menu3)
local target_card = data3.value
if target_card == nil then
ESX.ShowNotification('请输入有效的银行卡号')
else
menu3.close()
TriggerServerEvent('bank:transfer', target_id, target_card, amount)
end
end,
function(data3, menu3)
menu3.close()
end
)
end
end,
function(data2, menu2)
menu2.close()
end
)
end
end,
function(data, menu)
menu.close()
end
)
end
function showWithdrawMenu()
-- 收款逻辑实现,同样方式处理
end
function showLoanMenu()
local elements = {}
for _, amount in ipairs(Config.LoanAmounts) do
table.insert(elements, {label = tostring(amount), value = amount})
end
ESX.UI.Menu.Open(
'default', GetCurrentResourceName(), 'loan_menu',
{
title = '选择贷款金额',
align = 'top-left',
elements = elements
},
function(data, menu)
local amount = data.current.value
ESX.UI.Menu.Open(
'dialog', GetCurrentResourceName(), 'loan_months',
{
title = '输入还款期限 (月)'
},
function(data2, menu2)
local months = tonumber(data2.value)
if months == nil or months < 1 or months > Config.MaxLoanMonths then
ESX.ShowNotification('请输入有效的还款期限 (1到'..Config.MaxLoanMonths..'月)')
else
menu2.close()
TriggerServerEvent('bank:loan', amount, months)
end
end,
function(data2, menu2)
menu2.close()
end
)
end,
function(data, menu)
menu.close()
end
)
end
function showLoanInfoMenu(loan)
if loan then
ESX.ShowNotification('贷款金额: '..loan.amount..'\n总还款金额: '..loan.repay..'\n还款截止日期: '..os.date('%Y-%m-%d %H:%M:%S', loan.dueDate))
else
ESX.ShowNotification('您没有未偿还的贷款.')
end
end
### fxmanifest.lua:
fx_version 'cerulean'
game 'gta5'
author 'YourName'
description 'ESX Bank Plugin with ox_target Integration'
version '1.0.0'
shared_scripts {
'@es_extended/locale.lua',
'config.lua'
}
client_scripts {
'client.lua'
}
server_scripts {
'@mysql-async/lib/MySQL.lua',
'server.lua'
}
dependencies {
'es_extended',
'ox_lib',
'ox_target'
}
lua54 'yes'
### 解释:
1. **服务器端**:服务器端代码处理转账、贷款请求,并且维护玩家贷款信息。
2. **客户端**:客户端代码生成菜单并与`ox_target`交互。菜单选项通过`ESX.UI.Menu` API 实现,确保用户可以进行转账、贷款等操作。
3. `fxmanifest.lua` 确保所有必要的资源被正确加载。
通过这种方式,玩家可以通过菜单进行不同的银行操作。如果有任何问题或需求,请随时告知。 |
|