Initial commit: 金牛集团贷款档案管理系统

导入现有代码与文档,排除 data/uploads 运行时数据。
This commit is contained in:
梁铭洋
2026-08-29 11:52:22 +08:00
commit 97fea48393
14 changed files with 5478 additions and 0 deletions
+218
View File
@@ -0,0 +1,218 @@
<?php
declare(strict_types=1);
/** @var array $me */
?>
<div class="card fin-tool-page">
<h3 class="section-title">利息计算器</h3>
<div class="quick-links-col" style="margin-bottom:14px">
<a class="tree-link" href="index.php?action=quick_queries">← 返回便捷查询</a>
</div>
<div class="fin-two-col">
<div class="fin-panel">
<h4>输入</h4>
<div class="fin-row">
<label for="ic_principal">本金(元)</label>
<div>
<input id="ic_principal" type="text" inputmode="decimal" autocomplete="off" placeholder="如 1000000" style="width:100%;max-width:320px">
<div id="ic_principal_fmt" class="fin-muted"></div>
<div id="ic_principal_cap" class="fin-cn-cap"></div>
</div>
</div>
<div class="fin-row">
<label for="ic_rate">利率数值</label>
<div>
<input id="ic_rate" type="text" inputmode="decimal" style="width:140px">
<select id="ic_rate_kind" style="margin-left:8px">
<option value="annual">年利率 %</option>
<option value="monthly">月利率 %</option>
<option value="daily">日利率 %</option>
</select>
</div>
</div>
<div class="fin-row">
<label>计息天数</label>
<div>
<label class="inline small"><input type="radio" name="ic_day_mode" value="manual" checked> 模式A:直接输入天数</label>
<label class="inline small" style="margin-left:12px"><input type="radio" name="ic_day_mode" value="range"> 模式B:起止日期</label>
</div>
</div>
<div class="fin-row" id="ic_row_manual">
<label for="ic_days">天数</label>
<div>
<input id="ic_days" type="number" min="0" step="1" style="width:120px" placeholder="正整数">
<span class="fin-muted" id="ic_days_hint"></span>
</div>
</div>
<div class="fin-row" id="ic_row_range" style="display:none">
<label>起止日期</label>
<div style="display:flex;flex-wrap:wrap;gap:8px;align-items:center">
<input id="ic_d1" type="date">
<span>至</span>
<input id="ic_d2" type="date">
<span class="fin-muted" id="ic_range_days_label"></span>
</div>
</div>
<div class="fin-row">
<label for="ic_count_mode">结息方式</label>
<select id="ic_count_mode">
<option value="inclusive">记首记尾(算头又算尾,天数+1</option>
<option value="exclusive" selected>记首不记尾(算头不算尾)</option>
</select>
</div>
<div class="fin-row">
<label for="ic_basis">计息基准</label>
<select id="ic_basis">
<option value="360" selected>360 天/年(银行常用)</option>
<option value="365">365 天/年</option>
</select>
</div>
<div class="fin-actions">
<button type="button" class="toolbar-btn primary" id="ic_calc">计算</button>
<button type="button" class="toolbar-btn" id="ic_copy">一键复制结果</button>
<button type="button" class="btn-gray" id="ic_reset">重置</button>
</div>
</div>
<div class="fin-result-card" id="ic_result_wrap">
<h4 style="margin:0 0 10px">计算结果</h4>
<p class="fin-muted" style="margin:0 0 8px" id="ic_placeholder">请先填写左侧数据并点击「计算」</p>
<div id="ic_result_body" style="display:none">
<p class="small muted" style="margin:0">应付利息</p>
<div class="fin-out-num" id="ic_out_interest">—</div>
<p class="small muted" style="margin:12px 0 0">本息合计</p>
<div class="fin-out-num" id="ic_out_total" style="font-size:18px">—</div>
<p style="margin:12px 0 4px;font-size:13px">实际计息天数:<strong id="ic_out_days">—</strong></p>
<p style="margin:0;font-size:13px">参考日利率:<strong id="ic_out_daily">—</strong></p>
</div>
</div>
</div>
</div>
<script>
(function(){
var DIG='零壹贰叁肆伍陆柒捌玖', UNIT=['','拾','佰','仟'], GRP=['','万','亿','兆'];
function sectionFour(n){
var s='', str=('0000'+n).slice(-4);
for(var i=0;i<4;i++){
var d=+str[i]; if(d===0){ s+=DIG[0]; continue; }
s=s.replace(/零+$/,'');
s+=DIG[d]+UNIT[3-i];
}
s=s.replace(/零+/g,'零').replace(/零$/,'');
return s||DIG[0];
}
function toRmbUpper(x){
if(!isFinite(x)||x<=0) return '';
var yi=Math.floor(x/1e8), wan=Math.floor((x%1e8)/1e4), ge=Math.floor(x%1e4);
var out='';
if(yi>0) out+=sectionFour(yi)+'亿';
if(wan>0||(yi>0&&ge>0)) out+=sectionFour(wan)+'万';
out+=sectionFour(ge)+'元整';
return out.replace(/^壹拾/g,'拾');
}
function parseNum(s){
s=String(s||'').replace(/,/g,'').trim();
if(s==='') return NaN;
var v=parseFloat(s);
return isFinite(v)?v:NaN;
}
function fmtMoney(n){
if(!isFinite(n)) return '';
var p=(Math.round(n*100)/100).toFixed(2).split('.');
p[0]=p[0].replace(/\B(?=(\d{3})+(?!\d))/g,',');
return p.join('.');
}
function syncPrincipalFmt(){
var raw=document.getElementById('ic_principal').value;
var v=parseNum(raw);
document.getElementById('ic_principal_fmt').textContent=isFinite(v)&&v>0?('格式化:'+fmtMoney(v)+' 元'):'';
document.getElementById('ic_principal_cap').textContent=isFinite(v)&&v>0?('大写:'+toRmbUpper(Math.floor(v))):'';
}
function daysFromRange(d1,d2,mode){
if(!d1||!d2) return NaN;
var t0=new Date(d1+'T12:00:00').getTime(), t1=new Date(d2+'T12:00:00').getTime();
if(t1<t0) return NaN;
var diff=Math.round((t1-t0)/86400000);
return mode==='inclusive'?diff+1:diff;
}
function getEffectiveDays(){
var mode=document.querySelector('input[name="ic_day_mode"]:checked').value;
var cm=document.getElementById('ic_count_mode').value;
if(mode==='manual'){
var n=parseInt(document.getElementById('ic_days').value,10);
return isFinite(n)&&n>=0?n:NaN;
}
return daysFromRange(document.getElementById('ic_d1').value,document.getElementById('ic_d2').value,cm);
}
function dailyRef(P,Rk,rate,basis){
var b=+basis;
if(Rk==='annual') return (rate/100)/b;
if(Rk==='monthly') return (rate/100)/30;
return rate/100;
}
function interestAmount(P,Rk,rate,days,basis){
if(!(P>0)||!(days>=0)||!(rate>0)) return NaN;
var b=+basis;
if(Rk==='annual') return P*(rate/100)*(days/b);
if(Rk==='monthly') return P*(rate/100)*(days/30);
return P*(rate/100)*days;
}
function calc(){
var P=parseNum(document.getElementById('ic_principal').value);
var rate=parseNum(document.getElementById('ic_rate').value);
var Rk=document.getElementById('ic_rate_kind').value;
var basis=document.getElementById('ic_basis').value;
var days=getEffectiveDays();
if(!(P>0)){ alert('请输入有效本金'); return; }
if(!(rate>0)){ alert('请输入有效利率'); return; }
if(!isFinite(days)||days<0){ alert('请检查计息天数或起止日期'); return; }
var intr=interestAmount(P,Rk,rate,days,basis);
var dref=dailyRef(P,Rk,rate,basis);
document.getElementById('ic_out_interest').textContent=fmtMoney(intr)+' 元';
document.getElementById('ic_out_total').textContent=fmtMoney(P+intr)+' 元';
document.getElementById('ic_out_days').textContent=String(days);
document.getElementById('ic_out_daily').textContent=(dref*100).toFixed(6)+'%(按当前利率种类换算,仅供参考)';
document.getElementById('ic_result_body').style.display='block';
var ph=document.getElementById('ic_placeholder'); if(ph) ph.style.display='none';
}
function copyTxt(){
var t='利息 '+document.getElementById('ic_out_interest').textContent+' | 本息合计 '+document.getElementById('ic_out_total').textContent+' | 天数 '+document.getElementById('ic_out_days').textContent;
if(navigator.clipboard) navigator.clipboard.writeText(t).then(function(){alert('已复制');},function(){alert(t);});
else alert(t);
}
function resetAll(){
document.getElementById('ic_principal').value='';
document.getElementById('ic_rate').value='';
document.getElementById('ic_days').value='';
document.getElementById('ic_d1').value='';
document.getElementById('ic_d2').value='';
syncPrincipalFmt();
document.getElementById('ic_result_body').style.display='none';
var ph=document.getElementById('ic_placeholder'); if(ph) ph.style.display='block';
}
document.getElementById('ic_principal').addEventListener('input',syncPrincipalFmt);
document.getElementById('ic_principal').addEventListener('paste',function(){setTimeout(syncPrincipalFmt,0);});
document.querySelectorAll('input[name="ic_day_mode"]').forEach(function(r){
r.addEventListener('change',function(){
var m=document.querySelector('input[name="ic_day_mode"]:checked').value;
document.getElementById('ic_row_manual').style.display=m==='manual'?'':'none';
document.getElementById('ic_row_range').style.display=m==='range'?'':'none';
});
});
function syncRangeLabel(){
var cm=document.getElementById('ic_count_mode').value;
var d=daysFromRange(document.getElementById('ic_d1').value,document.getElementById('ic_d2').value,cm);
document.getElementById('ic_range_days_label').textContent=isFinite(d)?('→ 计息天数 '+d):'';
}
['ic_d1','ic_d2','ic_count_mode'].forEach(function(id){
var el=document.getElementById(id);
if(el) el.addEventListener('change',syncRangeLabel);
});
document.getElementById('ic_days').addEventListener('input',function(){
if(this.value && document.getElementById('ic_d1').value){ document.getElementById('ic_d1').value=''; document.getElementById('ic_d2').value=''; document.getElementById('ic_range_days_label').textContent=''; }
});
document.getElementById('ic_d1').addEventListener('change',function(){ if(this.value) document.getElementById('ic_days').value=''; });
document.getElementById('ic_d2').addEventListener('change',function(){ if(this.value) document.getElementById('ic_days').value=''; });
document.getElementById('ic_calc').addEventListener('click',calc);
document.getElementById('ic_copy').addEventListener('click',copyTxt);
document.getElementById('ic_reset').addEventListener('click',resetAll);
})();
</script>