liu
8 小时以前 514f372270b181f82e4deff98f8d0f38ace63183
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
<!doctype html>
<html lang="zh-CN">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>定位授权 · 产品追溯</title>
  <style>
    * { box-sizing: border-box; }
    body { margin: 0; min-height: 100vh; display: grid; place-items: center; padding: 24px; background: #f6f7f6; color: #1f2933; font: 16px/1.6 -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", sans-serif; }
    .trace-background { position: fixed; inset: 0; width: 100%; height: 100%; border: 0; pointer-events: none; opacity: .45; filter: blur(2px); }
    body.unlocked .trace-background { pointer-events: auto; opacity: 1; filter: none; }
    body::before { content: ''; position: fixed; inset: 0; background: #f6f7f688; z-index: 1; }
    body.unlocked::before, body.unlocked main { display: none; }
    main { position: relative; z-index: 2; width: min(100%, 440px); background: white; border-radius: 16px; padding: 28px 24px; box-shadow: 0 6px 28px #17382224; }
    .icon { width: 52px; height: 52px; display: grid; place-items: center; background: #eef7ef; color: #1f7a38; border-radius: 14px; font-size: 28px; }
    h1 { margin: 20px 0 8px; font-size: 23px; }
    p { margin: 0 0 18px; color: #58636d; }
    button { width: 100%; min-height: 48px; border: 0; border-radius: 9px; background: #1f7a38; color: white; font: inherit; font-weight: 600; cursor: pointer; }
    button:focus-visible { outline: 3px solid #7bc894; outline-offset: 3px; }
    button:disabled { opacity: .6; cursor: wait; }
    #status { min-height: 26px; margin-top: 14px; color: #b42318; }
    small { display: block; margin-top: 16px; color: #6b7280; }
  </style>
</head>
<body>
  <iframe id="traceFrame" class="trace-background" src="trace.html" tabindex="-1" aria-hidden="true" title="产品追溯背景"></iframe>
  <main>
    <div class="icon" aria-hidden="true">⌖</div>
    <h1>开启定位后查看追溯信息</h1>
    <p>为记录本次追溯查询所在位置,请允许浏览器获取当前位置。授权成功后将自动进入产品追溯页。</p>
    <button id="locate" type="button" disabled>开启定位并继续</button>
    <div id="status" role="status" aria-live="polite"></div>
    <small>本次会记录追溯码、坐标、定位精度和访问时间,供后台查看与统计。拒绝授权或定位失败时无法继续。</small>
  </main>
  <script>
    (function () {
      'use strict';
      var button = document.getElementById('locate');
      var status = document.getElementById('status');
      var code = new URLSearchParams(location.search).get('code') || '';
      function showTrace() {
        var frame = document.getElementById('traceFrame');
        frame.src = 'trace.html' + (code ? '?code=' + encodeURIComponent(code) + '&view=location' : '?view=location');
        frame.removeAttribute('aria-hidden');
        frame.removeAttribute('tabindex');
        frame.title = '产品追溯信息';
        document.body.classList.add('unlocked');
      }
 
      // 本地 profile 由后端明确关闭定位要求;配置失败时保持必须定位。
      status.textContent = '正在检查访问配置…';
      fetch('/public/mes/trace/config')
        .then(function (response) { return response.json(); })
        .then(function (result) {
          if (result && result.code === 0 && result.data && result.data.traceLocationRequired === false) {
            showTrace();
          } else {
            status.textContent = '';
            button.disabled = false;
          }
        })
        .catch(function () {
          status.textContent = '';
          button.disabled = false;
        });
 
      button.addEventListener('click', function () {
        if (!window.isSecureContext || !navigator.geolocation) {
          status.textContent = '当前网址不支持定位,请使用已配置 HTTPS 的追溯网址打开。';
          return;
        }
        button.disabled = true;
        status.textContent = '正在获取当前位置…';
        navigator.geolocation.getCurrentPosition(function (position) {
          fetch('/public/mes/trace/location-visit', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
              code: code,
              latitude: position.coords.latitude,
              longitude: position.coords.longitude,
              accuracy: position.coords.accuracy
            })
          }).then(function (response) { return response.json(); }).then(function (result) {
            if (!result || result.code !== 0) throw new Error(result && result.msg || '位置记录失败');
            showTrace();
          }).catch(function (error) {
            status.textContent = error.message || '位置记录失败,请重试。';
            button.disabled = false;
          });
        }, function (error) {
          status.textContent = error.code === 1 ? '定位权限被拒绝,请在浏览器设置中允许定位后重试。' : '定位失败,请检查手机定位和网络后重试。';
          button.disabled = false;
        }, { enableHighAccuracy: true, timeout: 15000, maximumAge: 0 });
      });
    })();
  </script>
</body>
</html>