zengxi123 commited on
Commit
3c33f14
·
verified ·
1 Parent(s): fefdb8d

创建一个条形扫码微信应用程序,它是html文件+uvue文件的格式。

Browse files

1.当它触发扫码时,发送POST请求,以将单号上传到数据库
2.创建一个存储十个条形码的数组,数组采用先进后出以确保最大只有十个,当扫码触发时将条形码数据加入这个数组中,当扫码得出的条形码数据已经在这个数组中时,应当发出提示说明单号已经扫描过,且不应该触发POST请求
3.它提供一个文本框,文本框放置需要注意的单号,以回车区分下一个,当扫码得出的条形码数据在文本框中时,应当给出提示
4.在编写代码时,你应该尽可能的去除耦合,以无数代码块的形式组成一个功能

Files changed (1) hide show
  1. barcode-scanner.html +227 -197
barcode-scanner.html CHANGED
@@ -3,254 +3,284 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Barcode Scanner</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
  <script src="https://unpkg.com/feather-icons"></script>
9
- <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
10
- <script src="https://cdn.jsdelivr.net/npm/vue@3.2.47/dist/vue.global.min.js"></script>
11
  </head>
12
- <body>
13
- <div id="app" class="min-h-screen bg-gray-100 p-4">
14
- <div class="max-w-md mx-auto bg-white rounded-xl shadow-md overflow-hidden p-6">
15
- <!-- Scanner Controls -->
16
- <div class="mb-6">
17
- <h1 class="text-2xl font-bold text-gray-800 mb-4">Barcode Scanner</h1>
18
- <button
19
- @click="initiateScan"
20
- class="w-full bg-blue-600 hover:bg-blue-700 text-white py-2 px-4 rounded-lg flex items-center justify-center transition"
21
- >
22
- <i data-feather="maximize" class="mr-2"></i> Start Scanning
23
- </button>
24
- </div>
25
 
26
- <!-- Special Barcodes Input -->
27
- <div class="mb-6">
28
- <label class="block text-gray-700 text-sm font-bold mb-2" for="specialBarcodes">
29
- Special Barcodes (one per line)
30
- </label>
31
- <textarea
32
- id="specialBarcodes"
33
- v-model="specialBarcodes"
34
- @change="updateWatchlist"
35
- class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
36
- rows="3"
37
- ></textarea>
38
  </div>
39
-
40
- <!-- Scan History -->
41
- <div class="mb-4">
42
- <div class="flex justify-between items-center mb-2">
43
- <h2 class="text-lg font-semibold text-gray-800">Scan History</h2>
44
- <button
45
- @click="clearHistory"
46
- class="text-sm text-blue-600 hover:text-blue-800"
47
- >
48
- Clear All
49
- </button>
50
- </div>
51
- <div class="space-y-2">
52
- <div
53
- v-for="(scan, index) in scanHistory"
54
- :key="index"
55
- class="flex justify-between items-center p-2 bg-gray-50 rounded-lg"
56
- >
57
- <span class="font-mono">{{ scan.barcode }}</span>
58
- <span class="text-xs text-gray-500">{{ scan.time }}</span>
59
  </div>
60
- <p v-if="scanHistory.length === 0" class="text-gray-500 text-center py-4">
61
- No scans yet
62
- </p>
 
 
63
  </div>
64
  </div>
 
65
 
66
- <!-- Toast Notification -->
67
- <div
68
- v-if="showToast"
69
- :class="toastClasses"
70
- class="fixed bottom-4 right-4 text-white px-4 py-2 rounded-lg shadow-lg transition-all duration-300"
71
- >
72
- <div class="flex items-center">
73
- <i data-feather="alert-circle" class="mr-2"></i>
74
- <span>{{ toastMessage }}</span>
75
- </div>
 
 
 
 
 
 
 
 
 
 
 
76
  </div>
77
  </div>
78
  </div>
79
 
80
  <script>
81
- const { createApp, ref, computed } = Vue;
 
 
 
 
 
 
82
 
83
- // Barcode Scanner Module
84
- const createBarcodeScanner = () => {
85
- const scanHistory = ref([]);
86
- const maxHistorySize = 10;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
 
88
- const addToHistory = (barcode) => {
89
- if (scanHistory.value.some(scan => scan.barcode === barcode)) {
90
- return false; // Already exists
91
- }
 
 
92
 
93
- const newScan = {
94
- barcode,
95
- time: new Date().toLocaleTimeString()
96
- };
97
 
98
- if (scanHistory.value.length >= maxHistorySize) {
99
- scanHistory.value.pop();
100
- }
101
- scanHistory.value.unshift(newScan);
102
- return true;
103
  };
104
 
105
- const clearHistory = () => {
106
- scanHistory.value = [];
 
107
  };
108
 
109
- return {
110
- scanHistory,
111
- addToHistory,
112
- clearHistory
113
  };
114
- };
115
 
116
- // Watchlist Module
117
- const createWatchlist = () => {
118
- const specialBarcodes = ref('');
119
- const watchlist = computed(() =>
120
- specialBarcodes.value.split('\n').filter(b => b.trim() !== '')
121
- );
122
 
123
- const updateWatchlist = (value) => {
124
- specialBarcodes.value = value;
 
 
 
 
 
125
  };
126
 
127
- const isSpecialBarcode = (barcode) => {
128
- return watchlist.value.includes(barcode);
 
 
 
 
 
 
 
 
 
 
 
 
129
  };
130
 
131
- return {
132
- specialBarcodes,
133
- watchlist,
134
- updateWatchlist,
135
- isSpecialBarcode
136
  };
137
- };
138
 
139
- // API Module
140
- const createApiClient = () => {
141
- const sendBarcode = async (barcode) => {
142
- try {
143
- // Replace with your actual API endpoint
144
- const response = await fetch('https://your-api-endpoint.com/barcodes', {
145
- method: 'POST',
146
- headers: {
147
- 'Content-Type': 'application/json',
148
- },
149
- body: JSON.stringify({ barcode })
150
- });
151
-
152
- if (!response.ok) {
153
- throw new Error('Network response was not ok');
154
- }
155
 
156
- return await response.json();
157
- } catch (error) {
158
- console.error('Error sending barcode:', error);
159
- throw error;
160
- }
 
161
  };
162
 
163
- return {
164
- sendBarcode
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
  };
166
- };
167
 
168
- // Toast Module
169
- const createToast = () => {
170
- const showToast = ref(false);
171
- const toastMessage = ref('');
172
- const toastType = ref('info');
173
 
174
- const toastClasses = computed(() => {
175
- const types = {
176
- info: 'bg-blue-600',
 
 
 
 
 
 
 
177
  success: 'bg-green-600',
178
  warning: 'bg-yellow-600',
179
  error: 'bg-red-600'
180
  };
181
- return types[toastType.value];
182
- });
183
-
184
- const displayToast = (message, type = 'info') => {
185
- toastMessage.value = message;
186
- toastType.value = type;
187
- showToast.value = true;
188
-
189
  setTimeout(() => {
190
- showToast.value = false;
 
 
191
  }, 3000);
192
  };
193
 
194
- return {
195
- showToast,
196
- toastMessage,
197
- toastClasses,
198
- displayToast
199
- };
200
- };
201
-
202
- // Main App
203
- createApp({
204
- setup() {
205
- // Initialize modules
206
- const scanner = createBarcodeScanner();
207
- const watchlist = createWatchlist();
208
- const api = createApiClient();
209
- const toast = createToast();
210
-
211
- // Simulate scan (replace with actual scanner implementation)
212
- const initiateScan = () => {
213
- // For demo purposes, generate a random barcode
214
- const barcode = 'BC' + Math.floor(100000 + Math.random() * 900000);
215
-
216
- // Check if already in history
217
- if (!scanner.addToHistory(barcode)) {
218
- toast.displayToast('This barcode has already been scanned!', 'warning');
219
- return;
220
- }
221
 
222
- // Check if special barcode
223
- if (watchlist.isSpecialBarcode(barcode)) {
224
- toast.displayToast('⚠️ Special barcode detected!', 'warning');
225
- }
226
 
227
- // Send to server
228
- api.sendBarcode(barcode)
229
- .then(() => {
230
- toast.displayToast(`Barcode "${barcode}" sent successfully`, 'success');
231
- })
232
- .catch(() => {
233
- toast.displayToast('Failed to send barcode', 'error');
234
- });
235
- };
236
 
237
- // Update watchlist when textarea changes
238
- const updateWatchlist = (event) => {
239
- watchlist.updateWatchlist(event.target.value);
240
- };
241
 
242
- return {
243
- ...scanner,
244
- ...watchlist,
245
- ...toast,
246
- initiateScan,
247
- updateWatchlist
248
- };
249
- },
250
- mounted() {
251
  feather.replace();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
252
  }
253
- }).mount('#app');
254
  </script>
255
  </body>
256
  </html>
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Barcode Scanner App</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
  <script src="https://unpkg.com/feather-icons"></script>
 
 
9
  </head>
10
+ <body class="bg-gray-100 min-h-screen">
11
+ <div class="container mx-auto px-4 py-8 max-w-md">
12
+ <header class="mb-8 text-center">
13
+ <h1 class="text-3xl font-bold text-indigo-600 mb-2">Barcode Scanner</h1>
14
+ <p class="text-gray-600">Scan and track barcodes efficiently</p>
15
+ </header>
 
 
 
 
 
 
 
16
 
17
+ <!-- Scanner Section -->
18
+ <div class="bg-white rounded-xl shadow-md p-6 mb-6">
19
+ <div class="flex justify-between items-center mb-4">
20
+ <h2 class="text-xl font-semibold text-gray-800">Scanner</h2>
21
+ <button id="scanBtn" class="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-lg flex items-center transition">
22
+ <i data-feather="maximize" class="mr-2"></i> Scan Now
23
+ </button>
 
 
 
 
 
24
  </div>
25
+
26
+ <div class="text-center">
27
+ <div id="scannerPlaceholder" class="mx-auto w-full h-48 bg-gray-200 rounded-lg flex items-center justify-center">
28
+ <div class="text-center">
29
+ <i data-feather="camera" class="w-12 h-12 mx-auto text-gray-400 mb-2"></i>
30
+ <p class="text-gray-500">Ready to scan</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  </div>
32
+ </div>
33
+
34
+ <div id="lastScanned" class="mt-4 p-3 bg-indigo-50 rounded-lg hidden">
35
+ <p class="text-sm text-gray-600 mb-1">Last scanned:</p>
36
+ <p id="lastScannedCode" class="font-mono text-lg font-bold text-indigo-700"></p>
37
  </div>
38
  </div>
39
+ </div>
40
 
41
+ <!-- Watchlist Section -->
42
+ <div class="bg-white rounded-xl shadow-md p-6 mb-6">
43
+ <h2 class="text-xl font-semibold text-gray-800 mb-4">Special Watchlist</h2>
44
+ <textarea id="watchlistInput" rows="3" class="w-full p-3 border border-gray-300 rounded-lg mb-3" placeholder="Enter barcodes to watch (one per line)"></textarea>
45
+ </div>
46
+
47
+ <!-- History Section -->
48
+ <div class="bg-white rounded-xl shadow-md p-6">
49
+ <div class="flex justify-between items-center mb-4">
50
+ <h2 class="text-xl font-semibold text-gray-800">Recent Scans</h2>
51
+ <button id="clearHistoryBtn" class="text-sm text-indigo-600 hover:text-indigo-800">Clear All</button>
52
+ </div>
53
+ <div id="scanHistory" class="space-y-2">
54
+ <p class="text-gray-500 text-center py-4">No scans yet</p>
55
+ </div>
56
+ </div>
57
+
58
+ <!-- Toast Notification -->
59
+ <div id="toast" class="fixed bottom-4 right-4 bg-gray-800 text-white px-4 py-2 rounded-lg shadow-lg transform translate-y-16 transition-transform duration-300 opacity-0 hidden">
60
+ <div class="flex items-center">
61
+ <span id="toastMessage"></span>
62
  </div>
63
  </div>
64
  </div>
65
 
66
  <script>
67
+ /* STATE MANAGEMENT */
68
+ const AppState = (() => {
69
+ const state = {
70
+ scanHistory: [],
71
+ watchlist: [],
72
+ maxHistorySize: 10
73
+ };
74
 
75
+ return {
76
+ getHistory: () => [...state.scanHistory],
77
+ addToHistory: (barcode) => {
78
+ if (state.scanHistory.length >= state.maxHistorySize) {
79
+ state.scanHistory.pop();
80
+ }
81
+ state.scanHistory.unshift(barcode);
82
+ },
83
+ clearHistory: () => {
84
+ state.scanHistory = [];
85
+ },
86
+ isInHistory: (barcode) => state.scanHistory.includes(barcode),
87
+
88
+ getWatchlist: () => [...state.watchlist],
89
+ updateWatchlist: (text) => {
90
+ state.watchlist = text.split('\n').filter(barcode => barcode.trim() !== '');
91
+ },
92
+ isInWatchlist: (barcode) => state.watchlist.includes(barcode)
93
+ };
94
+ })();
95
 
96
+ /* SCANNER MODULE */
97
+ const ScannerModule = (() => {
98
+ const scanBtn = document.getElementById('scanBtn');
99
+ const scannerPlaceholder = document.getElementById('scannerPlaceholder');
100
+ const lastScanned = document.getElementById('lastScanned');
101
+ const lastScannedCode = document.getElementById('lastScannedCode');
102
 
103
+ const init = () => {
104
+ scanBtn.addEventListener('click', handleScan);
105
+ };
 
106
 
107
+ const handleScan = () => {
108
+ // In a real app, this would trigger the device camera
109
+ simulateScan();
 
 
110
  };
111
 
112
+ const simulateScan = () => {
113
+ const barcode = 'BC' + Math.floor(100000 + Math.random() * 900000);
114
+ ScannerEvents.dispatch('scan', barcode);
115
  };
116
 
117
+ const updateLastScanned = (barcode) => {
118
+ lastScannedCode.textContent = barcode;
119
+ lastScanned.classList.remove('hidden');
 
120
  };
 
121
 
122
+ return { init, updateLastScanned };
123
+ })();
 
 
 
 
124
 
125
+ /* HISTORY MODULE */
126
+ const HistoryModule = (() => {
127
+ const scanHistory = document.getElementById('scanHistory');
128
+ const clearHistoryBtn = document.getElementById('clearHistoryBtn');
129
+
130
+ const init = () => {
131
+ clearHistoryBtn.addEventListener('click', handleClearHistory);
132
  };
133
 
134
+ const updateDisplay = () => {
135
+ const history = AppState.getHistory();
136
+
137
+ if (history.length === 0) {
138
+ scanHistory.innerHTML = '<p class="text-gray-500 text-center py-4">No scans yet</p>';
139
+ return;
140
+ }
141
+
142
+ scanHistory.innerHTML = history.map(barcode => `
143
+ <div class="flex justify-between items-center p-2 bg-gray-50 rounded-lg">
144
+ <span class="font-mono">${barcode}</span>
145
+ <span class="text-xs text-gray-500">Just now</span>
146
+ </div>
147
+ `).join('');
148
  };
149
 
150
+ const handleClearHistory = () => {
151
+ AppState.clearHistory();
152
+ updateDisplay();
153
+ ToastModule.show('Scan history cleared', 'info');
 
154
  };
 
155
 
156
+ return { init, updateDisplay };
157
+ })();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
 
159
+ /* WATCHLIST MODULE */
160
+ const WatchlistModule = (() => {
161
+ const watchlistInput = document.getElementById('watchlistInput');
162
+
163
+ const init = () => {
164
+ watchlistInput.addEventListener('change', handleWatchlistUpdate);
165
  };
166
 
167
+ const handleWatchlistUpdate = () => {
168
+ AppState.updateWatchlist(watchlistInput.value);
169
+ ToastModule.show('Watchlist updated', 'success');
170
+ };
171
+
172
+ return { init };
173
+ })();
174
+
175
+ /* API MODULE */
176
+ const ApiModule = (() => {
177
+ const sendBarcode = (barcode) => {
178
+ // In a real app, this would be a POST request
179
+ console.log('Sending to server:', barcode);
180
+ return new Promise((resolve) => {
181
+ setTimeout(() => {
182
+ resolve({ success: true });
183
+ }, 500);
184
+ });
185
  };
 
186
 
187
+ return { sendBarcode };
188
+ })();
 
 
 
189
 
190
+ /* TOAST MODULE */
191
+ const ToastModule = (() => {
192
+ const toast = document.getElementById('toast');
193
+ const toastMessage = document.getElementById('toastMessage');
194
+
195
+ const show = (message, type = 'info') => {
196
+ toastMessage.textContent = message;
197
+
198
+ const colors = {
199
+ info: 'bg-gray-800',
200
  success: 'bg-green-600',
201
  warning: 'bg-yellow-600',
202
  error: 'bg-red-600'
203
  };
204
+
205
+ toast.className = `fixed bottom-4 right-4 text-white px-4 py-2 rounded-lg shadow-lg transform translate-y-16 transition-transform duration-300 ${colors[type]}`;
206
+
207
+ toast.classList.remove('hidden');
208
+ toast.style.opacity = '1';
209
+ toast.style.transform = 'translateY(0)';
210
+
 
211
  setTimeout(() => {
212
+ toast.style.opacity = '0';
213
+ toast.style.transform = 'translateY(16px)';
214
+ setTimeout(() => toast.classList.add('hidden'), 300);
215
  }, 3000);
216
  };
217
 
218
+ return { show };
219
+ })();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
220
 
221
+ /* EVENT DISPATCHER */
222
+ const ScannerEvents = (() => {
223
+ const events = {};
 
224
 
225
+ const on = (event, callback) => {
226
+ if (!events[event]) events[event] = [];
227
+ events[event].push(callback);
228
+ };
 
 
 
 
 
229
 
230
+ const dispatch = (event, data) => {
231
+ if (!events[event]) return;
232
+ events[event].forEach(callback => callback(data));
233
+ };
234
 
235
+ return { on, dispatch };
236
+ })();
237
+
238
+ /* MAIN CONTROLLER */
239
+ const AppController = (() => {
240
+ const init = () => {
 
 
 
241
  feather.replace();
242
+
243
+ ScannerModule.init();
244
+ HistoryModule.init();
245
+ WatchlistModule.init();
246
+
247
+ ScannerEvents.on('scan', handleScan);
248
+ };
249
+
250
+ const handleScan = async (barcode) => {
251
+ if (AppState.isInHistory(barcode)) {
252
+ ToastModule.show('This barcode has already been scanned!', 'warning');
253
+ return;
254
+ }
255
+
256
+ if (AppState.isInWatchlist(barcode)) {
257
+ ToastModule.show('⚠️ Special barcode detected!', 'warning');
258
+ }
259
+
260
+ ScannerModule.updateLastScanned(barcode);
261
+ AppState.addToHistory(barcode);
262
+ HistoryModule.updateDisplay();
263
+
264
+ try {
265
+ await ApiModule.sendBarcode(barcode);
266
+ ToastModule.show(`Barcode "${barcode}" sent to server`, 'success');
267
+ } catch (error) {
268
+ ToastModule.show('Failed to send barcode', 'error');
269
+ }
270
+ };
271
+
272
+ return { init };
273
+ })();
274
+
275
+ // Initialize the app
276
+ AppController.init();
277
+
278
+ // For demo: simulate scanning by pressing 'S' key
279
+ document.addEventListener('keydown', (e) => {
280
+ if (e.key === 's') {
281
+ ScannerModule.simulateScan();
282
  }
283
+ });
284
  </script>
285
  </body>
286
  </html>