From 58a0e5b89efb351a564793c6a3cee2a47b70f605 Mon Sep 17 00:00:00 2001
From: Juan Felipe Zapata Moreno
Date: Mon, 5 Jan 2026 16:31:12 -0600
Subject: [PATCH] =?UTF-8?q?add:=20implementar=20esc=C3=A1ner=20de=20c?=
=?UTF-8?q?=C3=B3digos=20QR=20y=20agregar=20soporte=20en=20la=20interfaz?=
=?UTF-8?q?=20de=20usuario?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
package-lock.json | 64 +++++++++++++++++
package.json | 1 +
src/components/POS/QRscan.vue | 130 ++++++++++++++++++++++++++++++++++
src/lang/es.js | 1 +
src/pages/POS/Point.vue | 46 ++++++++++++
5 files changed, 242 insertions(+)
create mode 100644 src/components/POS/QRscan.vue
diff --git a/package-lock.json b/package-lock.json
index 2069d37..4046481 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -24,6 +24,7 @@
"vue": "^3.5.13",
"vue-i18n": "^11.1.1",
"vue-multiselect": "^3.2.0",
+ "vue-qrcode-reader": "^5.7.3",
"vue-router": "^4.5.0",
"ziggy-js": "^2.5.2"
},
@@ -1234,6 +1235,18 @@
"vite": "^5.2.0 || ^6"
}
},
+ "node_modules/@types/dom-webcodecs": {
+ "version": "0.1.18",
+ "resolved": "https://registry.npmjs.org/@types/dom-webcodecs/-/dom-webcodecs-0.1.18.tgz",
+ "integrity": "sha512-vAvE8C9DGWR+tkb19xyjk1TSUlJ7RUzzp4a9Anu7mwBT+fpyePWK1UxmH14tMO5zHmrnrRIMg5NutnnDztLxgg==",
+ "license": "MIT"
+ },
+ "node_modules/@types/emscripten": {
+ "version": "1.41.5",
+ "resolved": "https://registry.npmjs.org/@types/emscripten/-/emscripten-1.41.5.tgz",
+ "integrity": "sha512-cMQm7pxu6BxtHyqJ7mQZ2kXWV5SLmugybFdHCBbJ5eHzOo6VhBckEgAT3//rP5FwPHNPeEiq4SmQ5ucBwsOo4Q==",
+ "license": "MIT"
+ },
"node_modules/@types/estree": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz",
@@ -1522,6 +1535,16 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/barcode-detector": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/barcode-detector/-/barcode-detector-2.2.2.tgz",
+ "integrity": "sha512-JcSekql+EV93evfzF9zBr+Y6aRfkR+QFvgyzbwQ0dbymZXoAI9+WgT7H1E429f+3RKNncHz2CW98VQtaaKpmfQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/dom-webcodecs": "^0.1.11",
+ "zxing-wasm": "1.1.3"
+ }
+ },
"node_modules/base64-arraybuffer": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
@@ -3416,6 +3439,12 @@
"queue-microtask": "^1.2.2"
}
},
+ "node_modules/sdp": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/sdp/-/sdp-3.2.1.tgz",
+ "integrity": "sha512-lwsAIzOPlH8/7IIjjz3K0zYBk7aBVVcvjMwt3M4fLxpjMYyy7i3I97SLHebgn4YBjirkzfp3RvRDWSKsh/+WFw==",
+ "license": "MIT"
+ },
"node_modules/socket.io-client": {
"version": "4.8.1",
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.8.1.tgz",
@@ -3867,6 +3896,19 @@
"npm": ">= 6.14.15"
}
},
+ "node_modules/vue-qrcode-reader": {
+ "version": "5.7.3",
+ "resolved": "https://registry.npmjs.org/vue-qrcode-reader/-/vue-qrcode-reader-5.7.3.tgz",
+ "integrity": "sha512-iSGko42FsEvdHyizBMBs/X+HMO9Z5ONDxjW+mQdoraOR5emRNedmjC5SEJdYzGz8ZP5ME3lwB4iHy3S7MOt5Qw==",
+ "license": "MIT",
+ "dependencies": {
+ "barcode-detector": "2.2.2",
+ "webrtc-adapter": "8.2.3"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
"node_modules/vue-router": {
"version": "4.5.1",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.5.1.tgz",
@@ -3888,6 +3930,19 @@
"integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==",
"license": "MIT"
},
+ "node_modules/webrtc-adapter": {
+ "version": "8.2.3",
+ "resolved": "https://registry.npmjs.org/webrtc-adapter/-/webrtc-adapter-8.2.3.tgz",
+ "integrity": "sha512-gnmRz++suzmvxtp3ehQts6s2JtAGPuDPjA1F3a9ckNpG1kYdYuHWYpazoAnL9FS5/B21tKlhkorbdCXat0+4xQ==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "sdp": "^3.2.0"
+ },
+ "engines": {
+ "node": ">=6.0.0",
+ "npm": ">=3.10.0"
+ }
+ },
"node_modules/ws": {
"version": "8.17.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
@@ -3937,6 +3992,15 @@
"@types/qs": "^6.9.17",
"qs": "~6.9.7"
}
+ },
+ "node_modules/zxing-wasm": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/zxing-wasm/-/zxing-wasm-1.1.3.tgz",
+ "integrity": "sha512-MYm9k/5YVs4ZOTIFwlRjfFKD0crhefgbnt1+6TEpmKUDFp3E2uwqGSKwQOd2hOIsta/7Usq4hnpNRYTLoljnfA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/emscripten": "^1.39.10"
+ }
}
}
}
diff --git a/package.json b/package.json
index ff9ae63..d27f6a2 100644
--- a/package.json
+++ b/package.json
@@ -26,6 +26,7 @@
"vue": "^3.5.13",
"vue-i18n": "^11.1.1",
"vue-multiselect": "^3.2.0",
+ "vue-qrcode-reader": "^5.7.3",
"vue-router": "^4.5.0",
"ziggy-js": "^2.5.2"
},
diff --git a/src/components/POS/QRscan.vue b/src/components/POS/QRscan.vue
new file mode 100644
index 0000000..3279ae8
--- /dev/null
+++ b/src/components/POS/QRscan.vue
@@ -0,0 +1,130 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
¡Código detectado!
+
+
+
+
+
+ {{ error }}
+
+
+
+
+
\ No newline at end of file
diff --git a/src/lang/es.js b/src/lang/es.js
index 360ad08..2011425 100644
--- a/src/lang/es.js
+++ b/src/lang/es.js
@@ -451,6 +451,7 @@ export default {
},
pos: {
title: 'Punto de Venta',
+ subtitle: 'Gestión de ventas y caja',
category: 'Categorías',
inventory: 'Inventario',
prices: 'Precios',
diff --git a/src/pages/POS/Point.vue b/src/pages/POS/Point.vue
index 920456c..e4d6950 100644
--- a/src/pages/POS/Point.vue
+++ b/src/pages/POS/Point.vue
@@ -11,6 +11,7 @@ import GoogleIcon from '@Shared/GoogleIcon.vue';
import ProductCard from '@Components/POS/ProductCard.vue';
import CartItem from '@Components/POS/CartItem.vue';
import CheckoutModal from '@Components/POS/CheckoutModal.vue';
+import QRscan from '@Components/POS/QRscan.vue';
/** i18n */
const { t } = useI18n();
@@ -23,6 +24,7 @@ const products = ref([]);
const showCheckoutModal = ref(false);
const searchQuery = ref('');
const processingPayment = ref(false);
+const scanMode = ref(false);
/** Buscador de productos */
const searcher = useSearcher({
@@ -79,6 +81,15 @@ const closeCheckout = () => {
showCheckoutModal.value = false;
};
+const toggleScanMode = () => {
+ scanMode.value = !scanMode.value;
+ if(scanMode.value) {
+ window.Notify.info('Modo escaneo activado');
+ } else {
+ window.Notify.info('Modo escaneo desactivado');
+ }
+};
+
const handleConfirmSale = async (paymentData) => {
processingPayment.value = true;
@@ -187,6 +198,19 @@ onMounted(() => {
+
@@ -194,6 +218,28 @@ onMounted(() => {
+
+
+
+
+
+ Escáner de Códigos de Barras
+
+
+
+
+
+
+ Instrucciones: Coloca el código de barras frente a la cámara.
+ El producto se agregará automáticamente al carrito cuando se detecte.
+
+
+
+
+