r110/add.html · 约 10178 字符
1<!DOCTYPE html>
2<html lang="zh-CN">
3<head>
4<meta charset="UTF-8">
5<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">
6<meta name="theme-color" content="#0f9d76">
7<title>记一笔 · 家有账家庭记账工具</title>
8<link rel="stylesheet" href="style.css">
9</head>
10<body data-page="add">
11
12<div class="navbar grn"><a class="bk" href="index.html">‹</a><div class="tt">记一笔</div><div class="rt" data-tip="演示版:模板功能开发中">常用模板</div></div>
13
14<div style="padding:12px 13px 0">
15 <div class="seg" id="typeSeg">
16 <span class="on" data-v="pay">支出</span>
17 <span data-v="inc">收入</span>
18 <span data-v="trans">转账</span>
19 </div>
20</div>
21
22<div class="card" style="margin-top:12px">
23 <div style="display:flex;align-items:flex-end;gap:8px">
24 <div class="ico lg" id="curIco" style="background:#ff7a451a">🍜</div>
25 <div style="flex:1;min-width:0">
26 <div class="fz12 muted" id="curCatName">餐饮</div>
27 <div class="num" id="amtShow" style="font-size:31px;font-weight:800;line-height:1.15">0.00<span id="caret" style="color:var(--brand);font-weight:400">|</span></div>
28 </div>
29 <div class="fz12 muted" style="padding-bottom:6px">¥</div>
30 </div>
31</div>
32
33<div class="chips" id="catPager" style="margin-top:4px">
34 <span class="on" data-v="0">常用</span><span data-v="1">生活</span><span data-v="2">人情消费</span><span data-v="3">全部</span>
35</div>
36<div class="card" style="margin-top:8px;padding:12px 10px">
37 <div class="grid5" id="catGrid" style="gap:6px"></div>
38</div>
39
40<div class="card frm">
41 <div class="fi"><div class="lb">账户</div><div class="vl" id="accVal">微信零钱</div><span class="ar" data-sheet="#shAcc">›</span></div>
42 <div class="fi"><div class="lb">日期</div><div class="vl">今天 08-06 19:40</div><span class="ar" data-tip="演示版:日期选择器开发中">›</span></div>
43 <div class="fi"><div class="lb">记录人</div><div class="vl" id="memVal">我</div><span class="ar" data-sheet="#shMem">›</span></div>
44 <div class="fi"><div class="lb">账本</div><div class="vl">家庭日常账本</div><span class="ar" data-tip="演示版:切换账本请到家庭页">›</span></div>
45 <div class="fi"><div class="lb">备注</div><input class="tx" id="noteIn" placeholder="点此添加备注…"></div>
46 <div class="fi"><div class="lb">标签</div>
47 <div style="flex:1;display:flex;gap:6px;justify-content:flex-end;flex-wrap:wrap" id="tagBox">
48 <span class="tag" data-v="报销">报销</span><span class="tag" data-v="AA">AA</span>
49 <span class="tag" data-v="周期">周期</span><span class="tag" data-v="不计入预算">不计预算</span>
50 </div>
51 </div>
52 <div class="fi"><div class="lb">票据</div>
53 <div style="flex:1;display:flex;gap:7px;justify-content:flex-end">
54 <div class="ico" style="border:1px dashed #ccd8d4;background:#fff" data-tip="演示版:拍照上传需真机">📷</div>
55 <div class="ico" style="border:1px dashed #ccd8d4;background:#fff" data-tip="演示版:相册选择需真机">🖼️</div>
56 </div>
57 </div>
58</div>
59
60<div style="height:250px"></div>
61
62<div class="kb" id="kb">
63 <b data-k="1">1</b><b data-k="2">2</b><b data-k="3">3</b><b class="fn" data-k="del">⌫</b>
64 <b data-k="4">4</b><b data-k="5">5</b><b data-k="6">6</b><b class="ok" data-k="ok">保存</b>
65 <b data-k="7">7</b><b data-k="8">8</b><b data-k="9">9</b>
66 <b class="fn" data-k="again">再记</b><b data-k="0">0</b><b data-k=".">.</b>
67</div>
68
69<div class="sheet" id="shAcc">
70 <div class="sh"><h3>选择账户</h3><span class="x" data-close>✕</span></div>
71 <div class="list" id="accList"></div>
72</div>
73<div class="sheet" id="shMem">
74 <div class="sh"><h3>选择记录人</h3><span class="x" data-close>✕</span></div>
75 <div class="list" id="memList"></div>
76</div>
77
78<nav class="tabbar">
79<a href="index.html" class=""><span class="ti">🏠</span>首页</a>
80<a href="bills.html" class=""><span class="ti">📒</span>账单</a>
81<a href="add.html" class="fab on"><span class="fi">+</span><span class="fl">记一笔</span></a>
82<a href="chart.html" class=""><span class="ti">📊</span>图表</a>
83<a href="me.html" class=""><span class="ti">👤</span>我的</a>
84</nav>
85<div class="mask" id="mask"></div>
86<div class="toast" id="toast"></div>
87<script src="data.js"></script>
88<script src="app.js"></script>
89<script>
90
91var GROUPS = [
92 ['food', 'grocery', 'traffic', 'shop', 'util', 'house', 'edu', 'fun', 'daily', 'other'],
93 ['house', 'util', 'phone', 'daily', 'grocery', 'car', 'medical', 'pet', 'baby', 'cloth'],
94 ['gift', 'fun', 'travel', 'beauty', 'sport', 'cloth', 'shop', 'food', 'repay', 'other'],
95 CATS.map(function (c) { return c.id; })
96];
97var state = { t: 'pay', cat: 'food', amt: '', acc: 'a2', mem: 'm1', tags: [] };
98
99function qs(k) { var m = location.search.match(new RegExp('[?&]' + k + '=([^&]+)')); return m ? decodeURIComponent(m[1]) : ''; }
100if (qs('cat')) state.cat = qs('cat');
101if (qs('t') === 'inc') state.t = 'inc';
102
103function curList() {
104 if (state.t === 'inc') return INCATS.map(function (c) { return c.id; });
105 if (state.t === 'trans') return ['a1', 'a2', 'a3', 'a4', 'a5'];
106 return GROUPS[Number(segValue('#catPager') || 0)];
107}
108function renderCats() {
109 var ids = curList(), box = $('#catGrid');
110 if (state.t === 'trans') {
111 box.innerHTML = ACCOUNTS.filter(function (a) { return a.kind !== 'invest'; }).slice(0, 10).map(function (a) {
112 return '<div class="tile plain" data-a="' + a.id + '"><div class="emo">' + a.e + '</div><div class="lb">' + a.n.slice(0, 4) + '</div></div>';
113 }).join('');
114 $$('#catGrid .tile').forEach(function (t) {
115 t.addEventListener('click', function () { toast('转出账户:' + accOf(t.getAttribute('data-a')).n); });
116 });
117 return;
118 }
119 if (ids.indexOf(state.cat) < 0) state.cat = ids[0];
120 box.innerHTML = ids.map(function (id) {
121 var c = catOf(id), on = id === state.cat;
122 return '<div class="tile' + (on ? '' : ' plain') + '" data-c="' + id + '"' +
123 (on ? ' style="box-shadow:0 4px 14px ' + c.c + '38;border:1px solid ' + c.c + '"' : '') + '>' +
124 '<div class="emo">' + c.e + '</div><div class="lb"' + (on ? ' style="color:' + c.c + '"' : '') + '>' + c.n + '</div></div>';
125 }).join('');
126 $$('#catGrid .tile').forEach(function (t) {
127 t.addEventListener('click', function () { state.cat = t.getAttribute('data-c'); renderCats(); renderHead(); });
128 });
129}
130function renderHead() {
131 var c = catOf(state.cat);
132 $('#curIco').innerHTML = c.e;
133 $('#curIco').style.background = c.c + '1a';
134 $('#curCatName').textContent = (state.t === 'inc' ? '收入 · ' : state.t === 'trans' ? '转账' : '支出 · ') + (state.t === 'trans' ? '' : c.n);
135 var v = state.amt === '' ? '0.00' : state.amt;
136 $('#amtShow').innerHTML = v + '<span id="caret" style="color:var(--brand);font-weight:400">|</span>';
137}
138segGroup('#typeSeg', function (v) { state.t = v; renderCats(); renderHead(); });
139segGroup('#catPager', function () { renderCats(); });
140
141$$('#kb b').forEach(function (b) {
142 b.addEventListener('click', function () {
143 var k = b.getAttribute('data-k');
144 if (k === 'del') { state.amt = state.amt.slice(0, -1); }
145 else if (k === 'ok' || k === 'again') { save(k === 'again'); return; }
146 else if (k === '.') { if (state.amt.indexOf('.') < 0 && state.amt !== '') state.amt += '.'; }
147 else {
148 if (state.amt.indexOf('.') >= 0 && state.amt.split('.')[1].length >= 2) return;
149 if (state.amt === '' && k === '0') return;
150 state.amt += k;
151 }
152 renderHead();
153 });
154});
155
156function save(again) {
157 var n = parseFloat(state.amt || '0');
158 if (!(n > 0)) { toast('请输入金额'); return; }
159 var c = catOf(state.cat);
160 var rec = {
161 id: 'u' + Date.now(), t: state.t === 'trans' ? 'pay' : state.t, cat: state.cat,
162 n: ($('#noteIn').value || c.n + '支出').slice(0, 20), amt: n, acc: state.acc, mem: state.mem,
163 date: '2026-08-06', time: '19:40', note: $('#noteIn').value || '', tags: state.tags.slice()
164 };
165 var arr = SG.get('bills', []); arr.unshift(rec); SG.set('bills', arr);
166 toast('已记账 ' + money(n, rec.t) + ' 元 · ' + c.n);
167 state.amt = ''; $('#noteIn').value = ''; renderHead();
168 if (!again) setTimeout(function () { location.href = 'bills.html'; }, 900);
169}
170
171$('#accList').innerHTML = ACCOUNTS.filter(function (a) { return a.kind !== 'invest'; }).map(function (a) {
172 return '<div class="it" data-a="' + a.id + '"><div class="ico" style="background:' + a.c + '1a">' + a.e + '</div>' +
173 '<div class="mn"><div class="n">' + a.n + (a.tail ? ' (' + a.tail + ')' : '') + '</div>' +
174 '<div class="d">' + (a.kind === 'credit' ? '信用卡 · 可用额度 ¥' + money0(a.limit + a.bal) : '余额 ¥' + money0(a.bal)) + '</div></div>' +
175 '<span class="tag">选择</span></div>';
176}).join('');
177$$('#accList .it').forEach(function (it) {
178 it.addEventListener('click', function () {
179 state.acc = it.getAttribute('data-a');
180 $('#accVal').textContent = accOf(state.acc).n; closeSheet(); toast('账户已切换');
181 });
182});
183
184$('#memList').innerHTML = MEMBERS.map(function (m) {
185 return '<div class="it" data-m="' + m.id + '"><div class="avt" style="background:' + m.c + '">' + m.e + '</div>' +
186 '<div class="mn"><div class="n">' + m.n + '</div><div class="d">' + m.role + ' · ' + m.perm + '</div></div>' +
187 '<span class="tag">选择</span></div>';
188}).join('');
189$$('#memList .it').forEach(function (it) {
190 it.addEventListener('click', function () {
191 state.mem = it.getAttribute('data-m');
192 $('#memVal').textContent = memOf(state.mem).n; closeSheet();
193 });
194});
195
196$$('#tagBox .tag').forEach(function (t) {
197 t.addEventListener('click', function () {
198 var v = t.getAttribute('data-v'), i = state.tags.indexOf(v);
199 if (i >= 0) { state.tags.splice(i, 1); t.className = 'tag'; }
200 else { state.tags.push(v); t.className = 'tag g'; }
201 });
202});
203
204renderCats(); renderHead();
205
206</script>
207</body>
208</html>
209