首页/ mobileweb/ 家有账 · 家庭共享记账工具(移动端 H5)/ 代码预览

💻 代码预览 · 家有账 · 家庭共享记账工具(移动端 H5)

mw_tool · 上传者 驰旭教育
← 返回详情
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