|
@@ -1,7 +1,27 @@
|
|
<template>
|
|
<template>
|
|
<div class="form">
|
|
<div class="form">
|
|
- <van-nav-bar title="手动入库" left-text="返回" left-arrow @click-left="onClickLeft"> </van-nav-bar>
|
|
|
|
- <testForm v-model="formData.data" :formOption="formOption" :formConfig="formConfig" :rules="rules" @onSubmit="onSubmit" ref="formDom"></testForm>
|
|
|
|
|
|
+ <van-nav-bar
|
|
|
|
+ title="手动入库"
|
|
|
|
+ left-text="返回"
|
|
|
|
+ left-arrow
|
|
|
|
+ @click-left="onClickLeft"
|
|
|
|
+ >
|
|
|
|
+ </van-nav-bar>
|
|
|
|
+ <testForm
|
|
|
|
+ v-model="formData.data"
|
|
|
|
+ :formOption="formOption"
|
|
|
|
+ :formConfig="formConfig"
|
|
|
|
+ :rules="rules"
|
|
|
|
+ @onSubmit="onSubmit"
|
|
|
|
+ ref="formDom"
|
|
|
|
+ ></testForm>
|
|
|
|
+ <video
|
|
|
|
+ ref="video"
|
|
|
|
+ id="video"
|
|
|
|
+ class="scan-video"
|
|
|
|
+ autoplay
|
|
|
|
+ v-show="isShowVideo"
|
|
|
|
+ ></video>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
|
|
|
|
@@ -10,10 +30,14 @@ import { ref, reactive, getCurrentInstance, onMounted } from "vue";
|
|
import { showSuccessToast, showFailToast } from "vant";
|
|
import { showSuccessToast, showFailToast } from "vant";
|
|
import { useRoute } from "vue-router";
|
|
import { useRoute } from "vue-router";
|
|
import testForm from "@/components/testForm/index.vue";
|
|
import testForm from "@/components/testForm/index.vue";
|
|
-
|
|
|
|
|
|
+import { BrowserMultiFormatReader } from "@zxing/library";
|
|
|
|
+const codeReader = new BrowserMultiFormatReader();
|
|
const proxy = getCurrentInstance().proxy;
|
|
const proxy = getCurrentInstance().proxy;
|
|
const route = useRoute();
|
|
const route = useRoute();
|
|
const formDom = ref(null);
|
|
const formDom = ref(null);
|
|
|
|
+const isShowVideo = ref(false);
|
|
|
|
+const scanIndex = ref(-1);
|
|
|
|
+const productData = ref([]);
|
|
const formData = reactive({
|
|
const formData = reactive({
|
|
data: {
|
|
data: {
|
|
warehouseId: "",
|
|
warehouseId: "",
|
|
@@ -22,8 +46,8 @@ const formData = reactive({
|
|
},
|
|
},
|
|
});
|
|
});
|
|
const rules = {
|
|
const rules = {
|
|
- warehouseName: [{ required: true, message: "仓库名称不能为空" }],
|
|
|
|
- productName: [{ required: true, message: "物品名称不能为空" }],
|
|
|
|
|
|
+ warehouseId: [{ required: true, message: "仓库名称不能为空" }],
|
|
|
|
+ productId: [{ required: true, message: "物品名称不能为空" }],
|
|
quantity: [{ required: true, message: "入库数量不能为空" }],
|
|
quantity: [{ required: true, message: "入库数量不能为空" }],
|
|
};
|
|
};
|
|
const formOption = reactive({
|
|
const formOption = reactive({
|
|
@@ -50,6 +74,11 @@ const formOption = reactive({
|
|
value: "id",
|
|
value: "id",
|
|
},
|
|
},
|
|
data: [],
|
|
data: [],
|
|
|
|
+ isShowScanCode: true,
|
|
|
|
+ scanCode: (index) => {
|
|
|
|
+ scanIndex.value = index;
|
|
|
|
+ handleScanCode();
|
|
|
|
+ },
|
|
},
|
|
},
|
|
{
|
|
{
|
|
type: "input",
|
|
type: "input",
|
|
@@ -92,12 +121,17 @@ const formConfig = reactive([
|
|
]);
|
|
]);
|
|
const onClickLeft = () => history.back();
|
|
const onClickLeft = () => history.back();
|
|
const getDict = async () => {
|
|
const getDict = async () => {
|
|
- await proxy.post("/warehouse/page", { pageNum: 1, pageSize: 9999 }).then((res) => {
|
|
|
|
- formConfig[0].data = res.data.rows;
|
|
|
|
- });
|
|
|
|
- await proxy.post("/productInfo/page", { pageNum: 1, pageSize: 9999, definition: "" }).then((res) => {
|
|
|
|
- formOption.btnConfig.listConfig[0].data = res.data.rows;
|
|
|
|
- });
|
|
|
|
|
|
+ await proxy
|
|
|
|
+ .post("/warehouse/page", { pageNum: 1, pageSize: 9999 })
|
|
|
|
+ .then((res) => {
|
|
|
|
+ formConfig[0].data = res.data.rows;
|
|
|
|
+ });
|
|
|
|
+ await proxy
|
|
|
|
+ .post("/productInfo/page", { pageNum: 1, pageSize: 9999, definition: "" })
|
|
|
|
+ .then((res) => {
|
|
|
|
+ formOption.btnConfig.listConfig[0].data = res.data.rows;
|
|
|
|
+ productData.value = res.data.rows;
|
|
|
|
+ });
|
|
};
|
|
};
|
|
onMounted(async () => {
|
|
onMounted(async () => {
|
|
await getDict();
|
|
await getDict();
|
|
@@ -123,5 +157,64 @@ const onSubmit = () => {
|
|
}
|
|
}
|
|
);
|
|
);
|
|
};
|
|
};
|
|
|
|
+const showScanData = (id) => {
|
|
|
|
+ const current = productData.value.find((x) => x.id === id);
|
|
|
|
+ if (current) {
|
|
|
|
+ formData.data.list[scanIndex.value].productId = current.id;
|
|
|
|
+ formData.data.list[scanIndex.value].productIdName = current.name;
|
|
|
|
+ }
|
|
|
|
+};
|
|
|
|
+const decodeFromInputVideoFunc = (firstDeviceId) => {
|
|
|
|
+ codeReader.reset(); // 重置
|
|
|
|
+ isShowVideo.value = true;
|
|
|
|
+ codeReader.decodeFromInputVideoDeviceContinuously(
|
|
|
|
+ firstDeviceId,
|
|
|
|
+ "video",
|
|
|
|
+ (result, err) => {
|
|
|
|
+ if (result) {
|
|
|
|
+ codeReader.reset();
|
|
|
|
+ showSuccessToast("扫描成功");
|
|
|
|
+ isShowVideo.value = false;
|
|
|
|
+ showScanData(result.text);
|
|
|
|
+ }
|
|
|
|
+ if (err && !err) {
|
|
|
|
+ console.error(err);
|
|
|
|
+ isShowVideo.value = true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+const handleScanCode = () => {
|
|
|
|
+ codeReader
|
|
|
|
+ .getVideoInputDevices()
|
|
|
|
+ .then((videoInputDevices) => {
|
|
|
|
+ // 默认获取第一个摄像头设备id
|
|
|
|
+ let firstDeviceId = videoInputDevices[0].deviceId;
|
|
|
|
+ // 获取第一个摄像头设备的名称
|
|
|
|
+ const videoInputDeviceslablestr = JSON.stringify(
|
|
|
|
+ videoInputDevices[0].label
|
|
|
|
+ );
|
|
|
|
+ if (videoInputDevices.length > 1) {
|
|
|
|
+ // 判断是否后置摄像头
|
|
|
|
+ if (videoInputDeviceslablestr.indexOf("back") > -1) {
|
|
|
|
+ firstDeviceId = videoInputDevices[0].deviceId;
|
|
|
|
+ } else {
|
|
|
|
+ firstDeviceId = videoInputDevices[1].deviceId;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ decodeFromInputVideoFunc(firstDeviceId);
|
|
|
|
+ })
|
|
|
|
+ .catch((err) => {
|
|
|
|
+ console.error(err, "错误");
|
|
|
|
+ });
|
|
|
|
+};
|
|
</script>
|
|
</script>
|
|
-<style lang="scss" scoped></style>
|
|
|
|
|
|
+<style lang="scss" scoped>
|
|
|
|
+.scan-video {
|
|
|
|
+ width: 100vw;
|
|
|
|
+ position: absolute;
|
|
|
|
+ z-index: 1000;
|
|
|
|
+ top: 60px;
|
|
|
|
+}
|
|
|
|
+</style>
|