首页/ mobileweb/ 班级成绩查询系统(移动端 H5)/ 代码预览

💻 代码预览 · 班级成绩查询系统(移动端 H5)

mw_edu · 上传者 驰旭教育
← 返回详情
r115/app.js · 约 9883 字符
1
2var C = { brand: '#3b5bdb', brandD: '#2b44b8', good: '#2f9e44', bad: '#e03131', hot: '#f08c00', gray: '#868e96', grayL: '#adb5bd' };
3var $ = function (s, r) { return (r || document).querySelector(s); };
4var $$ = function (s, r) { return Array.prototype.slice.call((r || document).querySelectorAll(s)); };
5function esc(s) {
6  return String(s == null ? '' : s).replace(/[&<>"]/g, function (c) {
7    return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;' }[c];
8  });
9}
10function toast(m) {
11  var t = $('#__toast');
12  if (!t) { t = document.createElement('div'); t.id = '__toast'; t.style.cssText = 'position:fixed;left:50%;top:42%;transform:translate(-50%,-50%);background:rgba(0,0,0,.8);color:#fff;padding:10px 16px;border-radius:10px;font-size:13px;z-index:99;max-width:70%;text-align:center;'; document.body.appendChild(t); }
13  t.textContent = m; t.style.display = 'block';
14  clearTimeout(t._t); t._t = setTimeout(function () { t.style.display = 'none'; }, 1600);
15}
16
17var DS = {
18  _p: {},
19  get: function (name) {
20    if (this._p[name]) return this._p[name];
21    var p = new Promise(function (res) {
22      fetch('data/' + name + '.json').then(function (r) { return r.json(); }).then(function (j) { res(j); })
23        .catch(function () { res((window.__DATA__ && window.__DATA__[name]) || {}); });
24    });
25    this._p[name] = p; return p;
26  }
27};
28
29/* ============ SVG 图表引擎 ============ */
30var Chart = {};
31Chart.line = function (o) {
32  var w = o.w || 340, h = o.h || 200, pad = 30, labels = o.labels, series = o.series, max = o.max, min = o.min || 0, n = labels.length;
33  var gw = w - pad * 2, gh = h - pad * 2;
34  function X(i) { return pad + (n <= 1 ? gw / 2 : gw * i / (n - 1)); }
35  function Y(v) { return pad + gh - (v - min) / (max - min) * gh; }
36  var g = '', i;
37  for (i = 0; i <= 4; i++) { var gy = pad + gh * i / 4, val = Math.round(max - (max - min) * i / 4); g += '<line x1="' + pad + '" y1="' + gy + '" x2="' + (w - pad) + '" y2="' + gy + '" stroke="#eef0f3"/><text x="' + (pad - 5) + '" y="' + (gy + 3) + '" font-size="9" fill="#9aa0a6" text-anchor="end">' + val + '</text>'; }
38  var xl = ''; for (i = 0; i < n; i++) { xl += '<text x="' + X(i) + '" y="' + (h - 9) + '" font-size="9" fill="#9aa0a6" text-anchor="middle">' + esc(labels[i]) + '</text>'; }
39  var paths = '', dots = '', leg = '';
40  series.forEach(function (s) {
41    var d = ''; for (i = 0; i < n; i++) { d += (i ? 'L' : 'M') + X(i).toFixed(1) + ' ' + Y(s.data[i]).toFixed(1) + ' '; }
42    paths += '<path d="' + d + '" fill="none" stroke="' + s.color + '" stroke-width="2.2" stroke-linejoin="round" stroke-linecap="round"/>';
43    for (i = 0; i < n; i++) { dots += '<circle cx="' + X(i).toFixed(1) + '" cy="' + Y(s.data[i]).toFixed(1) + '" r="2.6" fill="' + s.color + '"/>'; }
44    leg += '<span style="display:inline-flex;align-items:center;gap:4px;margin-right:10px;font-size:11px;color:#646a73"><i style="width:11px;height:3px;background:' + s.color + ';display:inline-block;border-radius:2px"></i>' + esc(s.name) + '</span>';
45  });
46  return '<svg viewBox="0 0 ' + w + ' ' + h + '" width="100%" preserveAspectRatio="xMidYMid meet">' + g + xl + paths + dots + '</svg><div style="margin-top:4px">' + leg + '</div>';
47};
48Chart.radar = function (o) {
49  var size = o.size || 240, axes = o.axes, series = o.series, max = o.max || 1, n = axes.length, cx = size / 2, cy = size / 2, R = size / 2 - 28;
50  function pt(i, r) { var a = -Math.PI / 2 + i * 2 * Math.PI / n; return [cx + r * Math.cos(a), cy + r * Math.sin(a)]; }
51  var g = '', i, k;
52  for (k = 1; k <= 4; k++) { var rr = R * k / 4, d = ''; for (i = 0; i < n; i++) { var p = pt(i, rr); d += (i ? 'L' : 'M') + p[0].toFixed(1) + ' ' + p[1].toFixed(1) + ' '; } g += '<path d="' + d + 'Z" fill="none" stroke="#eef0f3"/>'; }
53  var sp = '', al = '';
54  for (i = 0; i < n; i++) { var p = pt(i, R); sp += '<line x1="' + cx + '" y1="' + cy + '" x2="' + p[0].toFixed(1) + '" y2="' + p[1].toFixed(1) + '" stroke="#eef0f3"/>'; var lp = pt(i, R + 13); al += '<text x="' + lp[0].toFixed(1) + '" y="' + lp[1].toFixed(1) + '" font-size="9.5" fill="#646a73" text-anchor="middle">' + esc(axes[i]) + '</text>'; }
55  var polys = '', leg = '';
56  series.forEach(function (s) {
57    var d = ''; for (i = 0; i < n; i++) { var p = pt(i, R * (s.data[i] / max)); d += (i ? 'L' : 'M') + p[0].toFixed(1) + ' ' + p[1].toFixed(1) + ' '; }
58    polys += '<path d="' + d + 'Z" fill="' + s.color + '" fill-opacity="0.18" stroke="' + s.color + '" stroke-width="2"/>';
59    for (i = 0; i < n; i++) { var p = pt(i, R * (s.data[i] / max)); polys += '<circle cx="' + p[0].toFixed(1) + '" cy="' + p[1].toFixed(1) + '" r="2.4" fill="' + s.color + '"/>'; }
60    leg += '<span style="display:inline-flex;align-items:center;gap:4px;margin-right:10px;font-size:11px;color:#646a73"><i style="width:10px;height:10px;background:' + s.color + ';opacity:.5;display:inline-block;border-radius:3px"></i>' + esc(s.name) + '</span>';
61  });
62  return '<svg viewBox="0 0 ' + size + ' ' + size + '" width="100%" preserveAspectRatio="xMidYMid meet">' + g + sp + polys + al + '</svg><div style="text-align:center;margin-top:2px">' + leg + '</div>';
63};
64Chart.bar = function (o) {
65  var w = o.w || 340, h = o.h || 200, pad = 26, labels = o.labels, series = o.series, max = o.max, n = labels.length, m = series.length;
66  var gw = w - pad * 2, gh = h - pad * 2;
67  function Y(v) { return pad + gh - (v / max) * gh; }
68  var g = '', i, k;
69  for (k = 0; k <= 4; k++) { var gy = pad + gh * k / 4, val = Math.round(max * (1 - k / 4)); g += '<line x1="' + pad + '" y1="' + gy + '" x2="' + (w - pad) + '" y2="' + gy + '" stroke="#eef0f3"/><text x="' + (pad - 5) + '" y="' + (gy + 3) + '" font-size="9" fill="#9aa0a6" text-anchor="end">' + val + '</text>'; }
70  var bw = gw / n * 0.62 / m, slot = gw / n, inner = gw / n * 0.62, gap = (slot - inner) / (m + 1);
71  var bars = '', xl = '';
72  for (i = 0; i < n; i++) {
73    var gx = pad + slot * i + (slot - inner) / 2;
74    series.forEach(function (s, si) {
75      var v = s.data[i], bx = gx + si * (bw + gap), by = Y(v), bh = h - pad - by;
76      bars += '<rect x="' + bx.toFixed(1) + '" y="' + by.toFixed(1) + '" width="' + bw.toFixed(1) + '" height="' + bh.toFixed(1) + '" rx="3" fill="' + s.color + '"/>';
77    });
78    xl += '<text x="' + (pad + slot * i + slot / 2) + '" y="' + (h - 9) + '" font-size="9" fill="#9aa0a6" text-anchor="middle">' + esc(labels[i]) + '</text>';
79  }
80  var leg = ''; series.forEach(function (s) { leg += '<span style="display:inline-flex;align-items:center;gap:4px;margin-right:10px;font-size:11px;color:#646a73"><i style="width:10px;height:10px;background:' + s.color + ';display:inline-block;border-radius:2px"></i>' + esc(s.name) + '</span>'; });
81  return '<svg viewBox="0 0 ' + w + ' ' + h + '" width="100%" preserveAspectRatio="xMidYMid meet">' + g + xl + bars + '</svg><div style="margin-top:4px">' + leg + '</div>';
82};
83Chart.ring = function (o) {
84  var size = o.size || 120, pct = o.pct, color = o.color || '#3b5bdb', label = o.label || '';
85  var r = size / 2 - 10, c = 2 * Math.PI * r, off = c * (1 - pct);
86  return '<svg viewBox="0 0 ' + size + ' ' + size + '" width="' + size + '" height="' + size + '"><circle cx="' + (size / 2) + '" cy="' + (size / 2) + '" r="' + r + '" fill="none" stroke="#eef0f3" stroke-width="10"/><circle cx="' + (size / 2) + '" cy="' + (size / 2) + '" r="' + r + '" fill="none" stroke="' + color + '" stroke-width="10" stroke-linecap="round" stroke-dasharray="' + c.toFixed(1) + '" stroke-dashoffset="' + off.toFixed(1) + '" transform="rotate(-90 ' + (size / 2) + ' ' + (size / 2) + ')"/><text x="' + (size / 2) + '" y="' + (size / 2 + 5) + '" font-size="19" font-weight="800" fill="#1f2329" text-anchor="middle">' + esc(label) + '</text></svg>';
87};
88Chart.hbar = function (o) {
89  var max = o.max, items = o.items, row = '';
90  items.forEach(function (it) {
91    var wp = (it.value / max * 100).toFixed(1);
92    var cp = it.compare != null ? (it.compare / max * 100).toFixed(1) : null;
93    row += '<div style="margin:9px 0"><div style="display:flex;justify-content:space-between;font-size:12px;margin-bottom:3px"><span>' + esc(it.label) + '</span><span style="color:#646a73">' + it.value + '<span style="color:#c0c4cc"> /' + max + '</span></span></div>' +
94      '<div style="position:relative;height:9px;background:#eef0f3;border-radius:6px">' +
95      (cp != null ? '<div style="position:absolute;left:0;top:0;height:9px;width:' + cp + '%;background:' + (it.compareColor || '#c5cde6') + ';border-radius:6px;opacity:.6"></div>' : '') +
96      '<div style="position:relative;height:9px;width:' + wp + '%;background:' + it.color + ';border-radius:6px"></div></div></div>';
97  });
98  return '<div>' + row + '</div>';
99};
100
101/* ============ 全局交互委托 ============ */
102document.addEventListener('click', function (e) {
103  var seg = e.target.closest('.seg');
104  if (seg && seg.dataset.group) {
105    var t = e.target.closest('[data-val]');
106    if (t) {
107      $$('.seg[data-group="' + seg.dataset.group + '"] [data-val]').forEach(function (x) { x.classList.remove('on'); });
108      t.classList.add('on');
109      $$('.seg-panel[data-group="' + seg.dataset.group + '"]').forEach(function (p) { p.style.display = 'none'; });
110      var p = $('.seg-panel[data-group="' + seg.dataset.group + '"][data-val="' + t.dataset.val + '"]');
111      if (p) p.style.display = '';
112    }
113    return;
114  }
115  var chip = e.target.closest('.chip');
116  if (chip && chip.dataset.filter) {
117    var f = chip.dataset.filter, scope = chip.closest('[data-filter-scope]') || document;
118    $$('.chip', scope).forEach(function (c) { c.classList.remove('on'); });
119    chip.classList.add('on');
120    $$('[data-status]', scope).forEach(function (el) { el.style.display = (f === '全部' || el.dataset.status === f) ? '' : 'none'; });
121    return;
122  }
123});
124