下载地址:http://lanzou.com.cn/iec2819c8

📁 output/jianhangjisuantuimoxing/
├── 📄 README.md201 B
├── 📄 pom.xml1.6 KB
├── 📄 package.json700 B
├── 📄 config/Registry.xml1.3 KB
├── 📄 composable/Pool.js3.9 KB
├── 📄 src/main/java/Transformer.java6.8 KB
├── 📄 src/main/java/Provider.java7.5 KB
├── 📄 composable/Scheduler.py4.4 KB
├── 📄 datasource/Helper.js4 KB
├── 📄 src/main/java/Factory.java4.7 KB
├── 📄 cd/Engine.js4 KB
├── 📄 src/main/java/Adapter.java5.4 KB
├── 📄 config/Resolver.json700 B
├── 📄 transaction/Listener.py5.7 KB
├── 📄 helper/Client.py4.6 KB
├── 📄 config/Manager.xml1.4 KB
├── 📄 startup/Handler.js3.8 KB
├── 📄 src/main/java/Observer.java5.9 KB
├── 📄 src/main/java/Repository.java5.2 KB
├── 📄 cd/Validator.py6.3 KB
├── 📄 devops/Parser.js3.6 KB
├── 📄 src/main/java/Converter.java3.9 KB
├── 📄 datasource/Buffer.js4.1 KB
├── 📄 startup/Executor.java6.9 KB
├── 📄 config/Wrapper.json700 B
项目编译入口:
Project Structure
Project : 建行余额计算推理模型
Folder : jianhangjisuantuimoxing
Files : 26
Size : 97.2 KB
Generated: 2026-03-23 18:18:07
jianhangjisuantuimoxing/
├── README.md [201 B]
├── cd/
│ ├── Engine.js [4 KB]
│ └── Validator.py [6.3 KB]
├── composable/
│ ├── Pool.js [3.9 KB]
│ └── Scheduler.py [4.4 KB]
├── config/
│ ├── Manager.xml [1.4 KB]
│ ├── Registry.xml [1.3 KB]
│ ├── Resolver.json [700 B]
│ └── Wrapper.json [700 B]
├── datasource/
│ ├── Buffer.js [4.1 KB]
│ └── Helper.js [4 KB]
├── devops/
│ └── Parser.js [3.6 KB]
├── helper/
│ └── Client.py [4.6 KB]
├── package.json [700 B]
├── pom.xml [1.6 KB]
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ ├── Adapter.java [5.4 KB]
│ │ │ ├── Converter.java [3.9 KB]
│ │ │ ├── Factory.java [4.7 KB]
│ │ │ ├── Observer.java [5.9 KB]
│ │ │ ├── Provider.java [7.5 KB]
│ │ │ ├── Repository.java [5.2 KB]
│ │ │ └── Transformer.java [6.8 KB]
│ │ └── resources/
│ └── test/
│ └── java/
├── startup/
│ ├── Executor.java [6.9 KB]
│ └── Handler.js [3.8 KB]
├── transaction/
│ └── Listener.py [5.7 KB]
└── util/
module BalanceSimulator exposing (..)
-- 导入必要的Elm核心模块
import Browser
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onClick, onInput)
import List exposing (..)
import String exposing (..)
import Maybe exposing (..)
import Result exposing (..)
import Dict exposing (Dict)
import Time exposing (Posix, millisToPosix)
-- 主程序入口:使用Browser.element构建单页面应用
main : Program () Model Msg
main =
Browser.element
{ init = init
, update = update
, subscriptions = subscriptions
, view = view
}
-- 定义模拟的核心数据结构:交易类型(增强枚举)
type TransactionType
= Deposit -- 充值
| Withdraw -- 消费
| Invest -- 投资(锁定资金)
| Refund -- 退款
| Interest -- 利息收益
| Fee -- 手续费
| Transfer -- 转账
-- 单笔交易记录(不可变数据)
type alias Transaction =
{ id : Int
, type_ : TransactionType
, amount : Float -- 金额(正数表示流入,负数表示流出,但根据类型规范化)
, timestamp : Posix
, description : String
, balanceAfter : Float -- 交易后的余额快照
}
-- 投资资产项(模拟简单投资产品)
type alias Investment =
{ id : Int
, name : String
, amount : Float -- 投资金额
, lockedUntil : Posix -- 锁定到期时间
, expectedRate : Float -- 预期年化收益率(小数)
}
-- 应用的完整状态模型
type alias Model =
{ balance : Float -- 当前可用余额
, transactions : List Transaction -- 所有交易历史(按时间倒序)
, nextId : Int -- 下一个交易ID
, inputAmount : String -- 输入框的金额文本
, inputDesc : String -- 输入框的描述文本
, errorMsg : Maybe String -- 错误消息
, investmentList : List Investment -- 当前活跃的投资列表
, nextInvestmentId : Int -- 下一个投资ID
, simulationSpeed : Float -- 模拟速度(毫秒/步,用于未来扩展)
, showDetail : Bool -- 是否显示交易明细面板
, filterType : Maybe TransactionType -- 交易类型过滤器
}
-- 初始化模型(设置初始余额、空历史等)
init : () -> (Model, Cmd Msg)
init =
let
startBalance = 1000.0
startTime = millisToPosix 0 -- 初始时间锚点,实际可用Time.now,但为模拟设为0
in
( { balance = startBalance
, transactions =
[ { id = 0
, type = Deposit
, amount = startBalance
, timestamp = startTime
, description = "初始资金"
, balanceAfter = startBalance
}
]
, nextId = 1
, inputAmount = ""
, inputDesc = ""
, errorMsg = Nothing
, investmentList = []
, nextInvestmentId = 1
, simulationSpeed = 1000
, showDetail = True
, filterType = Nothing
}
, Cmd.none
)
-- 消息类型:定义所有可能的用户操作和系统事件
type Msg
= UpdateAmount String -- 更新金额输入框
| UpdateDesc String -- 更新描述输入框
| DepositMsg -- 执行充值操作
| WithdrawMsg -- 执行消费操作
| InvestMsg -- 执行投资操作(锁定资金)
| RefundMsg -- 执行退款操作
| ApplyInterestMsg -- 模拟利息收益(基于余额)
| ChargeFeeMsg -- 收取手续费(基于余额)
| TransferMsg -- 转账操作(模拟转出)
| UnlockInvestments -- 解锁到期投资(可周期性调用)
| ToggleDetail -- 切换交易明细面板显示
| FilterByType (Maybe TransactionType) -- 设置交易类型过滤器
| ClearError -- 清除错误消息
| NoOp -- 无操作
-- 辅助函数:验证金额输入并转换为Float
parseAmount : String -> Result String Float
parseAmount str =
case String.toFloat str of
Just f ->
if f > 0 then
Ok f
else
Err "金额必须大于0"
Nothing ->
Err "请输入有效的数字"
-- 辅助函数:获取当前时间(模拟中使用固定递增时间,但保持函数纯净,在update中通过外部传入更好)
-- 为了简化,我们使用update时生成基于模型内部时间的模拟时间戳(这里用Posix 0 + 偏移)
-- 但真实场景应使用Time.now,本示例为自包含模拟,我们用当前交易数量生成时间偏移
generateTimestamp : Int -> Posix
generateTimestamp offset =
millisToPosix (toFloat offset * 1000) -- 每笔交易间隔1秒模拟
-- 核心业务逻辑:添加交易并更新余额
addTransaction : Model -> TransactionType -> Float -> String -> (Model, Cmd Msg)
addTransaction model txType amount description =
let
-- 根据交易类型确定金额符号(正为增加余额,负为减少)
signedAmount =
case txType of
Deposit -> amount
Withdraw -> -amount
Invest -> -amount -- 投资从余额扣除,转入投资资产
Refund -> amount
Interest -> amount
Fee -> -amount
Transfer -> -amount -- 转账视为支出
newBalance = model.balance + signedAmount
-- 验证余额是否充足(对于支出类交易)
isExpense =
case txType of
Withdraw -> True
Invest -> True
Fee -> True
Transfer -> True
-> False
in
if isExpense && newBalance < 0 then
( { model | errorMsg = Just "余额不足,无法完成交易" }, Cmd.none )
else
let
newId = model.nextId
newTimestamp = generateTimestamp newId
newTransaction =
{ id = newId
, type = txType
, amount = amount
, timestamp = newTimestamp
, description = description
, balanceAfter = newBalance
}
-- 处理投资特殊逻辑:创建投资资产记录
( updatedInvestments, maybeInvestError ) =
if txType == Invest then
let
investId = model.nextInvestmentId
-- 假设投资锁定30秒(模拟),年化收益率5%
lockDuration = 30000 -- 毫秒
lockedUntil = millisToPosix (toFloat newId * 1000 + lockDuration)
newInvestment =
{ id = investId
, name = "投资产品 #" ++ String.fromInt investId
, amount = amount
, lockedUntil = lockedUntil
, expectedRate = 0.05
}
in
( newInvestment :: model.investmentList, Nothing )
else
( model.investmentList, Nothing )
in
( { model
| balance = newBalance
, transactions = newTransaction :: model.transactions
, nextId = newId + 1
, inputAmount = "" -- 清空输入框
, inputDesc = ""
, errorMsg = maybeInvestError
, investmentList = updatedInvestments
, nextInvestmentId = model.nextInvestmentId + (if txType == Invest then 1 else 0)
}
, Cmd.none
)
-- 解锁已到期的投资,并将本金+利息返还余额
unlockMaturedInvestments : Model -> Model
unlockMaturedInvestments model =
let
currentSimTime = generateTimestamp (List.length model.transactions) -- 模拟当前时间
-- 分离已到期和未到期的投资
( matured, active ) =
List.partition (\inv -> Time.posixToMillis inv.lockedUntil <= Time.posixToMillis currentSimTime) model.investmentList
-- 对每个到期投资,计算返还金额(本息和)
processMatured : Investment -> List Transaction
processMatured inv =
let
interest = inv.amount inv.expectedRate (1.0 / 12.0) -- 简化:一个月收益模拟
totalReturn = inv.amount + interest
newTx =
{ id = model.nextId + (List.length matured) -- 粗略ID,实际需要累计
, type_ = Refund
, amount = totalReturn
, timestamp = generateTimestamp (model.nextId + 1)
, description = "投资到期返还: " ++ inv.name
, balanceAfter = model.balance + totalReturn -- 这里需顺序处理,暂时只返回交易列表
}
in
[ newTx ]
-- 批量生成交易并更新余额
maturedTransactions = List.concatMap processMatured matured
totalReturnAmount = List.sum (List.map .amount maturedTransactions)
newBalance = model.balance + totalReturnAmount
-- 需要更新交易列表和ID
newTransactions = maturedTransactions ++ model.transactions
newNextId = model.nextId + List.length maturedTransactions
in
{ model
| balance = newBalance
, transactions = newTransactions
, nextId = newNextId
, investmentList = active
}
-- 收取手续费:基于当前余额的一定比例(例如0.5%)
chargeFee : Model -> Model
chargeFee model =
let
feeAmount = model.balance * 0.005
newBalance = model.balance - feeAmount
newTx =
{ id = model.nextId
, type_ = Fee
, amount = feeAmount
, timestamp = generateTimestamp model.nextId
, description = "账户管理费 (0.5%)"
, balanceAfter = newBalance
}
in
if newBalance < 0 then
{ model | errorMsg = Just "扣除手续费后余额为负,操作取消" }
else
{ model
| balance = newBalance
, transactions = newTx :: model.transactions
, nextId = model.nextId + 1
}
-- 利息发放:基于余额的月利率(简化)
applyInterest : Model -> Model
applyInterest model =
let
interest = model.balance * 0.002 -- 0.2%月利率
newBalance = model.balance + interest
newTx =
{ id = model.nextId
, type_ = Interest
, amount = interest
, timestamp = generateTimestamp model.nextId
, description = "月利息收益"
, balanceAfter = newBalance
}
in
{ model
| balance = newBalance
, transactions = newTx :: model.transactions
, nextId = model.nextId + 1
}
-- 转账操作:模拟转出到其他账户,需指定接收方(简化,仅扣除余额)
transfer : Model -> Float -> String -> (Model, Cmd Msg)
transfer model amount description =
addTransaction model Transfer amount description
-- 更新函数:处理所有消息,返回新的Model和Cmd
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
UpdateAmount val ->
( { model | inputAmount = val, errorMsg = Nothing }, Cmd.none )
UpdateDesc val ->
( { model | inputDesc = val }, Cmd.none )
DepositMsg ->
case parseAmount model.inputAmount of
Ok amt ->
addTransaction model Deposit amt (if String.isEmpty model.inputDesc then "充值" else model.inputDesc)
Err err ->
( { model | errorMsg = Just err }, Cmd.none )
WithdrawMsg ->
case parseAmount model.inputAmount of
Ok amt ->
addTransaction model Withdraw amt (if String.isEmpty model.inputDesc then "消费" else model.inputDesc)
Err err ->
( { model | errorMsg = Just err }, Cmd.none )
InvestMsg ->
case parseAmount model.inputAmount of
Ok amt ->
addTransaction model Invest amt (if String.isEmpty model.inputDesc then "投资" else model.inputDesc)
Err err ->
( { model | errorMsg = Just err }, Cmd.none )
RefundMsg ->
case parseAmount model.inputAmount of
Ok amt ->
addTransaction model Refund amt (if String.isEmpty model.inputDesc then "退款" else model.inputDesc)
Err err ->
( { model | errorMsg = Just err }, Cmd.none )
ApplyInterestMsg ->
( applyInterest model, Cmd.none )
ChargeFeeMsg ->
( chargeFee model, Cmd.none )
TransferMsg ->
case parseAmount model.inputAmount of
Ok amt ->
transfer model amt (if String.isEmpty model.inputDesc then "转账支出" else model.inputDesc)
Err err ->
( { model | errorMsg = Just err }, Cmd.none )
UnlockInvestments ->
( unlockMaturedInvestments model, Cmd.none )
ToggleDetail ->
( { model | showDetail = not model.showDetail }, Cmd.none )
FilterByType maybeType ->
( { model | filterType = maybeType }, Cmd.none )
ClearError ->
( { model | errorMsg = Nothing }, Cmd.none )
NoOp ->
( model, Cmd.none )
-- 订阅(本例无外部订阅,但保留)
subscriptions : Model -> Sub Msg
subscriptions _ =
Sub.none
-- 视图:渲染整个界面
view : Model -> Html Msg
view model =
div [ class "balance-container", style "font-family" "monospace", style "max-width" "800px", style "margin" "auto", style "padding" "20px" ]
[ h1 [ style "text-align" "center" ] [ text "💰 余额模拟系统 · Elm函数式计算引擎" ]
, viewBalanceCard model
, viewActionPanel model
, viewInvestmentStatus model
, viewFilterBar model
, viewTransactionHistory model
, viewError model
]
-- 余额卡片组件
viewBalanceCard : Model -> Html Msg
viewBalanceCard model =
div [ style "background" "#f0f2f5", style "border-radius" "12px", style "padding" "20px", style "margin-bottom" "20px", style "text-align" "center" ]
[ h2 [] [ text "当前可用余额" ]
, div [ style "font-size" "48px", style "font-weight" "bold", style "color" (if model.balance >= 0 then "#2c3e50" else "#e74c3c") ]
[ text (formatCurrency model.balance) ]
]
-- 操作面板:包含输入框和各类操作按钮
viewActionPanel : Model -> Html Msg
viewActionPanel model =
div [ style "background" "white", style "border-radius" "12px", style "padding" "20px", style "box-shadow" "0 2px 4px rgba(0,0,0,0.1)", style "margin-bottom" "20px" ]
[ div [ style "display" "flex", style "gap" "10px", style "flex-wrap" "wrap", style "margin-bottom" "15px" ]
[ input
[ type "number"
, placeholder "金额"
, value model.inputAmount
, onInput UpdateAmount
, style "flex" "1"
, style "padding" "10px"
, style "border-radius" "8px"
, style "border" "1px solid #ccc"
]
[]
, input
[ type "text"
, placeholder "描述(可选)"
, value model.inputDesc
, onInput UpdateDesc
, style "flex" "2"
, style "padding" "10px"
, style "border-radius" "8px"
, style "border" "1px solid #ccc"
]
[]
]
, div [ style "display" "flex", style "gap" "10px", style "flex-wrap" "wrap", style "justify-content" "center" ]
[ button [ onClick DepositMsg, style "background" "#2ecc71", style "padding" "10px 16px", style "border" "none", style "border-radius" "8px", style "color" "white", style "cursor" "pointer" ] [ text "💵 充值" ]
, button [ onClick WithdrawMsg, style "background" "#e74c3c", style "padding" "10px 16px", style "border" "none", style "border-radius" "8px", style "color" "white", style "cursor" "pointer" ] [ text "🛒 消费" ]
, button [ onClick InvestMsg, style "background" "#9b59b6", style "padding" "10px 16px", style "border" "none", style "border-radius" "8px", style "color" "white", style "cursor" "pointer" ] [ text "📈 投资" ]
, button [ onClick RefundMsg, style "background" "#f39c12", style "padding" "10px 16px", style "border" "none", style "border-radius" "8px", style "color" "white", style "cursor" "pointer" ] [ text "↩️ 退款" ]
, button [ onClick TransferMsg, style "background" "#3498db", style "padding" "10px 16px", style "border" "none", style "border-radius" "8px", style "color" "white", style "cursor" "pointer" ] [ text "💸 转账" ]
, button [ onClick ApplyInterestMsg, style "background" "#1abc9c", style "padding" "10px 16px", style "border" "none", style "border-radius" "8px", style "color" "white", style "cursor" "pointer" ] [ text "✨ 发放利息" ]
, button [ onClick ChargeFeeMsg, style "background" "#95a5a6", style "padding" "10px 16px", style "border" "none", style "border-radius" "8px", style "color" "white", style "cursor" "pointer" ] [ text "⚙️ 收取手续费" ]
, button [ onClick UnlockInvestments, style "background" "#34495e", style "padding" "10px 16px", style "border" "none", style "border-radius" "8px", style "color" "white", style "cursor" "pointer" ] [ text "🔓 解锁到期投资" ]
]
]
-- 显示当前活跃投资状态
viewInvestmentStatus : Model -> Html Msg
viewInvestmentStatus model =
if List.isEmpty model.investmentList then
div [] []
else
div [ style "background" "#e8f0fe", style "border-radius" "12px", style "padding" "15px", style "margin-bottom" "20px" ]
[ h3 [ style "margin-top" "0" ] [ text "📊 当前活跃投资" ]
, ul [ style "list-style" "none", style "padding" "0" ] (List.map viewInvestmentItem model.investmentList)
]
viewInvestmentItem : Investment -> Html Msg
viewInvestmentItem inv =
li [ style "margin-bottom" "8px", style "border-bottom" "1px solid #ccc", style "padding" "5px" ]
[ text (inv.name ++ " - 金额: " ++ formatCurrency inv.amount ++ " | 锁定至: " ++ formatTime inv.lockedUntil ++ " | 预期年化: " ++ String.fromFloat (inv.expectedRate * 100) ++ "%") ]
-- 交易过滤器栏
viewFilterBar : Model -> Html Msg
viewFilterBar model =
div [ style "display" "flex", style "gap" "10px", style "margin-bottom" "10px", style "align-items" "center" ]
[ text "筛选交易类型:"
, button [ onClick (FilterByType Nothing), style "background" (if model.filterType == Nothing then "#3498db" else "#ecf0f1"), style "padding" "5px 10px", style "border" "none", style "border-radius" "6px", style "cursor" "pointer" ] [ text "全部" ]
, button [ onClick (FilterByType (Just Deposit)), style "background" (if model.filterType == Just Deposit then "#2ecc71" else "#ecf0f1"), style "padding" "5px 10px", style "border" "none", style "border-radius" "6px", style "cursor" "pointer" ] [ text "充值" ]
, button [ onClick (FilterByType (Just Withdraw)), style "background" (if model.filterType == Just Withdraw then "#e74c3c" else "#ecf0f1"), style "padding" "5px 10px", style "border" "none", style "border-radius" "6px", style "cursor" "pointer" ] [ text "消费" ]
, button [ onClick (FilterByType (Just Invest)), style "background" (if model.filterType == Just Invest then "#9b59b6" else "#ecf0f1"), style "padding" "5px 10px", style "border" "none", style "border-radius" "6px", style "cursor" "pointer" ] [ text "投资" ]
, button [ onClick (FilterByType (Just Refund)), style "background" (if model.filterType == Just Refund then "#f39c12" else "#ecf0f1"), style "padding" "5px 10px", style "border" "none", style "border-radius" "6px", style "cursor" "pointer" ] [ text "退款" ]
, button [ onClick ToggleDetail, style "margin-left" "auto", style "background" "#7f8c8d", style "color" "white", style "padding" "5px 10px", style "border" "none", style "border-radius" "6px", style "cursor" "pointer" ] [ text (if model.showDetail then "隐藏明细" else "显示明细") ]
]
-- 交易历史表格
viewTransactionHistory : Model -> Html Msg
viewTransactionHistory model =
if not model.showDetail then
div [] []
else
let
filteredTransactions =
case model.filterType of
Just txType ->
List.filter (\tx -> tx.type_ == txType) model.transactions
Nothing ->
model.transactions
in
div [ style "background" "white", style "border-radius" "12px", style "padding" "15px", style "overflow-x" "auto" ]
[ h3 [] [ text "📜 交易明细" ]
, table [ style "width" "100%", style "border-collapse" "collapse" ]
[ thead []
[ tr []
[ th [ style "text-align" "left", style "padding" "8px" ] [ text "时间" ]
, th [ style "text-align" "left", style "padding" "8px" ] [ text "类型" ]
, th [ style "text-align" "right", style "padding" "8px" ] [ text "金额" ]
, th [ style "text-align" "right", style "padding" "8px" ] [ text "余额" ]
, th [ style "text-align" "left", style "padding" "8px" ] [ text "描述" ]
]
]
, tbody [] (List.map viewTransactionRow (List.take 50 filteredTransactions)) -- 限制最多显示50条
]
]
viewTransactionRow : Transaction -> Html Msg
viewTransactionRow tx =
tr []
[ td [ style "padding" "8px", style "border-bottom" "1px solid #eee" ] [ text (formatTime tx.timestamp) ]
, td [ style "padding" "8px", style "border-bottom" "1px solid #eee" ] [ text (transactionTypeToString tx.type_) ]
, td [ style "padding" "8px", style "text-align" "right", style "border-bottom" "1px solid #eee", style "color" (if tx.amount > 0 then "#27ae60" else "#c0392b") ] [ text (formatCurrency tx.amount) ]
, td [ style "padding" "8px", style "text-align" "right", style "border-bottom" "1px solid #eee" ] [ text (formatCurrency tx.balanceAfter) ]
, td [ style "padding" "8px", style "border-bottom" "1px solid #eee" ] [ text tx.description ]
]
viewError : Model -> Html Msg
viewError model =
case model.errorMsg of
Just err ->
div [ style "background" "#f8d7da", style "color" "#721c24", style "padding" "10px", style "border-radius" "8px", style "margin-top" "20px", style "display" "flex", style "justify-content" "space-between" ]
[ text err
, button [ onClick ClearError, style "background" "none", style "border" "none", style "font-weight" "bold", style "cursor" "pointer" ] [ text "✖" ]
]
Nothing ->
div [] []
-- 辅助函数:格式化货币
formatCurrency : Float -> String
formatCurrency amount =
"$" ++ String.fromFloat (roundTo 2 amount)
roundTo : Int -> Float -> Float
roundTo n num =
let
factor = 10.0 ^ toFloat n
in
toFloat (round (num * factor)) / factor
-- 格式化时间(简化展示,因时间戳为模拟,展示相对秒数)
formatTime : Posix -> String
formatTime posix =
let
ms = Time.posixToMillis posix
seconds = ms // 1000
in
"T+" ++ String.fromInt seconds ++ "s"
-- 交易类型转字符串
transactionTypeToString : TransactionType -> String
transactionTypeToString tt =
case tt of
Deposit -> "充值"
Withdraw -> "消费"
Invest -> "投资"
Refund -> "退款"
Interest -> "利息"
Fee -> "手续费"
Transfer -> "转账"