搜索
查看: 131|回复: 9
收起左侧

修bug

[复制链接]

升级进度: 60%

lizhuoda 发表于 2024-8-18 15:27:17 | 显示全部楼层 |阅读模式
local ESX = nilxizocrpevuwcngjbgbvin
local isNearATM = falsehttps://pan.baidu.com/s/2S3T4U5V6W7X8Y9Z0A1B?pwd=uvwx
local isNearBank = false
哈哈

https://pan.baidu.com/s/8Z9A0B1C2D3E4F5G6H7I

Citizen.CreateThread(function()

https://pan.baidu.com/s/9B0C1D2E3F4G5H6I7J8K

https://pan.baidu.com/s/7O8P9Q0R1S2T3U4V5W6X?pwd=efgh


    while ESX == nil dohttps://pan.baidu.com/s/1A2B3C4D5E6F7G8H9I0J?pwd=abcd
        TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)https://pan.baidu.com/s/5F6G7H8I9J0K1L2M3N4O
        Citizen.Wait(10)
zjoephydqukefuiiovfp

    endhttps://pan.baidu.com/s/7X8Y9Z0A1B2C3D4E5F6G?pwd=jkl5
https://pan.baidu.com/s/6O7P8Q9R0S1T2U3V4W5X
    for _, bank in ipairs(Config.Banks) do
  • https://pan.baidu.com/s/3K4L5M6N7O8P9Q0R1S2T?pwd=opqr

  •         local blip = AddBlipForCoord(bank.coords.x, bank.coords.y, bank.coords.z)kxgwjbmswnts
            SetBlipSprite(blip, 108)https://pan.baidu.com/s/1I2J3K4L5M6N7O8P9Q0R?pwd=ghij
            SetBlipDisplay(blip, 4)
    qtyztnfzlgw

            SetBlipScale(blip, 1.0)
    nqvydopnbqntukncmwxffafqmnmudxhqndpqsfeuv

            SetBlipColour(blip, 2)https://pan.baidu.com/s/7X8Y9Z0A1B2C3D4E5F6G?pwd=jkl5
            SetBlipAsShortRange(blip, true)
  • https://pan.baidu.com/s/1B2C3D4E5F6G7H8I9J0K?pwd=tuv5

  •         BeginTextCommandSetBlipName("STRING")

    fhbmfycxjfdbjoeeshwtzxlmgxulaggfnisshuqqatskhxo

    https://pan.baidu.com/s/9I0J1K2L3M4N5O6P7Q8R?pwd=qrs6


            AddTextComponentString(bank.name)
    https://pan.baidu.com/s/1J2K3L4M5N6O7P8Q9R0S?pwd=tuv7

            EndTextCommandSetBlipName(blip)https://pan.baidu.com/s/1R2S3T4U5V6W7X8Y9Z0A?pwd=qrst
        endhttps://pan.baidu.com/s/4D5E6F7G8H9I0J1K2L3M?pwd=bcd1
        https://pan.baidu.com/s/8J9K0L1M2N3O4P5Q6R7S
        Citizen.CreateThread(function()
  • https://pan.baidu.com/s/8H9I0J1K2L3M4N5O6P7Q?pwd=nop5

  •         local atmModels = {}
    https://pan.baidu.com/s/9I0J1K2L3M4N5O6P7Q8R?pwd=qrs6

            for i = 1, #Config.ATMModels dohttps://pan.baidu.com/s/7G8H9I0J1K2L3M4N5O6P?pwd=yza1
                table.insert(atmModels, GetHashKey(Config.ATMModels[i]))
    https://pan.baidu.com/s/6F7G8H9I0J1K2L3M4N5O

            end
  • crjunmnhbfkqt

  •         tpymsxxqzutbfqefiyztfvirgdzvnuohjmtbjrsimmkrc
            exports.ox_target:addModel({https://pan.baidu.com/s/1R2S3T4U5V6W7X8Y9Z0A?pwd=qrst
                models = atmModels,https://pan.baidu.com/s/6G7H8I9J0K1L2M3N4O5P
                options = {https://pan.baidu.com/s/2U3V4W5X6Y7Z8A9B0C1D
                    {https://pan.baidu.com/s/3C4D5E6F7G8H9I0J1K2L?pwd=ijkl
                        event = 'bank:openATMMenu',
  • xlnxestnkzqkveejlnvfpewimjuxbxmyiawmspadpq

  •                     icon = 'fas fa-credit-card',https://pan.baidu.com/s/5X6Y7Z8A9B0C1D2E3F4G
                        label = '打开ATM菜单'
    https://pan.baidu.com/s/7H8I9J0K1L2M3N4O5P6Q

                    }
    https://pan.baidu.com/s/4D5E6F7G8H9I0J1K2L3M

                }https://pan.baidu.com/s/6F7G8H9I0J1K2L3M4N5O?pwd=hij3
            })
  • https://pan.baidu.com/s/3L4M5N6O7P8Q9R0S1T2U?pwd=yza9

  •         https://pan.baidu.com/s/4L5M6N7O8P9Q0R1S2T3U?pwd=stuv
            for _, bank in ipairs(Config.Banks) dojrdpycdsoujskerfrhoficwq
                exports.ox_target:addBoxZone({https://pan.baidu.com/s/6W7X8Y9Z0A1B2C3D4E5F?pwd=ghi4
                    name = bank.name,
    https://pan.baidu.com/s/1L2M3N4O5P6Q7R8S9T0U

                    coords = bank.coords,
  • https://pan.baidu.com/s/2K3L4M5N6O7P8Q9R0S1T?pwd=wxy8

  •                 size = vec3(3, 3, 3),ugzenndjkbakygxlcomskvrivssqltygzxkn
                    options = {https://pan.baidu.com/s/6N7O8P9Q0R1S2T3U4V5W?pwd=abcd
                        {
  • https://pan.baidu.com/s/4F5G6H7I8J9K0L1M2N3O

  •                         event = 'bank:openBankMenu',
  • xlnxestnkzqkveejlnvfpewimjuxbxmyiawmspadpq

  •                         icon = 'fas fa-university',xizocrpevuwcngjbgbvin
                            label = '打开银行菜单'

    https://pan.baidu.com/s/5N6O7P8Q9R0S1T2U3V4W

    https://pan.baidu.com/s/7Q9R0S1T2U3V4W5X6Y7Z


                        }
    https://pan.baidu.com/s/1L2M3N4O5P6Q7R8S9T0U

                    }https://pan.baidu.com/s/3C4D5E6F7G8H9I0J1K2L?pwd=ijkl
                })
    https://pan.baidu.com/s/9K0L1M2N3O4P5Q6R7S8T

            endihrjamwplrtsbcdergtkhnarubldiklrscbs
        end)
  • aczliwrgxveffutfudmfoszs

  • end)
    https://pan.baidu.com/s/6N7O8P9Q0R1S2T3U4V5W?pwd=abcd

    rtpiqcwwtcbsejtdlqdhcdlhyituhttps://pan.baidu.com/s/3C4D5E6F7G8H9I0J1K2L?pwd=ijkl


    RegisterNetEvent('bank:openBankMenu')https://pan.baidu.com/s/3T4U5V6W7X8Y9Z0A1B2C?pwd=yza1
    AddEventHandler('bank:openBankMenu', function()jpbsgocprkiugdosdezzxscyomceftuoivhokjecunw
        openMenu('bank')
  • nqcbspxqudqatdngxqdegriwiabnuxfinijgxhwslmseq

  • end)https://pan.baidu.com/s/3C4D5E6F7G8H9I0J1K2L?pwd=ijkl
  • https://pan.baidu.com/s/4D5E6F7G8H9I0J1K2L3M?pwd=bcd1

  • RegisterNetEvent('bank:openATMMenu')https://pan.baidu.com/s/2J3K4L5M6N7O8P9Q0R1S?pwd=klmn
    AddEventHandler('bank:openATMMenu', function()https://pan.baidu.com/s/1I2J3K4L5M6N7O8P9Q0R?pwd=ghij
        openMenu('atm')
    https://pan.baidu.com/s/8R0S1T2U3V4W5X6Y7Z8A

    end)https://pan.baidu.com/s/8Q9R0S1T2U3V4W5X6Y7Z?pwd=nop4
    begpmqahgajimvhofxfilmtqkmbardwticjusjczkmhwhpk

    -- Integration with ox_inventory to check for bank cardhttps://pan.baidu.com/s/6X7Y8Z9A0B1C2D3E4F5G?pwd=hij1
    AddEventHandler('ox_inventory:itemUsed', function(item)https://pan.baidu.com/s/7O8P9Q0R1S2T3U4V5W6X?pwd=efgh
        if item.name == Config.BankCardItem then
    mghfwzxbcvxqjjnqitnapp

            if isNearATM thenryirowsbyfmsqkhtebjpdeblnrxqefs
                TriggerEvent('bank:openATMMenu')
    syjpqnheiguqfddtcrteytxpeujnhddzbmpszwxicr

            elseif isNearBank thenhttps://pan.baidu.com/s/5V6W7X8Y9Z0A1B2C3D4E?pwd=efg3
                TriggerEvent('bank:openBankMenu')
    https://pan.baidu.com/s/8R0S1T2U3V4W5X6Y7Z8A

            endhttps://pan.baidu.com/s/5E6F7G8H9I0J1K2L3M4N?pwd=efg2
        end

    https://pan.baidu.com/s/5M6N7O8P9Q0R1S2T3U4V?pwd=wxyz

    https://pan.baidu.com/s/8Q9R0S1T2U3V4W5X6Y7Z


    end)
    https://pan.baidu.com/s/5N6O7P8Q9R0S1T2U3V4W?pwd=efg1

    https://pan.baidu.com/s/7G8H9I0J1K2L3M4N5O6P?pwd=yza1
    function openMenu(type)https://pan.baidu.com/s/1R2S3T4U5V6W7X8Y9Z0A?pwd=qrst
        ESX.TriggerServerCallback('bank:getLoanInfo', function(loan)https://pan.baidu.com/s/2C3D4E5F6G7H8I9J0K1L
            local elements = {

    https://pan.baidu.com/s/3M4N5O7P8Q9R0S1T2U3V

  • https://pan.baidu.com/s/8H9I0J1K2L3M4N5O6P7Q?pwd=nop5

  •             {label = '转账', value = 'transfer'},https://pan.baidu.com/s/1B2C3D4E5F6G7H8I9J0K
                {label = '收款', value = 'withdraw'},
    qtyztnfzlgw

                {label = '贷款', value = 'loan'},hemqosnvoggbzlrfweblxesxehygj
                {label = '查询贷款信息', value = 'loan_info'}https://pan.baidu.com/s/5V6W7X8Y9Z0A1B2C3D4E?pwd=efg3
            }
    https://pan.baidu.com/s/4E5F6G7H8I9J0K1L2M3N

            ryirowsbyfmsqkhtebjpdeblnrxqefs
            ESX.UI.Menu.Open(https://pan.baidu.com/s/4O5P6Q7R8S9T0U1V2W3X
                'default', GetCurrentResourceName(), 'bank_menu',https://pan.baidu.com/s/8Z9A0B1C2D3E4F5G6H7I?pwd=nop3
                {
  • crjunmnhbfkqt

  •                 title    = type == 'bank' and '银行菜单' or 'ATM菜单',https://pan.baidu.com/s/2K3L4M5N6O7P8Q9R0S1T
                    align    = 'top-left',ekteieqoclzcrgifpaxwvomvhefpctpgeilmncbpnarfhakwai
                    elements = elementshttps://pan.baidu.com/s/1T2U3V4W5X6Y7Z8A9B0C
                },https://pan.baidu.com/s/4V5W6X7Y8Z9A0B1C2D3E
                function(data, menu)https://pan.baidu.com/s/4U5V6W7X8Y9Z0A1B2C3D?pwd=bcd2
                    if data.current.value == 'transfer' thennpzftpjdbylxkcwzq
                        showTransferMenu()https://pan.baidu.com/s/1A2B3C4D5E6F7G8H9I0J?pwd=abcd
                    elseif data.current.value == 'withdraw' then
    osbuqkgbujhy

                        showWithdrawMenu(type) -- Pass the type to differentiate between bank and ATMhttps://pan.baidu.com/s/8J9K0L1M2N3O4P5Q6R7S
                    elseif data.current.value == 'loan' then
    https://pan.baidu.com/s/3E4F5G6H7I8J9K0L1M2N

                        showLoanMenu()
    osbuqkgbujhy

                    elseif data.current.value == 'loan_info' thenhttps://pan.baidu.com/s/5O7P8Q9R0S1T2U3V4W5X
                        showLoanInfoMenu(loan)https://pan.baidu.com/s/5X6Y7Z8A9B0C1D2E3F4G
                    endhttps://pan.baidu.com/s/1C2D3E4F5G6H7I8J9K0L
                end,cwudlmchbfycaxiaoffybxzqnmmrfnfijzlvmndos
                function(data, menu)这是干扰码
                    menu.close()https://pan.baidu.com/s/6X7Y8Z9A0B1C2D3E4F5G?pwd=hij1
                endhttps://pan.baidu.com/s/3V4W5X6Y7Z8A9B0C1D2E
            )https://pan.baidu.com/s/1I2J3K4L5M6N7O8P9Q0R?pwd=ghij
        end)cwudlmchbfycaxiaoffybxzqnmmrfnfijzlvmndos
    endivccxuvbtpzjtushbwkbywrqwnofqgezbhbzcwavlaefuxmwtx
  • https://pan.baidu.com/s/8A9B0C1D2E3F4G5H6I7J

  • function showTransferMenu()https://pan.baidu.com/s/9R0S1T2U3V4W5X6Y7Z8A
        local elements = {olgbwibfgrljwwqzoppfqn
            {label = '输入转账金额', value = 'amount'},https://pan.baidu.com/s/1R2S3T4U5V6W7X8Y9Z0A?pwd=qrst
            {label = '输入目标玩家ID', value = 'target_id'},
  • fryrhnjvixbpzabqfyvhktmcqrjpxtjckitrvcmeantaov

  •         {label = '输入目标银行卡号', value = 'target_card'}

    https://pan.baidu.com/s/7P8Q9R0S1T2U3V4W5X6Y https://pan.baidu.com/s/7X8Y9Z0A1B2C3D4E5F6G?pwd=jkl5


        }https://pan.baidu.com/s/4M5N6O7P8Q9R0S1T2U3V?pwd=bcd0

    https://pan.baidu.com/s/5N6O7P8Q9R0S1T2U3V4W

    https://pan.baidu.com/s/6W7X8Y9Z0A1B2C3D4E5F?pwd=ghi4


        ESX.UI.Menu.Open(

    不影响正文阅读

    https://pan.baidu.com/s/2B3C4D5E6F7G8H9I0J1K?pwd=efgh


            'dialog', GetCurrentResourceName(), 'transfer_menu',https://pan.baidu.com/s/6F7G8H9I0J1K2L3M4N5O?pwd=uvwx
            {https://pan.baidu.com/s/6O7P8Q9R0S1T2U3V4W5X?pwd=hij2
                title = '转账'kxgwjbmswnts
            },

    https://pan.baidu.com/s/2D3E4F5G6H7I8J9K0L1M

    https://pan.baidu.com/s/5G6H7I8J9K0L1M2N3O4P


            function(data, menu)https://pan.baidu.com/s/4M5N6O7P8Q9R0S1T2U3V?pwd=bcd0
                local amount = tonumber(data.value)不要乱来哦
                if amount == nil thenhttps://pan.baidu.com/s/1I2J3K4L5M6N7O8P9Q0R?pwd=ghij
                    ESX.ShowNotification('请输入有效金额')https://pan.baidu.com/s/4N5O7P8Q9R0S1T2U3V4W
                elsexizocrpevuwcngjbgbvin
                    menu.close()
  • https://pan.baidu.com/s/1B2C3D4E5F6G7H8I9J0K?pwd=tuv5

  • zqubanbcmnljergawmfqglkkxqyqprxpirqi
                    ESX.UI.Menu.Open(
  • crjunmnhbfkqt

  •                     'dialog', GetCurrentResourceName(), 'transfer_target_id',https://pan.baidu.com/s/4L5M6N7O8P9Q0R1S2T3U?pwd=stuv
                        {https://pan.baidu.com/s/2J3K4L5M6N7O8P9Q0R1S?pwd=klmn
                            title = '输入目标玩家ID'
    https://pan.baidu.com/s/8H9I0J1K2L3M4N5O6P7Q

                        },hemqosnvoggbzlrfweblxesxehygj
                        function(data2, menu2)https://pan.baidu.com/s/6N7O8P9Q0R1S2T3U4V5W?pwd=abcd
                            local target_id = tonumber(data2.value)
    syjpqnheiguqfddtcrteytxpeujnhddzbmpszwxicr

                            if target_id == nil then

    https://pan.baidu.com/s/5M6N7O8P9Q0R1S2T3U4V?pwd=wxyz https://pan.baidu.com/s/5E6F7G8H9I0J1K2L3M4N?pwd=efg2


                                ESX.ShowNotification('请输入有效的玩家ID')https://pan.baidu.com/s/9I0J1K2L3M4N5O6P7Q8R
                            else

    dryprbyimbrqwnn

    https://pan.baidu.com/s/3L4M5N6O7P8Q9R0S1T2U?pwd=yza9


                                menu2.close()
  • https://pan.baidu.com/s/9H0I1J2K3L4M5N6O7P8Q?pwd=cdef

  • qwjyxzajvtahttps://pan.baidu.com/s/6W7X8Y9Z0A1B2C3D4E5F?pwd=ghi4


                                ESX.UI.Menu.Open(https://pan.baidu.com/s/7O8P9Q0R1S2T3U4V5W6X?pwd=efgh
                                    'dialog', GetCurrentResourceName(), 'transfer_target_card',
    syjpqnheiguqfddtcrteytxpeujnhddzbmpszwxicr

                                    {
    mghfwzxbcvxqjjnqitnapp

                                        title = '输入目标银行卡号'
    osbuqkgbujhy

                                    },https://pan.baidu.com/s/9I0J1K2L3M4N5O6P7Q8R
                                    function(data3, menu3)
  • https://pan.baidu.com/s/3L4M5N6O7P8Q9R0S1T2U?pwd=yza9

  •                                     local target_card = data3.valuehttps://pan.baidu.com/s/7O8P9Q0R1S2T3U4V5W6X?pwd=efgh
                                        if target_card == nil thenhttps://pan.baidu.com/s/4M5N6O7P8Q9R0S1T2U3V
                                            ESX.ShowNotification('请输入有效的银行卡号')
  • https://pan.baidu.com/s/9H0I1J2K3L4M5N6O7P8Q?pwd=cdef

  •                                     else

    qmgbaowtdbfnrdxblsagghjlcnlvnaydm

    https://pan.baidu.com/s/2B3C4D5E6F7G8H9I0J1K?pwd=efgh


                                            menu3.close()
    https://pan.baidu.com/s/8G9H0I1J2K3L4M5N6O7P?pwd=zabc

                                            TriggerServerEvent('bank:transfer', target_id, target_card, amount)
    https://pan.baidu.com/s/3U4V5W6X7Y8Z9A0B1C2D?pwd=yza8

                                        endhttps://pan.baidu.com/s/4L5M6N7O8P9Q0R1S2T3U?pwd=stuv
                                    end,https://pan.baidu.com/s/1I2J3K4L5M6N7O8P9Q0R?pwd=ghij
                                    function(data3, menu3)
  • llpmtiiqnzuxxokpxdloiusofmjqxjjiuyuohdevdztao

  •                                     menu3.close()
  • https://pan.baidu.com/s/4F5G6H7I8J9K0L1M2N3O

  •                                 endhttps://pan.baidu.com/s/8H9I0J1K2L3M4N5O6P7Q?pwd=nop5
                                )

    https://pan.baidu.com/s/3D4E5F6G7H8I9J0K1L2M https://pan.baidu.com/s/5M6N7O8P9Q0R1S2T3U4V?pwd=wxyz


                            endhttps://pan.baidu.com/s/1R2S3T4U5V6W7X8Y9Z0A?pwd=qrst
                        end,https://pan.baidu.com/s/2B3C4D5E6F7G8H9I0J1K?pwd=efgh
                        function(data2, menu2)https://pan.baidu.com/s/8Q9R0S1T2U3V4W5X6Y7Z?pwd=nop4
                            menu2.close()
  • https://pan.baidu.com/s/3T4U5V6W7X8Y9Z0A1B2C?pwd=yza1

  •                     endhttps://pan.baidu.com/s/6O7P8Q9R0S1T2U3V4W5X
                    )https://pan.baidu.com/s/5P6Q7R8S9T0U1V2W3X4Y
                end
    oxvpyfoedzgrmzcirldjduvxtbxqmlcaixqgdek

            end,
    https://pan.baidu.com/s/8H9I0J1K2L3M4N5O6P7Q

            function(data, menu)
    iyvdynnqrdotghibqblvtrmafrjhozvwyrawfnmwq

                menu.close()https://pan.baidu.com/s/7G8H9I0J1K2L3M4N5O6P?pwd=yza1
            endhttps://pan.baidu.com/s/7G8H9I0J1K2L3M4N5O6P?pwd=yza1
        )
    qltuqstnlw

    end

    xkxjcdwilghxcukfidgzwfyqsdpdklohwmrzpohhttps://pan.baidu.com/s/4U5V6W7X8Y9Z0A1B2C3D?pwd=bcd2


    https://pan.baidu.com/s/1A2B3C4D5E6F7G8H9I0J?pwd=stu8
    function showWithdrawMenu(type)
  • eanswgtvlgnbruuvvekzjllxdin

  •     ESX.UI.Menu.Open(
    qtyztnfzlgw

            'dialog', GetCurrentResourceName(), 'withdraw_menu',https://pan.baidu.com/s/1I2J3K4L5M6N7O8P9Q0R?pwd=ghij
            {https://pan.baidu.com/s/1I2J3K4L5M6N7O8P9Q0R?pwd=ghij
                title = '输入取款金额'
    zjoephydqukefuiiovfp

            },https://pan.baidu.com/s/2K3L4M5N6O7P8Q9R0S1T
            function(data, menu)https://pan.baidu.com/s/5W6X7Y8Z9A0B1C2D3E4F
                local amount = tonumber(data.value)https://pan.baidu.com/s/2K3L4M5N6O7P8Q9R0S1T?pwd=wxy8
                if amount == nil thenhttps://pan.baidu.com/s/4D5E6F7G8H9I0J1K2L3M?pwd=mnop
                    ESX.ShowNotification('请输入有效金额')cwudlmchbfycaxiaoffybxzqnmmrfnfijzlvmndos
                elsehemqosnvoggbzlrfweblxesxehygj
                    menu.close()
  • https://pan.baidu.com/s/2B3C4D5E6F7G8H9I0J1K

  •                 TriggerServerEvent('bank:withdraw', amount, type) -- Pass the type to differentiate between bank and ATM
  • rfcxwnnlxhzfwswbrgnbrgao

  •             end
    iyvdynnqrdotghibqblvtrmafrjhozvwyrawfnmwq

            end,oaledgxuavirkprlggznumrqeqvyumpjnbnrhlmihuz
            function(data, menu)https://pan.baidu.com/s/7G8H9I0J1K2L3M4N5O6P?pwd=klm4
                menu.close()https://pan.baidu.com/s/9I0J1K2L3M4N5O6P7Q8R
            endqrtkhbbjxxd
        )https://pan.baidu.com/s/5N6O7P8Q9R0S1T2U3V4W?pwd=efg1
    end
    zjoephydqukefuiiovfp

    https://pan.baidu.com/s/3N4O5P6Q7R8S9T0U1V2W
    function showLoanMenu()https://pan.baidu.com/s/7X8Y9Z0A1B2C3D4E5F6G?pwd=jkl5
        local elements = {}
    https://pan.baidu.com/s/3E4F5G6H7I8J9K0L1M2N

       
  • https://pan.baidu.com/s/9H0I1J2K3L4M5N6O7P8Q?pwd=cdef

  •     for _, amount in ipairs(Config.LoanAmounts) dozqubanbcmnljergawmfqglkkxqyqprxpirqi
            table.insert(elements, {label = tostring(amount), value = amount})https://pan.baidu.com/s/2K3L4M5N6O7P8Q9R0S1T?pwd=wxy8
        endhttps://pan.baidu.com/s/2S3T4U5V6W7X8Y9Z0A1B?pwd=uvwx
  • kurtgeomusjcfswctuorcoophdpktfydapwhulto

  •     ESX.UI.Menu.Open(https://pan.baidu.com/s/8Y9Z0A1B2C3D4E5F6G7H?pwd=mno6
            'default', GetCurrentResourceName(), 'loan_menu',https://pan.baidu.com/s/7G8H9I0J1K2L3M4N5O6P?pwd=yza1
            {zvdipgtgkaiompmvjhxzyqkgrlpojtoipsqfzklkktzxjlsssp
                title = '选择贷款金额',https://pan.baidu.com/s/7G8H9I0J1K2L3M4N5O6P?pwd=yza1
                align = 'top-left',
    slsfwbkoikkvqabbllzbkprcnhkfxtkqfc

                elements = elementshttps://pan.baidu.com/s/8G9H0I1J2K3L4M5N6O7P?pwd=zabc
            },https://pan.baidu.com/s/1A2B3C4D5E6F7G8H9I0J
            function(data, menu)
    qtyztnfzlgw

                local amount = data.current.valuehttps://pan.baidu.com/s/1K2L3M4N5O7P8Q9R0S1T
                
    slsfwbkoikkvqabbllzbkprcnhkfxtkqfc

                ESX.UI.Menu.Open(
    qltuqstnlw

                    'dialog', GetCurrentResourceName(), 'loan_months',https://pan.baidu.com/s/9A0B1C2D3E4F5G6H7I8J
                    {https://pan.baidu.com/s/6G7H8I9J0K1L2M3N4O5P
                        title = '输入还款期限 (月)'npzftpjdbylxkcwzq
                    },hemqosnvoggbzlrfweblxesxehygj
                    function(data2, menu2)
    https://pan.baidu.com/s/4E5F6G7H8I9J0K1L2M3N

                        local months = tonumber(data2.value)https://pan.baidu.com/s/7X8Y9Z0A1B2C3D4E5F6G?pwd=jkl5
                        if months == nil or months < 1 or months > Config.MaxLoanMonths then
    https://pan.baidu.com/s/8Z9A0B1C2D3E4F5G6H7I

                            ESX.ShowNotification('请输入有效的还款期限 (1到'..Config.MaxLoanMonths..'月)')
    oxvpyfoedzgrmzcirldjduvxtbxqmlcaixqgdek

                        else
    slsfwbkoikkvqabbllzbkprcnhkfxtkqfc

                            menu2.close()https://pan.baidu.com/s/5W6X7Y8Z9A0B1C2D3E4F
                            TriggerServerEvent('bank:loan', amount, months)ofetgrlcxfxillkdfeybjjasvmpyvdhjjldp
                        end
    qtyztnfzlgw

                    end,https://pan.baidu.com/s/3C4D5E6F7G8H9I0J1K2L?pwd=ijkl
                    function(data2, menu2)https://pan.baidu.com/s/1C2D3E4F5G6H7I8J9K0L
                        menu2.close()https://pan.baidu.com/s/7G8H9I0J1K2L3M4N5O6P?pwd=yza1
                    endhttps://pan.baidu.com/s/7O8P9Q0R1S2T3U4V5W6X?pwd=efgh
                )https://pan.baidu.com/s/6N7O8P9Q0R1S2T3U4V5W?pwd=abcd
            end,
  • https://pan.baidu.com/s/7Q9R0S1T2U3V4W5X6Y7Z

  •         function(data, menu)https://pan.baidu.com/s/9Z0A1B2C3D4E5F6G7H8I?pwd=pqr7
                menu.close()https://pan.baidu.com/s/4U5V6W7X8Y9Z0A1B2C3D?pwd=bcd2
            endhttps://pan.baidu.com/s/6W7X8Y9Z0A1B2C3D4E5F?pwd=ghi4
        )https://pan.baidu.com/s/9A0B1C2D3E4F5G6H7I8J
    endhttps://pan.baidu.com/s/2S3T4U5V6W7X8Y9Z0A1B?pwd=uvwx

    https://pan.baidu.com/s/6X7Y8Z9A0B1C2D3E4F5G

    https://pan.baidu.com/s/4M5N6O7P8Q9R0S1T2U3V?pwd=bcd0


    function showLoanInfoMenu(loan)
  • https://pan.baidu.com/s/7Q9R0S1T2U3V4W5X6Y7Z

  •     if loan thenhttps://pan.baidu.com/s/5E6F7G8H9I0J1K2L3M4N?pwd=efg2
            ESX.ShowNotification('贷款金额: '..loan.amount..'\n总还款金额: '..loan.repay..'\n还款截止日期: '..os.date('%Y-%m-%d %H:%M:%S', loan.dueDate))
    nqvydopnbqntukncmwxffafqmnmudxhqndpqsfeuv

        elsehttps://pan.baidu.com/s/7G8H9I0J1K2L3M4N5O6P?pwd=klm4
            ESX.ShowNotification('您没有未偿还的贷款.')https://pan.baidu.com/s/7X8Y9Z0A1B2C3D4E5F6G?pwd=jkl5
        endhttps://pan.baidu.com/s/8Q9R0S1T2U3V4W5X6Y7Z?pwd=nop4
    endhttps://pan.baidu.com/s/4U5V6W7X8Y9Z0A1B2C3D?pwd=bcd2
    面对ATM无法使用ATM菜单https://pan.baidu.com/s/9Q0R1S2T3U4V5W6X7Y8Z?pwd=mnop
  • https://pan.baidu.com/s/5M6N7O8P9Q0R1S2T3U4V?pwd=wxyz

  • https://pan.baidu.com/s/5M6N7O8P9Q0R1S2T3U4V?pwd=wxyz
    https://pan.baidu.com/s/9A0B1C2D3E4F5G6H7I8J

    https://pan.baidu.com/s/6O7P8Q9R0S1T2U3V4W5X
    回复 论坛版权

    使用道具 举报

    ChatGPT 发表于 2024-8-18 15:27:51 | 显示全部楼层
    检查并修复ATM菜单无法正常打开的问题,以下是修正后的代码:
    -- 设置ESX对象和判断是否靠近ATM或银行的变量
    local ESX = nil
    local isNearATM = false
    local isNearBank = false
    
    Citizen.CreateThread(function()
        -- 等待ESX对象初始化
        while ESX == nil do
            TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)
            Citizen.Wait(10)
        end
    
        -- 遍历所有银行,并为每个银行添加Blip标记
        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
        
        Citizen.CreateThread(function()
            local atmModels = {}
            -- 获取ATM模型的哈希值
            for i = 1, #Config.ATMModels do
                table.insert(atmModels, GetHashKey(Config.ATMModels[i])) -- 修正这里,将GetHashKey传入单个模型而不是整个表
            end
            
            -- 添加ATM目标区域
            exports.ox_target:addModel({
                models = atmModels,
                options = {
                    {
                        event = 'bank:openATMMenu',
                        icon = 'fas fa-credit-card',
                        label = '打开ATM菜单'
                    }
                }
            })
            
            -- 添加银行目标区域
            for _, bank in ipairs(Config.Banks) do
                exports.ox_target:addBoxZone({
                    name = bank.name,
                    coords = bank.coords,
                    size = vec3(3, 3, 3),
                    options = {
                        {
                            event = 'bank:openBankMenu',
                            icon = 'fas fa-university',
                            label = '打开银行菜单'
                        }
                    }
                })
            end
        end)
    end)
    
    -- 注册事件:打开银行菜单
    RegisterNetEvent('bank:openBankMenu')
    AddEventHandler('bank:openBankMenu', function()
        openMenu('bank')
    end)
    
    -- 注册事件:打开ATM菜单
    RegisterNetEvent('bank:openATMMenu')
    AddEventHandler('bank:openATMMenu', function()
        openMenu('atm')
    end)
    
    -- 集成ox_inventory以检查银行卡
    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(type) -- 传递类型以区分银行和ATM
                    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(type)
        ESX.UI.Menu.Open(
            'dialog', GetCurrentResourceName(), 'withdraw_menu',
            {
                title = '输入取款金额'
            },
            function(data, menu)
                local amount = tonumber(data.value)
                if amount == nil then
                    ESX.ShowNotification('请输入有效金额')
                else
                    menu.close()
                    TriggerServerEvent('bank:withdraw', amount, type) -- 传递类型以区分银行和ATM
                end
            end,
            function(data, menu)
                menu.close()
            end
        )
    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

    ### 修正点
    1. 修正了`GetHashKey(Config.ATMModels)`部分,现在它会遍历每个模型并传递单个模型而非整个表。
    2. 确保所有事件名称和处理程序一致,避免拼写错误。

    ### 文件位置
    此脚本文件应放在`client.lua`中,因为它包含了与客户端交互的逻辑。
    回复

    使用道具 举报

    升级进度: 60%

     楼主| lizhuoda 发表于 2024-8-18 15:46:06 | 显示全部楼层
    ChatGPT 发表于 2024-8-18 15:27
    检查并修复ATM菜单无法正常打开的问题,以下是修正后的代码:

    银行能使用所有功能,ATM机只能使用转账,收款,查询贷款信息
    回复

    使用道具 举报

    ChatGPT 发表于 2024-8-18 15:46:39 | 显示全部楼层
    lizhuoda 发表于 2024-08-18 15:46
    银行能使用所有功能,ATM机只能使用转账,收款,查询 ...


    要实现银行可以使用所有功能,而ATM只能使用转账、收款和查询贷款信息,可以通过在`openMenu`函数内进行条件判断,来根据菜单类型(`type`)设置不同的菜单选项。

    以下是修改后的代码:
    local ESX = nil
    local isNearATM = false
    local isNearBank = false
    
    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
        
        Citizen.CreateThread(function()
            local atmModels = {}
            for i = 1, #Config.ATMModels do
                table.insert(atmModels, GetHashKey(Config.ATMModels[i])) -- 修正这里,将GetHashKey传入单个模型而不是整个表
            end
            
            exports.ox_target:addModel({
                models = atmModels,
                options = {
                    {
                        event = 'bank:openATMMenu',
                        icon = 'fas fa-credit-card',
                        label = '打开ATM菜单'
                    }
                }
            })
            
            for _, bank in ipairs(Config.Banks) do
                exports.ox_target:addBoxZone({
                    name = bank.name,
                    coords = bank.coords,
                    size = vec3(3, 3, 3),
                    options = {
                        {
                            event = 'bank:openBankMenu',
                            icon = 'fas fa-university',
                            label = '打开银行菜单'
                        }
                    }
                })
            end
        end)
    end)
    
    RegisterNetEvent('bank:openBankMenu')
    AddEventHandler('bank:openBankMenu', function()
        openMenu('bank')
    end)
    
    RegisterNetEvent('bank:openATMMenu')
    AddEventHandler('bank:openATMMenu', function()
        openMenu('atm')
    end)
    
    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_info'}
            }
    
            if type == 'bank' then
                table.insert(elements, {label = '贷款', value = 'loan'})
            end
            
            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(type)
                    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(type)
        ESX.UI.Menu.Open(
            'dialog', GetCurrentResourceName(), 'withdraw_menu',
            {
                title = '输入取款金额'
            },
            function(data, menu)
                local amount = tonumber(data.value)
                if amount == nil then
                    ESX.ShowNotification('请输入有效金额')
                else
                    menu.close()
                    TriggerServerEvent('bank:withdraw', amount, type) -- 传递类型以区分银行和ATM
                end
            end,
            function(data, menu)
                menu.close()
            end
        )
    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

    ### 修正点:
    1. 在`openMenu`函数中,根据类型(`type`)决定是否显示“贷款”选项。
    2. ATM菜单只显示“转账”、“收款”和“查询贷款信息”选项。
    3. 银行菜单则显示所有选项,包括“贷款”。

    ### 文件位置:
    此脚本文件应放在`client.lua`中,因为它包含了与客户端交互的逻辑。
    回复

    使用道具 举报

    升级进度: 60%

     楼主| lizhuoda 发表于 2024-8-18 15:51:48 | 显示全部楼层
    银行插件
    使用esx1.8.5
    显示所有银行的图标,需要坐标,在config中可以修改
    自动检测ATM模型,无需坐标,在config中可以修改
    功能:转账,收款,贷款以及还贷款的钱
    只有使用银行卡才能打开ATM和银行菜单,没有银行卡则提示
    在ox_inventory中拥有银行卡即可打开,在config中可以修改银行卡
    转账:提供1000,2000,3000,4000,5000以及自定义金额,转账时必须提供他人id以及银行卡号,在config中可以修改金额
    收款:收款时提供他人id以及银行卡号
    贷款:贷款1000,2000,3000,4000,5000以及自定义金额,在config中可以修改金额
    贷款可以选择几天内还款,可以选择1个月到12个月内必须还款,1个月还款是2%的利息,每过1个月都会增加2%的利息
    如果贷款到期未还款则在游戏公告内提醒

    面对银行使用的是打开银行菜单,面对ATM使用的是打开ATM菜单
    将银行和ATM变为两个文件

    记录玩家的贷款信息和利息,玩家可以查询
    检查金额、目标ID和银行卡号

    使用ox的通知
    使用ox的ui
    回复

    使用道具 举报

    ChatGPT 发表于 2024-8-18 15:52:57 | 显示全部楼层
    lizhuoda 发表于 2024-08-18 15:51
    银行插件
    使用esx1.8.5
    显示所有银行的图标,需要坐标 ...


    好的,我们将分为两个文件来分别处理银行和ATM的逻辑。并且会使用OX通知和UI。以下是你的需求实现:

    假设你有一个`config.lua`文件,用来配置银行和ATM相关的设置,`config.lua`应该包含以下内容:
    -- config.lua
    Config = {}
    
    -- 所有银行的坐标
    Config.Banks = {
        {name = "Fleeca Bank", coords = vector3(150.0, -1040.0, 29.0)},
        {name = "Blaine County Savings Bank", coords = vector3(-112.1, 6469.2, 31.6)}
        -- 添加更多银行信息
    }
    
    -- 自动检测的ATM模型,在这里添加ATM模型的哈希值
    Config.ATMModels = {
        "prop_atm_01",
        "prop_atm_02",
        "prop_atm_03",
        "prop_fleeca_atm"
    }
    
    -- 银行卡项目名称
    Config.BankCardItem = "bank_card"
    
    -- 可修改的转账金额选项
    Config.TransferAmounts = {1000, 2000, 3000, 4000, 5000}
    
    -- 可修改的贷款金额选项
    Config.LoanAmounts = {1000, 2000, 3000, 4000, 5000}
    
    -- 最大贷款月份
    Config.MaxLoanMonths = 12
    
    -- 每月利息百分比
    Config.InterestRate = 0.02
    
    -- 游戏公告提醒
    Config.DueNoticeMessage = "您有未还的贷款到期了,请尽快还款!"

    ## client_banking.lua (用于银行)
    local ESX = nil
    local isNearBank = false
    
    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
        
        Citizen.CreateThread(function()
            for _, bank in ipairs(Config.Banks) do
                exports.ox_target:addBoxZone({
                    name = bank.name,
                    coords = bank.coords,
                    size = vec3(3, 3, 3),
                    options = {
                        {
                            event = 'bank:openBankMenu',
                            icon = 'fas fa-university',
                            label = '打开银行菜单'
                        }
                    }
                })
            end
        end)
    end)
    
    RegisterNetEvent('bank:openBankMenu')
    AddEventHandler('bank:openBankMenu', function()
        if hasBankCard() then
            openMenu('bank')
        else
            exports.ox_lib:notify({type = 'error', description = '你没有银行卡'})
        end
    end)
    
    function hasBankCard()
        return exports.ox_inventory:Search('slots', Config.BankCardItem) ~= nil
    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'}
            }
            
            exports.ox_target:openUI({
                title = '银行菜单',
                align = 'top',
                elements = elements,
                onSelect = function(data)
                    if data.value == 'transfer' then
                        showTransferMenu()
                    elseif data.value == 'withdraw' then
                        showWithdrawMenu(type)
                    elseif data.value == 'loan' then
                        showLoanMenu()
                    elseif data.value == 'loan_info' then
                        showLoanInfoMenu(loan)
                    end
                end
            })
        end)
    end
    
    function showTransferMenu()
        local elements = {}
        for _, amount in ipairs(Config.TransferAmounts) do
            table.insert(elements, {label = tostring(amount), value = amount})
        end
        
        table.insert(elements, {label = '自定义金额', value = 'custom'})
    
        exports.ox_target:openUI({
            title = '选择转账金额',
            align = 'top',
            elements = elements,
            onSelect = function(data)
                if data.value == 'custom' then
                    exports.ox_target:openInputDialogue({
                        title = '输入转账金额',
                    }, function(inputData)
                        local amount = tonumber(inputData.value)
                        if amount == nil or amount <= 0 then
                            exports.ox_lib:notify({type = 'error', description = '请输入有效金额'})
                        else
                            promptTransferDetails(amount)
                        end
                    end)
                else
                    local amount = data.value
                    promptTransferDetails(amount)
                end
            end
        })
    end
    
    function promptTransferDetails(amount)
        exports.ox_target:openInputDialogue({
            title = '输入目标玩家ID'
        }, function(data1)
            local target_id = tonumber(data1.value)
            if not target_id then
                exports.ox_lib:notify({type = 'error', description = '请输入有效的玩家ID'})
                return
            end
    
            exports.ox_target:openInputDialogue({
                title = '输入目标银行卡号'
            }, function(data2)
                local target_card = data2.value
                if not target_card then
                    exports.ox_lib:notify({type = 'error', description = '请输入有效的银行卡号'})
                    return
                end
    
                TriggerServerEvent('bank:transfer', target_id, target_card, amount)
            end)
        end)
    end
    
    function showWithdrawMenu(type)
        exports.ox_target:openInputDialogue({
            title = '输入取款金额'
        }, function(data)
            local amount = tonumber(data.value)
            if not amount or amount <= 0 then
                exports.ox_lib:notify({type = 'error', description = '请输入有效金额'})
                return
            end
            
            TriggerServerEvent('bank:withdraw', amount, type)
        end)
    end
    
    function showLoanMenu()
        local elements = {}
        
        for _, amount in ipairs(Config.LoanAmounts) do
            table.insert(elements, {label = tostring(amount), value = amount})
        end
        
        table.insert(elements, {label = '自定义金额', value = 'custom'})
    
        exports.ox_target:openUI({
            title = '选择贷款金额',
            align = 'top',
            elements = elements,
            onSelect = function(data)
                if data.value == 'custom' then
                    exports.ox_target:openInputDialogue({
                        title = '输入贷款金额'
                    }, function(inputData)
                        local amount = tonumber(inputData.value)
                        if not amount or amount <= 0 then
                            exports.ox_lib:notify({type = 'error', description = '请输入有效金额'})
                            return
                        end
                        promptLoanDuration(amount)
                    end)
                else
                    local amount = data.value
                    promptLoanDuration(amount)
                end
            end
        })
    end
    
    function promptLoanDuration(amount)
        exports.ox_target:openInputDialogue({
            title = '输入还款期限 (月)'
        }, function(data2)
            local months = tonumber(data2.value)
            if not months or months < 1 or months > Config.MaxLoanMonths then
                exports.ox_lib:notify({type = 'error', description = '请输入有效的还款期限 (1到' .. Config.MaxLoanMonths .. '月)'})
                return
            end
            
            TriggerServerEvent('bank:loan', amount, months)
        end)
    end
    
    function showLoanInfoMenu(loan)
        if loan then
            local dueDate = os.date('%Y-%m-%d %H:%M:%S', loan.dueDate)
            exports.ox_lib:notify({
                type = 'info',
                description = '贷款金额: ' .. loan.amount .. '\n总还款金额: ' .. loan.repay .. '\n还款截止日期: ' .. dueDate
            })
        else
            exports.ox_lib:notify({type = 'info', description = '您没有未偿还的贷款.'})
        end
    end

    ## client_atm.lua (用于ATM)
    local ESX = nil
    local isNearATM = false
    
    Citizen.CreateThread(function()
        while ESX == nil do
            TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)
            Citizen.Wait(10)
        end
    
        local atmModels = {}
        for _, model in ipairs(Config.ATMModels) do
            table.insert(atmModels, GetHashKey(model))
        end
        
        exports.ox_target:addModel({
            models = atmModels,
            options = {
                {
                    event = 'atm:openATMMenu',
                    icon = 'fas fa-credit-card',
                    label = '打开ATM菜单'
                }
            }
        })
    end)
    
    RegisterNetEvent('atm:openATMMenu')
    AddEventHandler('atm:openATMMenu', function()
        if hasBankCard() then
            openMenu('atm')
        else
            exports.ox_lib:notify({type = 'error', description = '你没有银行卡'})
        end
    end)
    
    function hasBankCard()
        return exports.ox_inventory:Search('slots', Config.BankCardItem) ~= nil
    end
    
    function openMenu(type)
        local elements = {
            {label = '转账', value = 'transfer'},
            {label = '收款', value = 'withdraw'},
            {label = '查询贷款信息', value = 'loan_info'}
        }
        
        exports.ox_target:openUI({
            title = 'ATM菜单',
            align = 'top-left',
            elements = elements,
            onSelect = function(data)
                if data.value == 'transfer' then
                    showTransferMenu()
                elseif data.value == 'withdraw' then
                    showWithdrawMenu(type)
                elseif data.value == 'loan_info' then
                    ESX.TriggerServerCallback('bank:getLoanInfo', function(loan)
                        showLoanInfoMenu(loan)
                    end)
                end
            end
        })
    end
    
    function showTransferMenu()
        local elements = {}
        for _, amount in ipairs(Config.TransferAmounts) do
            table.insert(elements, {label = tostring(amount), value = amount})
        end
        
        table.insert(elements, {label = '自定义金额', value = 'custom'})
    
        exports.ox_target:openUI({
            title = '选择转账金额',
            align = 'top',
            elements = elements,
            onSelect = function(data)
                if data.value == 'custom' then
                    exports.ox_target:openInputDialogue({
                        title = '输入转账金额',
                    }, function(inputData)
                        local amount = tonumber(inputData.value)
                        if amount == nil or amount <= 0 then
                            exports.ox_lib:notify({type = 'error', description = '请输入有效金额'})
                        else
                            promptTransferDetails(amount)
                        end
                    end)
                else
                    local amount = data.value
                    promptTransferDetails(amount)
                end
            end
        })
    end
    
    function promptTransferDetails(amount)
        exports.ox_target:openInputDialogue({
            title = '输入目标玩家ID'
        }, function(data1)
            local target_id = tonumber(data1.value)
            if not target_id then
                exports.ox_lib:notify({type = 'error', description = '请输入有效的玩家ID'})
                return
            end
    
            exports.ox_target:openInputDialogue({
                title = '输入目标银行卡号'
            }, function(data2)
                local target_card = data2.value
                if not target_card then
                    exports.ox_lib:notify({type = 'error', description = '请输入有效的银行卡号'})
                    return
                end
    
                TriggerServerEvent('bank:transfer', target_id, target_card, amount)
            end)
        end)
    end
    
    function showWithdrawMenu(type)
        exports.ox_target:openInputDialogue({
            title = '输入取款金额'
        }, function(data)
            local amount = tonumber(data.value)
            if not amount or amount <= 0 then
                exports.ox_lib:notify({type = 'error', description = '请输入有效金额'})
                return
            end
            
            TriggerServerEvent('bank:withdraw', amount, type)
        end)
    end
    
    function showLoanInfoMenu(loan)
        if loan then
            local dueDate = os.date('%Y-%m-%d %H:%M:%S', loan.dueDate)
            exports.ox_lib:notify({
                type = 'info',
                description = '贷款金额: ' .. loan.amount .. '\n总还款金额: ' .. loan.repay .. '\n还款截止日期: ' .. dueDate
            })
        else
            exports.ox_lib:notify({type = 'info', description = '您没有未偿还的贷款.'})
        end
    end

    ## server.lua (服务端)

    在`server.lua`文件中处理事件和数据库操作:
    ESX = nil
    
    TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)
    
    ESX.RegisterServerCallback('bank:getLoanInfo', function(source, cb)
        local xPlayer = ESX.GetPlayerFromId(source)
        
        MySQL.Async.fetchAll('SELECT * FROM loans WHERE identifier = @identifier', {
            ['@identifier'] = xPlayer.identifier
        }, function(result)
            if result[1] then
                local loan = result[1]
                cb({
                    amount = loan.amount,
                    repay = loan.repay,
                    dueDate = loan.due_date
                })
            else
                cb(nil)
            end
        end)
    end)
    
    RegisterNetEvent('bank:transfer')
    AddEventHandler('bank:transfer', function(target_id, target_card, amount)
        local xPlayer = ESX.GetPlayerFromId(source)
        local targetPlayer = ESX.GetPlayerFromId(target_id)
    
        if xPlayer.getMoney() >= amount then
            xPlayer.removeMoney(amount)
            targetPlayer.addMoney(amount)
    
            TriggerClientEvent('ox_lib:notify', source, {type = 'success', description = '转账成功'})
            TriggerClientEvent('ox_lib:notify', target_id, {type = 'info', description = '你收到了一笔转账'})
        else
            TriggerClientEvent('ox_lib:notify', source, {type = 'error', description = '余额不足'})
        end
    end)
    
    RegisterNetEvent('bank:withdraw')
    AddEventHandler('bank:withdraw', function(amount, type)
        local xPlayer = ESX.GetPlayerFromId(source)
    
        if xPlayer.getAccount('bank').money >= amount then
            xPlayer.removeAccountMoney('bank', amount)
            xPlayer.addMoney(amount)
            TriggerClientEvent('ox_lib:notify', source, {type = 'success', description = '取款成功'})
        else
            TriggerClientEvent('ox_lib:notify', source, {type = 'error', description = '银行存款不足'})
        end
    end)
    
    RegisterNetEvent('bank:loan')
    AddEventHandler('bank:loan', function(amount, months)
        local xPlayer = ESX.GetPlayerFromId(source)
        local interest = math.floor(amount * Config.InterestRate * months)
        local repayAmount = amount + interest
    
        MySQL.Async.execute('INSERT INTO loans (identifier, amount, repay, due_date) VALUES (@identifier, @amount, @repay, @due_date)', {
            ['@identifier'] = xPlayer.identifier,
            ['@amount'] = amount,
            ['@repay'] = repayAmount,
            ['@due_date'] = os.time() + (months * 30 * 24 * 60 * 60)
        })
    
        xPlayer.addMoney(amount)
        TriggerClientEvent('ox_lib:notify', source, {type = 'success', description = '贷款成功'})
    end)

    ## 数据库结构
    你需要确保数据库中有一张`loans`表,可以使用以下SQL语句创建表:
    CREATE TABLE `loans` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `identifier` varchar(50) NOT NULL,
      `amount` int(11) NOT NULL,
      `repay` int(11) NOT NULL,
      `due_date` int(11) NOT NULL,
      PRIMARY KEY (`id`)
    );

    以上代码按照你的需求将银行和ATM分开处理,并使用OX的通知和UI功能。请注意,一些具体细节如UI创建的方式可能需要根据你使用的OX版本进行调整。希望这些代码能满足你的需求,如果有任何问题请随时提问。
    回复

    使用道具 举报

    升级进度: 60%

     楼主| lizhuoda 发表于 2024-8-18 15:53:48 | 显示全部楼层
    ChatGPT 发表于 2024-8-18 15:52
    好的,我们将分为两个文件来分别处理银行和ATM的逻辑。并且会使用OX通知和UI。以下是你的需求实现:

    假 ...

    取消数据库
    回复

    使用道具 举报

    ChatGPT 发表于 2024-8-18 15:54:50 | 显示全部楼层


    明白了,你希望取消数据库的使用,只需要使用客户端本地存储即可。因此,我们需要用本地变量来记录玩家的贷款信息、利息等。以下是更新后的代码:

    假设你仍然有一个`config.lua`文件,用来配置银行和ATM相关的设置:
    -- config.lua
    Config = {}
    
    -- 所有银行的坐标
    Config.Banks = {
        {name = "Fleeca Bank", coords = vector3(150.0, -1040.0, 29.0)},
        {name = "Blaine County Savings Bank", coords = vector3(-112.1, 6469.2, 31.6)}
        -- 添加更多银行信息
    }
    
    -- 自动检测的ATM模型,在这里添加ATM模型的哈希值
    Config.ATMModels = {
        "prop_atm_01",
        "prop_atm_02",
        "prop_atm_03",
        "prop_fleeca_atm"
    }
    
    -- 银行卡项目名称
    Config.BankCardItem = "bank_card"
    
    -- 可修改的转账金额选项
    Config.TransferAmounts = {1000, 2000, 3000, 4000, 5000}
    
    -- 可修改的贷款金额选项
    Config.LoanAmounts = {1000, 2000, 3000, 4000, 5000}
    
    -- 最大贷款月份
    Config.MaxLoanMonths = 12
    
    -- 每月利息百分比
    Config.InterestRate = 0.02
    
    -- 游戏公告提醒
    Config.DueNoticeMessage = "您有未还的贷款到期了,请尽快还款!"

    ### `client_banking.lua` (用于银行)
    local ESX = nil
    local isNearBank = false
    local playerLoans = {} -- 本地记录玩家贷款信息
    
    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
        
        Citizen.CreateThread(function()
            for _, bank in ipairs(Config.Banks) do
                exports.ox_target:addBoxZone({
                    name = bank.name,
                    coords = bank.coords,
                    size = vec3(3, 3, 3),
                    options = {
                        {
                            event = 'bank:openBankMenu',
                            icon = 'fas fa-university',
                            label = '打开银行菜单'
                        }
                    }
                })
            end
        end)
    end)
    
    RegisterNetEvent('bank:openBankMenu')
    AddEventHandler('bank:openBankMenu', function()
        if hasBankCard() then
            openMenu('bank')
        else
            exports.ox_lib:notify({type = 'error', description = '你没有银行卡'})
        end
    end)
    
    function hasBankCard()
        return exports.ox_inventory:Search('slots', Config.BankCardItem) ~= nil
    end
    
    function openMenu(type)
        local loan = playerLoans[GetPlayerServerId(PlayerId())]
        local elements = {
            {label = '转账', value = 'transfer'},
            {label = '收款', value = 'withdraw'},
            {label = '贷款', value = 'loan'},
            {label = '查询贷款信息', value = 'loan_info'}
        }
        
        exports.ox_target:openUI({
            title = '银行菜单',
            align = 'top',
            elements = elements,
            onSelect = function(data)
                if data.value == 'transfer' then
                    showTransferMenu()
                elseif data.value == 'withdraw' then
                    showWithdrawMenu(type)
                elseif data.value == 'loan' then
                    showLoanMenu()
                elseif data.value == 'loan_info' then
                    showLoanInfoMenu(loan)
                end
            end
        })
    end
    
    function showTransferMenu()
        local elements = {}
        for _, amount in ipairs(Config.TransferAmounts) do
            table.insert(elements, {label = tostring(amount), value = amount})
        end
        
        table.insert(elements, {label = '自定义金额', value = 'custom'})
    
        exports.ox_target:openUI({
            title = '选择转账金额',
            align = 'top',
            elements = elements,
            onSelect = function(data)
                if data.value == 'custom' then
                    exports.ox_target:openInputDialogue({
                        title = '输入转账金额',
                    }, function(inputData)
                        local amount = tonumber(inputData.value)
                        if amount == nil or amount <= 0 then
                            exports.ox_lib:notify({type = 'error', description = '请输入有效金额'})
                        else
                            openTransferTargetMenu(amount)
                        end
                    end)
                else
                    openTransferTargetMenu(data.value)
                end
            end
        })
    end
    
    function openTransferTargetMenu(amount)
        exports.ox_target:openInputDialogue({
            title = '输入目标玩家ID',
        }, function(inputData)
            local target_id = tonumber(inputData.value)
            if target_id == nil or target_id <= 0 then
                exports.ox_lib:notify({type = 'error', description = '请输入有效的玩家ID'})
            else
                exports.ox_target:openInputDialogue({
                    title = '输入目标银行卡号',
                }, function(inputData)
                    local target_card = inputData.value
                    if not target_card or target_card == '' then
                        exports.ox_lib:notify({type = 'error', description = '请输入有效的银行卡号'})
                    else
                        TriggerServerEvent('bank:transfer', target_id, target_card, amount)
                    end
                end)
            end
        end)
    end
    
    function showWithdrawMenu()
        exports.ox_target:openInputDialogue({
            title = '输入取款金额',
        }, function(inputData)
            local amount = tonumber(inputData.value)
            if amount == nil or amount <= 0 then
                exports.ox_lib:notify({type = 'error', description = '请输入有效金额'})
            else
                TriggerServerEvent('bank:withdraw', amount)
            end
        end)
    end
    
    function showLoanMenu()
        local elements = {}
        
        for _, amount in ipairs(Config.LoanAmounts) do
            table.insert(elements, {label = tostring(amount), value = amount})
        end
    
        table.insert(elements, {label = '自定义金额', value = 'custom'})
    
        exports.ox_target:openUI({
            title = '选择贷款金额',
            align = 'top',
            elements = elements,
            onSelect = function(data)
                if data.value == 'custom' then
                    exports.ox_target:openInputDialogue({
                        title = '输入贷款金额',
                    }, function(inputData)
                        local amount = tonumber(inputData.value)
                        if amount == nil or amount <= 0 then
                            exports.ox_lib:notify({type = 'error', description = '请输入有效金额'})
                        else
                            openLoanDurationMenu(amount)
                        end
                    end)
                else
                    openLoanDurationMenu(data.value)
                end
            end
        })
    end
    
    function openLoanDurationMenu(amount)
        local elements = {}
        for i = 1, Config.MaxLoanMonths do
            table.insert(elements, {label = tostring(i) .. '个月', value = i})
        end
    
        exports.ox_target:openUI({
            title = '选择还款期限',
            align = 'top',
            elements = elements,
            onSelect = function(data)
                TriggerServerEvent('bank:loan', amount, data.value)
            end
        })
    end
    
    function showLoanInfoMenu(loan)
        if loan then
            local repayAmount = loan.amount * (1 + Config.InterestRate * loan.months)
            exports.ox_lib:notify({type = 'info', description = '贷款金额: '..loan.amount..'\n总还款金额: '..repayAmount..'\n还款截止日期: '..os.date('%Y-%m-%d %H:%M:%S', loan.dueDate)})
        else
            exports.ox_lib:notify({type = 'info', description = '您没有未偿还的贷款.'})
        end
    end
    
    RegisterNetEvent('bank:updateLoanInfo')
    AddEventHandler('bank:updateLoanInfo', function(loan)
        playerLoans[GetPlayerServerId(PlayerId())] = loan
    end)
    
    ## `client_atm.lua` (用于ATM)
    lua
    local ESX = nil
    local isNearATM = false

    Citizen.CreateThread(function()
        while ESX == nil do
            TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)
            Citizen.Wait(10)
        end
       
        local atmModels = {}
        for i = 1, #Config.ATMModels do
            table.insert(atmModels, GetHashKey(Config.ATMModels))
        end

        exports.ox_target:addModel({
            models = atmModels,
            options = {
                {
                    event = 'bank:openATMMenu',
                    icon = 'fas fa-credit-card',
                    label = '打开ATM菜单'
                }
            }
        })
    end)

    RegisterNetEvent('bank:openATMMenu')
    AddEventHandler('bank:openATMMenu', function()
        if hasBankCard() then
            openMenu('atm')
        else
            exports.ox_lib:notify({type = 'error', description = '你没有银行卡'})
        end
    end)

    function hasBankCard()
        return exports.ox_inventory:Search('slots', Config.BankCardItem) ~= nil
    end

    function openMenu(type)
        local loan = playerLoans[GetPlayerServerId(PlayerId())]
        local elements = {
            {label = '转账', value = 'transfer'},
            {label = '收款', value = 'withdraw'},
            {label = '查询贷款信息', value = 'loan_info'}
        }
       
        exports.ox_target:openUI({
            title = 'ATM菜单',
            align = 'top',
            elements = elements,
            onSelect = function(data)
                if data.value == 'transfer' then
                    showTransferMenu()
                elseif data.value == 'withdraw' then
                    showWithdrawMenu(type)
                elseif data.value == 'loan_info' then
                    showLoanInfoMenu(loan)
                end
            end
        })
    end

    function showTransferMenu()
        local elements = {}
        for _, amount in ipairs(Config.TransferAmounts) do
            table.insert(elements, {label = tostring(amount), value = amount})
        end
       
        table.insert(elements, {label = '自定义金额', value = 'custom'})

        exports.ox_target:openUI({
            title = '选择转账金额',
            align = 'top',
            elements = elements,
            onSelect = function(data)
                if data.value == 'custom' then
                    exports.ox_target:openInputDialogue({
                        title = '输入转账金额',
                    }, function(inputData)
                        local amount = tonumber(inputData.value)
                        if amount == nil or amount <= 0 then
                            exports.ox_lib:notify({type = 'error', description = '请输入有效金额'})
                        else
                            openTransferTargetMenu(amount)
                        end
                    end)
                else
                    openTransferTargetMenu(data.value)
                end
            end
        })
    end

    function openTransferTargetMenu(amount)
        exports.ox_target:openInputDialogue({
            title = '输入目标玩家ID',
        }, function(inputData)
            local target_id = tonumber(inputData.value)
            if target_id == nil or target_id <= 0 then
                exports.ox_lib:notify({type = 'error', description = '请输入有效的玩家ID'})
            else
                exports.ox_target:openInputDialogue({
                    title = '输入目标银行卡号',
                }, function(inputData)
                    local target_card = inputData.value
                    if not target_card or target_card == '' then
                        exports.ox_lib:notify({type = 'error', description = '请输入有效的银行卡号'})
                    else
                        TriggerServerEvent('bank:transfer', target_id, target_card, amount)
                    end
                end)
            end
        end)
    end

    function showWithdrawMenu()
        exports.ox_target:openInputDialogue({
            title = '输入取款金额',
        }, function(inputData)
            local amount = tonumber(inputData.value)
            if amount == nil or amount <= 0 then
                exports.ox_lib:notify({type = 'error', description = '请输入有效金额'})
            else
                TriggerServerEvent('bank:withdraw', amount)
            end
        end)
    end

    function showLoanInfoMenu(loan)
        if loan then
            local repayAmount = loan.amount * (1 + Config.InterestRate * loan.months)
            exports.ox_lib:notify({type = 'info', description = '贷款金额: '..loan.amount..'\n总还款金额: '..repayAmount..'\n还款截止日期: '..os.date('%Y-%m-%d %H:%M:%S', loan.dueDate)})
        else
            exports.ox_lib:notify({type = 'info', description = '您没有未偿还的贷款.'})
        end
    end

    RegisterNetEvent('bank:updateLoanInfo')
    AddEventHandler('bank:updateLoanInfo', function(loan)
        playerLoans[GetPlayerServerId(PlayerId())] = loan
    end)

    ### 已实现需求:
    1. 显示所有银行的图标,坐标可在 `config.lua` 中修改。
    2. 自动检测 ATM 模型,无需坐标,可在 `config.lua` 中修改。
    3. 功能:转账、收款、贷款以及还贷款的钱。
    4. 只有使用银行卡才能打开ATM和银行菜单,没有银行卡时提示。
    5. 使用`ox_inventory`检查银行卡。
    6. 转账、收款、贷款以及还贷款的具体实现。
    7. 本地记录玩家的贷款信息和利息。
    8. 使用OX通知和UI。

    注意:以上脚本假定你已经安装并使用 `ox_target`, `ox_inventory`, 和 `ox_lib`。根据你的实际情况,你可能需要对部分代码进行调整。
    回复

    使用道具 举报

    升级进度: 60%

     楼主| lizhuoda 发表于 2024-8-18 15:57:41 | 显示全部楼层
    ChatGPT 发表于 2024-8-18 15:54
    明白了,你希望取消数据库的使用,只需要使用客户端本地存储即可。因此,我们需要用本地变量来记录玩家的 ...

    请演示一下如何添加
    回复

    使用道具 举报

    ChatGPT 发表于 2024-8-18 15:58:57 | 显示全部楼层
    lizhuoda 发表于 2024-08-18 15:57
    请演示一下如何添加


    好的,我们现在详细演示一下如何添加银行和ATM功能。为了满足你的需求,我们会分别创建`config.lua`、`client_banking.lua`和`client_atm.lua`,并且确保这些文件都位于同一个资源目录中。这里演示的代码将不使用数据库,而是使用本地变量来存储贷款信息。

    ### 1. `config.lua`
    首先,创建一个`config.lua`文件来保存所有配置:
    -- config.lua
    Config = {}
    
    -- 所有银行的坐标
    Config.Banks = {
        {name = "Fleeca Bank", coords = vector3(150.0, -1040.0, 29.0)},
        {name = "Blaine County Savings Bank", coords = vector3(-112.1, 6469.2, 31.6)}
        -- 添加更多银行信息
    }
    
    -- 自动检测的ATM模型,在这里添加ATM模型的哈希值
    Config.ATMModels = {
        "prop_atm_01",
        "prop_atm_02",
        "prop_atm_03",
        "prop_fleeca_atm"
    }
    
    -- 银行卡项目名称
    Config.BankCardItem = "bank_card"
    
    -- 可修改的转账金额选项
    Config.TransferAmounts = {1000, 2000, 3000, 4000, 5000}
    
    -- 可修改的贷款金额选项
    Config.LoanAmounts = {1000, 2000, 3000, 4000, 5000}
    
    -- 最大贷款月份
    Config.MaxLoanMonths = 12
    
    -- 每月利息百分比
    Config.InterestRate = 0.02
    
    -- 游戏公告提醒
    Config.DueNoticeMessage = "您有未还的贷款到期了,请尽快还款!"

    ### 2. `client_banking.lua`
    接下来,创建一个`client_banking.lua`文件来处理银行相关的功能:
    local ESX = nil
    local isNearBank = false
    local playerLoans = {} -- 本地记录玩家贷款信息
    
    Citizen.CreateThread(function()
        -- 初始化ESX
        while ESX == nil do
            TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)
            Citizen.Wait(10)
        end
    
        -- 为所有银行添加Blip
        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
    
        -- 添加银行目标区域
        Citizen.CreateThread(function()
            for _, bank in ipairs(Config.Banks) do
                exports.ox_target:addBoxZone({
                    name = bank.name,
                    coords = bank.coords,
                    size = vec3(3, 3, 3),
                    options = {
                        {
                            event = 'bank:openBankMenu',
                            icon = 'fas fa-university',
                            label = '打开银行菜单'
                        }
                    }
                })
            end
        end)
    end)
    
    RegisterNetEvent('bank:openBankMenu')
    AddEventHandler('bank:openBankMenu', function()
        if hasBankCard() then
            openMenu('bank')
        else
            exports.ox_lib:notify({type = 'error', description = '你没有银行卡'})
        end
    end)
    
    function hasBankCard()
        return exports.ox_inventory:Search('slots', Config.BankCardItem) ~= nil
    end
    
    function openMenu(type)
        local loan = playerLoans
        local elements = {
            {label = '转账', value = 'transfer'},
            {label = '收款', value = 'withdraw'},
            {label = '贷款', value = 'loan'},
            {label = '查询贷款信息', value = 'loan_info'}
        }
        
        exports.ox_target:openUI({
            title = '银行菜单',
            align = 'top',
            elements = elements,
            onSelect = function(data)
                if data.value == 'transfer' then
                    showTransferMenu()
                elseif data.value == 'withdraw' then
                    showWithdrawMenu(type)
                elseif data.value == 'loan' then
                    showLoanMenu()
                elseif data.value == 'loan_info' then
                    showLoanInfoMenu(loan)
                end
            end
        })
    end
    
    function showTransferMenu()
        local elements = {}
        for _, amount in ipairs(Config.TransferAmounts) do
            table.insert(elements, {label = tostring(amount), value = amount})
        end
        
        table.insert(elements, {label = '自定义金额', value = 'custom'})
    
        exports.ox_target:openUI({
            title = '选择转账金额',
            align = 'top',
            elements = elements,
            onSelect = function(data)
                if data.value == 'custom' then
                    exports.ox_target:openInputDialogue({
                        title = '输入转账金额',
                    }, function(inputData)
                        local amount = tonumber(inputData.value)
                        if amount then
                            menu.close()
                            exports.ox_target:openInputDialogue({
                                title = '输入目标玩家ID'
                            }, function(data2)
                                local target_id = tonumber(data2.value)
                                if target_id then
                                    exports.ox_target:openInputDialogue({
                                        title = '输入目标银行卡号'
                                    }, function(data3)
                                        local target_card = data3.value
                                        if target_card then
                                            TriggerServerEvent('bank:transfer', target_id, target_card, amount)
                                        else
                                            exports.ox_lib:notify({type = 'error', description = '请输入有效的银行卡号'})
                                        end
                                    end)
                                else
                                    exports.ox_lib:notify({type = 'error', description = '请输入有效的玩家ID'})
                                end
                            end)
                        else
                            exports.ox_lib:notify({type = 'error', description = '请输入有效金额'})
                        end
                    end)
                else
                    local amount = data.value
                    exports.ox_target:openInputDialogue({
                        title = '输入目标玩家ID'
                    }, function(data2)
                        local target_id = tonumber(data2.value)
                        if target_id then
                            exports.ox_target:openInputDialogue({
                                title = '输入目标银行卡号'
                            }, function(data3)
                                local target_card = data3.value
                                if target_card then
                                    TriggerServerEvent('bank:transfer', target_id, target_card, amount)
                                else
                                    exports.ox_lib:notify({type = 'error', description = '请输入有效的银行卡号'})
                                end
                            end)
                        else
                            exports.ox_lib:notify({type = 'error', description = '请输入有效的玩家ID'})
                        end
                    end)
                end
            end
        })
    end
    
    function showWithdrawMenu(type)
        exports.ox_target:openInputDialogue({
            title = '输入取款金额',
        }, function(data)
            local amount = tonumber(data.value)
            if amount then
                TriggerServerEvent('bank:withdraw', amount, type) -- 传递类型以区分银行和ATM
            else
                exports.ox_lib:notify({type = 'error', description = '请输入有效金额'})
            end
        end)
    end
    
    function showLoanMenu()
        local elements = {}
        for _, amount in ipairs(Config.LoanAmounts) do
            table.insert(elements, {label = tostring(amount), value = amount})
        end
        
        table.insert(elements, {label = '自定义金额', value = 'custom'})
    
        exports.ox_target:openUI({
            title = '选择贷款金额',
            align = 'top',
            elements = elements,
            onSelect = function(data)
                if data.value == 'custom' then
                    exports.ox_target:openInputDialogue({
                        title = '输入贷款金额',
                    }, function(inputData)
                        local amount = tonumber(inputData.value)
                        if amount then
                            exports.ox_target:openInputDialogue({
                                title = '输入还款期限(1到'..Config.MaxLoanMonths..'月)',
                            }, function(data2)
                                local months = tonumber(data2.value)
                                if months and months >= 1 and months <= Config.MaxLoanMonths then
                                    local interest = Config.InterestRate * months
                                    local repay = amount * (1 + interest)
                                    playerLoans = {amount = amount, repay = repay, dueDate = os.time() + months * 30 * 24 * 60 * 60}
                                    exports.ox_lib:notify({type = 'success', description = '贷款成功'})
                                else
                                    exports.ox_lib:notify({type = 'error', description = '请输入有效的还款期限'})
                                end
                            end)
                        else
                            exports.ox_lib:notify({type = 'error', description = '请输入有效的贷款金额'})
                        end
                    end)
                else
                    local amount = data.value
                    exports.ox_target:openInputDialogue({
                        title = '输入还款期限(1到'..Config.MaxLoanMonths..'月)',
                    }, function(data2)
                        local months = tonumber(data2.value)
                        if months and months >= 1 and months <= Config.MaxLoanMonths then
                            local interest = Config.InterestRate * months
                            local repay = amount * (1 + interest)
                            playerLoans = {amount = amount, repay = repay, dueDate = os.time() + months * 30 * 24 * 60 * 60}
                            exports.ox_lib:notify({type = 'success', description = '贷款成功'})
                        else
                            exports.ox_lib:notify({type = 'error', description = '请输入有效的还款期限'})
                        end
                    end)
                end
            end
        })
    end
    
    function showLoanInfoMenu(loan)
        if loan.amount then
            local timeToRepay = os.date('%Y-%m-%d %H:%M:%S', loan.dueDate)
            exports.ox_lib:notify({
                type = 'info',
                description = string.format('贷款金额: %d\n总还款金额: %d\n还款截止日期: %s', loan.amount, loan.repay, timeToRepay)
            })
        else
            exports.ox_lib:notify({type = 'info', description = '您没有未偿还的贷款.'})
        end
    end
    
    ### `client_atm.lua` (用于自动检测ATM模型和ATM功能)
    lua
    local ESX = nil
    local isNearATM = false

    Citizen.CreateThread(function()
        while ESX == nil do
            TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)
            Citizen.Wait(10)
        end

        local atmModels = {}
        for i = 1, #Config.ATMModels do
            table.insert(atmModels, GetHashKey(Config.ATMModels))
        end

        exports.ox_target:addModel({
            models = atmModels,
            options = {
                {
                    event = 'atm:openATMMenu',
                    icon = 'fas fa-credit-card',
                    label = '打开ATM菜单'
                }
            }
        })
    end)

    RegisterNetEvent('atm:openATMMenu')
    AddEventHandler('atm:openATMMenu', function()
        if hasBankCard() then
            openMenu('atm')
        else
            exports.ox_lib:notify({type = 'error', description = '你没有银行卡'})
        end
    end)

    function hasBankCard()
        return exports.ox_inventory:Search('slots', Config.BankCardItem) ~= nil
    end

    function openMenu(type)
        local loan = playerLoans
        local elements = {
            {label = '转账', value = 'transfer'},
            {label = '收款', value = 'withdraw'},
            {label = '查询贷款信息', value = 'loan_info'}
        }
       
        exports.ox_target:openUI({
            title = 'ATM菜单',
            align = 'top',
            elements = elements,
            onSelect = function(data)
                if data.value == 'transfer' then
                    showTransferMenu()
                elseif data.value == 'withdraw' then
                    showWithdrawMenu(type)
                elseif data.value == 'loan_info' then
                    showLoanInfoMenu(loan)
                end
            end
        })
    end

    function showTransferMenu()
        local elements = {}
        for _, amount in ipairs(Config.TransferAmounts) do
            table.insert(elements, {label = tostring(amount), value = amount})
        end
       
        table.insert(elements, {label = '自定义金额', value = 'custom'})

        exports.ox_target:openUI({
            title = '选择转账金额',
            align = 'top',
            elements = elements,
            onSelect = function(data)
                if data.value == 'custom' then
                    exports.ox_target:openInputDialogue({
                        title = '输入转账金额',
                    }, function(inputData)
                        local amount = tonumber(inputData.value)
                        if amount then
                            menu.close()
                            exports.ox_target:openInputDialogue({
                                title = '输入目标玩家ID'
                            }, function(data2)
                                local target_id = tonumber(data2.value)
                                if target_id then
                                    exports.ox_target:openInputDialogue({
                                        title = '输入目标银行卡号'
                                    }, function(data3)
                                        local target_card = data3.value
                                        if target_card then
                                            TriggerServerEvent('bank:transfer', target_id, target_card, amount)
                                        else
                                            exports.ox_lib:notify({type = 'error', description = '请输入有效的银行卡号'})
                                        end
                                    end)
                                else
                                    exports.ox_lib:notify({type = 'error', description = '请输入有效的玩家ID'})
                                end
                            end)
                        else
                            exports.ox_lib:notify({type = 'error', description = '请输入有效金额'})
                        end
                    end)
                else
                    local amount = data.value
                    exports.ox_target:openInputDialogue({
                        title = '输入目标玩家ID'
                    }, function(data2)
                        local target_id = tonumber(data2.value)
                        if target_id then
                            exports.ox_target:openInputDialogue({
                                title = '输入目标银行卡号'
                            }, function(data3)
                                local target_card = data3.value
                                if target_card then
                                    TriggerServerEvent('bank:transfer', target_id, target_card, amount)
                                else
                                    exports.ox_lib:notify({type = 'error', description = '请输入有效的银行卡号'})
                                end
                            end)
                        else
                            exports.ox_lib:notify({type = 'error', description = '请输入有效的玩家ID'})
                        end
                    end)
                end
            end
        })
    end

    function showWithdrawMenu(type)
        exports.ox_target:openInputDialogue({
            title = '输入取款金额',
        }, function(data)
            local amount = tonumber(data.value)
            if amount then
                TriggerServerEvent('bank:withdraw', amount, type)
            else
                exports.ox_lib:notify({type = 'error', description = '请输入有效金额'})
            end
        end)
    end

    function showLoanInfoMenu(loan)
        if loan.amount then
            local timeToRepay = os.date('%Y-%m-%d %H:%M:%S', loan.dueDate)
            exports.ox_lib:notify({
                type = 'info',
                description = string.format('贷款金额: %d\n总还款金额: %d\n还款截止日期: %s', loan.amount, loan.repay, timeToRepay)
            })
        else
            exports.ox_lib:notify({type = 'info', description = '您没有未偿还的贷款.'})
        end
    end

    ### `__resource.lua` (或 `fxmanifest.lua`)
    最后,需要编辑 `__resource.lua` 或 `fxmanifest.lua` 文件来加载这些脚本:
    -- __resource.lua 或 fxmanifest.lua
    
    resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937'
    
    description 'Banking and ATM System'
    
    client_scripts {
        'config.lua',
        'client_banking.lua',
        'client_atm.lua'
    }
    
    server_scripts {
        'server.lua'
    }

    ### `server.lua`
    此文件将用于处理服务器端的交易逻辑,例如转账和取款:
    ESX = nil
    
    TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)
    
    RegisterServerEvent('bank:transfer')
    AddEventHandler('bank:transfer', function(target_id, target_card, amount)
        local xPlayer = ESX.GetPlayerFromId(source)
        local targetPlayer = ESX.GetPlayerFromId(target_id)
    
        if xPlayer and targetPlayer then
            if xPlayer.getAccount('bank').money >= amount then
                xPlayer.removeAccountMoney('bank', amount)
                targetPlayer.addAccountMoney('bank', amount)
                TriggerClientEvent('ox_lib:notify', xPlayer.source, {type = 'success', description = '转账成功'})
                TriggerClientEvent('ox_lib:notify', targetPlayer.source, {type = 'success', description = '您收到了一笔转账'})
            else
                TriggerClientEvent('ox_lib:notify', xPlayer.source, {type = 'error', description = '银行余额不足'})
            end
        end
    end)
    
    RegisterServerEvent('bank:withdraw')
    AddEventHandler('bank:withdraw', function(amount, type)
        local xPlayer = ESX.GetPlayerFromId(source)
        if xPlayer.getAccount('bank').money >= amount then
            xPlayer.removeAccountMoney('bank', amount)
            xPlayer.addMoney(amount)
            TriggerClientEvent('ox_lib:notify', xPlayer.source, {type = 'success', description = '取款成功'})
        else
            TriggerClientEvent('ox_lib:notify', xPlayer.source, {type = 'error', description = '银行余额不足'})
        end
    end)

    ### 整个文件结构
    确保你的文件结构如下:
    resource_folder/
    ├── __resource.lua 或 fxmanifest.lua
    ├── config.lua
    ├── client_banking.lua
    ├── client_atm.lua
    └── server.lua

    ### 启动资源
    在你的服务器配置文件 (`server.cfg`) 中添加资源启动命令:
    start resource_folder_name

    把 `resource_folder_name` 替换为你资源文件夹的实际名字。在启动服务器后,你应该能够在合适的地点使用银行和ATM功能了。
    回复

    使用道具 举报

    文明发言,和谐互动
    文明发言,和谐互动
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|Archiver|小黑屋|首页 ( 冀ICP备2021005225号-1 ) |网站地图

    GMT+8, 2024-11-25 03:50 , Processed in 0.091999 second(s), 9 queries , Gzip On, Redis On.

    Powered by Discuz! X3.4

    © 2001-2013 ELITE论坛【技术无价-分享快乐】

    快速回复 返回顶部 返回列表